view libgui/src/interpreter-qobject.h @ 27302:5f170ea12fa1

use Qt signals to pass interpreter callbacks to octave-qobject * interpreter-qobject.h, interpreter-qobject.cc (interpreter_qobject::m_interpreter): New data member. (interpreter_qobject::execute): Cache pointer to interpreter after it is created. Set it to nullptr before exiting to disable interpreter events. (interpreter_qobject::interpreter_event): New functions. * octave-qobject.h, octave-qobject.cc (octave_qapplication::interpreter_event): New signals. (base_qobject::interpreter_event): New slots. Forward action to m_interpreter object interpreter_event functions. (base_qobject::base_qobject): Connect interpreter_event signals for octave_qapplication to the base_qobject::interpreter_event slots. (octave_qapplication::notify): Emit interpreter_event signal instead of using event_manager::post_exception. * qt-interpreter-events.cc: Declare and register octave::fcn_callback and octave::meth_callback as Qt meta types. * event-manager.h, event-manager.cc (event_manager::m_interpreter): New data member. Update constructor, change all uses. (octave::fcn_callback, octave::meth_callback): New typedefs. (event_manager::post_event): Limit allowable callback function signatures. For meth_callback functions, arrange for a reference to the interpreter object to be passed as the first argument. (event_manager::post_exception): Delete. (event_manager::rethrow_exception_callback): Delete. * GLCanvas.cc (GLCanvas::do_print): Use event_manager::post_event instead of event_manager::post_exception. * file-editor-tab.h (file_eitor_tab::interpreter_event): New signals. * file-editor.cc (file_editor::add_file_editor_tab): Forward interpreter_event signal from newly constructed file_editor_tab object to the interpreter_event signal of the file_editor object. * main-window.h, main-window.cc (main_window::construct): Connect the interpreter_event signal from the main_window object to the parent octave_qobject object. (main_window::interpreter_event): New signals. * octave-dock-widget.h, octave-dock-widget.cc (octave_dock_widget::octave_dock_widget) Forward the interpreter_event signal from the octave_dock_widget object to the interpreter_event signal for parent main_window object. (octave_dock_widget::interpreter_event): New signals. * variable-editor-model.h, variable-editor-model.cc (variable_editor_model::init_from_oct, variable_editor_model::retrieve_variable): Accept reference to interpreter object as an argument. Change all uses. (variable_editor_model::interpreter_event): New signals. * variable-editor.cc (variable_editor::edit_variable): Forward interpreter_event signal from newly constructed variable_editor_model to interpreter_event signal fro variable_editor object. * files-dock-widget.cc, file-editor-tab.cc, main-window.cc, variable-editor-model.cc: In all functions that need to perform interpreter actions, emit an interpreter_event signal instead of accessing the interprter event_manager and calling post_interpreter_event directly.
author John W. Eaton <jwe@octave.org>
date Mon, 29 Jul 2019 10:43:04 -0400
parents 99aa1bcb8848
children f0e3f3e28a8e
line wrap: on
line source

/*

Copyright (C) 2013-2019 John W. Eaton
Copyright (C) 2011-2019 Jacob Dawid

This file is part of Octave.

Octave is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Octave is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING.  If not, see
<https://www.gnu.org/licenses/>.

*/

#if ! defined (octave_interpreter_qobject_h)
#define octave_interpreter_qobject_h 1

#include <memory>

#include <QObject>

#include "qt-interpreter-events.h"

namespace octave
{
  class interpreter;

  class base_qobject;

  class interpreter_qobject : public QObject
  {
    Q_OBJECT

  public:

    interpreter_qobject (base_qobject *oct_qobj);

    ~interpreter_qobject (void) = default;

    qt_interpreter_events * qt_link (void) { return m_qt_link.get (); }

    void confirm_shutdown (bool closenow);

    void interpreter_event (const fcn_callback& fcn);

    void interpreter_event (const meth_callback& meth);

  signals:

    void octave_ready_signal (void);

    void octave_finished_signal (int);

  public slots:

    // Programming Note: With the current design of the interpreter,
    // additional signals will not be noticed because the execute
    // function starts the Octave interpreter and it doesn't return
    // until the interpreter exits.  So the Qt event loop running in the
    // thread where the interpreter_qobject object lives never has a
    // chance to see another signal.  Changing the design of the
    // terminal widget as proposed and discussed here:
    //
    //   https://lists.gnu.org/archive/html/octave-maintainers/2019-05/msg00115.html
    //   https://lists.gnu.org/archive/html/octave-maintainers/2019-06/msg00009.html
    //
    // coulld solve that problem.  Briefly, instead of having the Octave
    // interpreter block and wait for keyboard input, the terminal
    // widget would be in charge of accepting keyboard events and use
    // readline in callback mode.  Then the terminal widget and the
    // interpreter will not block except when executing code.  Then we
    // could have the interpreter qobject directly accept signals.

    //! Initialize and execute the octave interpreter.

    void execute (void);

  private:

    base_qobject *m_octave_qobject;

    interpreter *m_interpreter;

    std::shared_ptr<qt_interpreter_events> m_qt_link;
  };
}

#endif