GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
octave-link.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2013-2018 John W. Eaton
4 Copyright (C) 2011-2018 Jacob Dawid
5 Copyright (C) 2011-2018 John P. Swensen
6 
7 This file is part of Octave.
8 
9 Octave is free software: you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <https://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if ! defined (octave_octave_link_h)
26 #define octave_octave_link_h 1
27 
28 #include "octave-config.h"
29 
30 #include <list>
31 #include <string>
32 
33 #include "oct-mutex.h"
34 
35 #include "event-queue.h"
36 
37 class octave_value;
38 class string_vector;
39 
40 namespace octave
41 {
42  class symbol_scope;
43 }
44 
45 //! Provides threadsafe access to octave.
46 //! @author Jacob Dawid
47 //!
48 //! This class is a wrapper around octave and provides thread safety by
49 //! buffering access operations to octave and executing them in the
50 //! readline event hook, which lives in the octave thread.
51 
52 class
53 OCTINTERP_API
55 {
56 protected:
57 
58  octave_link (void);
59 
60 public:
61 
62  // No copying!
63 
64  octave_link (const octave_link&) = delete;
65 
66  octave_link& operator = (const octave_link&) = delete;
67 
68  virtual ~octave_link (void);
69 
70  static void generate_events (void)
71  {
72  if (enabled ())
73  instance->do_generate_events ();
74  }
75 
76  // If disable is TRUE, then no additional events will be processed
77  // other than exit.
78 
79  static void process_events (bool disable = false)
80  {
81  if (enabled ())
82  {
83  if (disable)
84  instance->do_disable ();
85 
86  instance->do_process_events ();
87  }
88  }
89 
90  static void discard_events (void)
91  {
92  if (enabled ())
93  instance->do_discard_events ();
94  }
95 
96  static bool confirm_shutdown (void)
97  {
98  bool retval = true;
99 
100  if (enabled ())
101  retval = instance->do_confirm_shutdown ();
102 
103  return retval;
104  }
105 
106  template <typename T>
107  static void post_event (T *obj, void (T::*method) (void))
108  {
109  if (enabled ())
110  instance->do_post_event (obj, method);
111  }
112 
113  template <typename T, typename A>
114  static void post_event (T *obj, void (T::*method) (A), A arg)
115  {
116  if (enabled ())
117  instance->do_post_event (obj, method, arg);
118  }
119 
120  template <typename T, typename A>
121  static void post_event (T *obj, void (T::*method) (const A&), const A& arg)
122  {
123  if (enabled ())
124  instance->do_post_event (obj, method, arg);
125  }
126 
127  template <class T, class A, class B>
128  static void post_event (T *obj, void (T::*method) (const A&, const B&),
129  const A& arg_a, const B& arg_b)
130  {
131  if (enabled ())
132  instance->do_post_event<T, A, B> (obj, method, arg_a, arg_b);
133  }
134 
135  template <class T, class A, class B, class C>
136  static void post_event (T *obj,
137  void (T::*method) (const A&, const B&, const C&),
138  const A& arg_a, const B& arg_b, const C& arg_c)
139  {
140  if (enabled ())
141  instance->do_post_event<T, A, B, C> (obj, method, arg_a, arg_b, arg_c);
142  }
143 
144  template <class T, class A, class B, class C, class D>
145  static void
146  post_event (T *obj,
147  void (T::*method) (const A&, const B&, const C&, const D&),
148  const A& arg_a, const B& arg_b, const C& arg_c, const D& arg_d)
149  {
150  if (enabled ())
151  instance->do_post_event<T, A, B, C, D>
152  (obj, method, arg_a, arg_b, arg_c, arg_d);
153  }
154 
155  static void
156  post_exception (const std::exception_ptr &p)
157  {
158  if (enabled ())
159  instance->do_post_exception (p);
160  }
161 
162  static void entered_readline_hook (void)
163  {
164  if (enabled ())
165  instance->do_entered_readline_hook ();
166  }
167 
168  static void finished_readline_hook (void)
169  {
170  if (enabled ())
171  instance->do_finished_readline_hook ();
172  }
173 
174  static bool
176  {
177  return enabled () ? instance->do_copy_image_to_clipboard (file) : false;
178  }
179 
180  static bool
182  {
183  return enabled () ? instance->do_edit_file (file) : false;
184  }
185 
186  static bool
188  {
189  return enabled () ? instance->do_prompt_new_edit_file (file) : false;
190  }
191 
192  static int
193  message_dialog (const std::string& dlg, const std::string& msg,
194  const std::string& title)
195  {
196  return enabled () ? instance->do_message_dialog (dlg, msg, title) : 0;
197  }
198 
199  static std::string
200  question_dialog (const std::string& msg, const std::string& title,
201  const std::string& btn1, const std::string& btn2,
202  const std::string& btn3, const std::string& btndef)
203  {
204  return enabled () ? instance->do_question_dialog (msg, title, btn1,
205  btn2, btn3, btndef) : "";
206  }
207 
208  static std::pair<std::list<int>, int>
209  list_dialog (const std::list<std::string>& list,
210  const std::string& mode,
211  int width, int height,
212  const std::list<int>& initial_value,
213  const std::string& name,
214  const std::list<std::string>& prompt,
215  const std::string& ok_string,
216  const std::string& cancel_string)
217  {
218  return enabled ()
219  ? instance->do_list_dialog (list, mode, width, height,
220  initial_value, name, prompt,
221  ok_string, cancel_string)
222  : std::pair<std::list<int>, int> ();
223  }
224 
225  static std::list<std::string>
226  input_dialog (const std::list<std::string>& prompt,
227  const std::string& title,
228  const std::list<float>& nr,
229  const std::list<float>& nc,
230  const std::list<std::string>& defaults)
231  {
232  return enabled ()
233  ? instance->do_input_dialog (prompt, title, nr, nc, defaults)
234  : std::list<std::string> ();
235  }
236 
237  typedef std::list<std::pair<std::string, std::string>> filter_list;
238 
239  static std::list<std::string>
240  file_dialog (const filter_list& filter, const std::string& title,
241  const std::string& filename, const std::string& dirname,
242  const std::string& multimode)
243  {
244  return enabled ()
245  ? instance->do_file_dialog (filter, title, filename, dirname,
246  multimode)
247  : std::list<std::string> ();
248  }
249 
251  const std::string& dir,
252  bool addpath_option)
253  {
254  return enabled ()
255  ? instance->do_debug_cd_or_addpath_error (file, dir, addpath_option)
256  : 0;
257  }
258 
259  static void change_directory (const std::string& dir)
260  {
261  if (enabled ())
262  instance->do_change_directory (dir);
263  }
264 
265  // Preserves pending input.
267  {
268  if (enabled ())
269  instance->do_execute_command_in_terminal (command);
270  }
271 
272  static void set_workspace (void);
273 
274  static void set_workspace (bool top_level,
275  const octave::symbol_scope& scope,
276  bool update_variable_editor = true)
277  {
278  if (enabled ())
279  instance->do_set_workspace (top_level, instance->debugging, scope,
280  update_variable_editor);
281  }
282 
283  static void clear_workspace (void)
284  {
285  if (enabled ())
286  instance->do_clear_workspace ();
287  }
288 
289  static void set_history (const string_vector& hist)
290  {
291  if (enabled ())
292  instance->do_set_history (hist);
293  }
294 
295  static void append_history (const std::string& hist_entry)
296  {
297  if (enabled ())
298  instance->do_append_history (hist_entry);
299  }
300 
301  static void clear_history (void)
302  {
303  if (enabled ())
304  instance->do_clear_history ();
305  }
306 
307  static void pre_input_event (void)
308  {
309  if (enabled ())
310  instance->do_pre_input_event ();
311  }
312 
313  static void post_input_event (void)
314  {
315  if (enabled ())
316  instance->do_post_input_event ();
317  }
318 
319  static void enter_debugger_event (const std::string& file, int line)
320  {
321  if (enabled ())
322  {
323  instance->debugging = true;
324 
325  instance->do_enter_debugger_event (file, line);
326  }
327  }
328 
329  static void execute_in_debugger_event (const std::string& file, int line)
330  {
331  if (enabled ())
332  instance->do_execute_in_debugger_event (file, line);
333  }
334 
335  static void exit_debugger_event (void)
336  {
337  if (enabled () && instance->debugging)
338  {
339  instance->debugging = false;
340 
341  instance->do_exit_debugger_event ();
342  }
343  }
344 
345  static void
346  update_breakpoint (bool insert, const std::string& file, int line,
347  const std::string& cond = "")
348  {
349  if (enabled ())
350  instance->do_update_breakpoint (insert, file, line, cond);
351  }
352 
353  static void connect_link (octave_link *);
354 
355  static octave_link * disconnect_link (bool delete_instance = true)
356  {
357  if (delete_instance)
358  {
359  delete instance;
360  instance = nullptr;
361  return nullptr;
362  }
363  else
364  {
365  octave_link *retval = instance;
366  instance = nullptr;
367  return retval;
368  }
369  }
370 
371  static void set_default_prompts (std::string& ps1, std::string& ps2,
372  std::string& ps4)
373  {
374  if (enabled ())
375  instance->do_set_default_prompts (ps1, ps2, ps4);
376  }
377 
378  static bool enable (void)
379  {
380  return instance_ok () ? instance->do_enable () : false;
381  }
382 
383  static bool disable (void)
384  {
385  return instance_ok () ? instance->do_disable () : false;
386  }
387 
388  bool do_enable (void)
389  {
390  bool retval = link_enabled;
391  link_enabled = true;
392  return retval;
393  }
394 
395  bool do_disable (void)
396  {
397  bool retval = link_enabled;
398  link_enabled = false;
399  return retval;
400  }
401 
402  static bool enabled (void)
403  {
404  return instance_ok () ? instance->link_enabled : false;
405  }
406 
407  static bool
409  {
410  if (enabled ())
411  {
412  instance->do_show_preferences ();
413  return true;
414  }
415  else
416  return false;
417  }
418 
419  static bool
421  {
422  if (enabled ())
423  {
424  instance->do_show_doc (file);
425  return true;
426  }
427  else
428  return false;
429  }
430 
431  static bool
433  {
434  if (enabled ())
435  {
436  instance->do_register_doc (file);
437  return true;
438  }
439  else
440  return false;
441  }
442 
443  static bool
445  {
446  if (enabled ())
447  {
448  instance->do_unregister_doc (file);
449  return true;
450  }
451  else
452  return false;
453 
454  }
455 
456  static bool
458  {
459  if (enabled ())
460  {
461  instance->do_edit_variable (name, val);
462  return true;
463  }
464  else
465  return false;
466  }
467 
468 private:
469 
471 
472  static bool instance_ok (void) { return instance != nullptr; }
473 
474 protected:
475 
476  // Semaphore to lock access to the event queue.
478 
479  // Event Queue.
481 
482  bool debugging;
484 
485  void do_generate_events (void);
486  void do_process_events (void);
487  void do_discard_events (void);
488 
489  template <typename T>
490  void do_post_event (T *obj, void (T::*method) (void))
491  {
492  gui_event_queue.add_method (obj, method);
493  }
494 
495  template <typename T, typename A>
496  void do_post_event (T *obj, void (T::*method) (A), A arg)
497  {
498  gui_event_queue.add_method (obj, method, arg);
499  }
500 
501  template <typename T, typename A>
502  void do_post_event (T *obj, void (T::*method) (const A&), const A& arg)
503  {
504  gui_event_queue.add_method (obj, method, arg);
505  }
506 
507  template <class T, class A, class B>
508  void do_post_event (T *obj, void (T::*method) (const A&, const B&),
509  const A& arg_a, const B& arg_b)
510  {
511  gui_event_queue.add_method<T, A, B>
512  (obj, method, arg_a, arg_b);
513  }
514 
515  template <class T, class A, class B, class C>
516  void do_post_event (T *obj,
517  void (T::*method) (const A&, const B&, const C&),
518  const A& arg_a, const B& arg_b, const C& arg_c)
519  {
520  gui_event_queue.add_method<T, A, B, C>
521  (obj, method, arg_a, arg_b, arg_c);
522  }
523 
524  template <class T, class A, class B, class C, class D>
525  void
526  do_post_event (T *obj,
527  void (T::*method) (const A&, const B&, const C&, const D&),
528  const A& arg_a, const B& arg_b, const C& arg_c, const D& arg_d)
529  {
530  gui_event_queue.add_method<T, A, B, C, D>
531  (obj, method, arg_a, arg_b, arg_c, arg_d);
532  }
533 
534  void
535  rethrow_exception_callback (const std::exception_ptr &p)
536  {
537  std::rethrow_exception (p);
538  }
539 
540  void
541  do_post_exception (const std::exception_ptr &p)
542  {
543  do_post_event (this, &octave_link::rethrow_exception_callback, p);
544  }
545 
546  void do_entered_readline_hook (void) { }
548 
549  virtual bool do_confirm_shutdown (void) = 0;
550 
551  virtual bool do_copy_image_to_clipboard (const std::string& file) = 0;
552 
553  virtual bool do_edit_file (const std::string& file) = 0;
554  virtual bool do_prompt_new_edit_file (const std::string& file) = 0;
555 
556  virtual int
557  do_message_dialog (const std::string& dlg, const std::string& msg,
558  const std::string& title) = 0;
559 
560  virtual std::string
561  do_question_dialog (const std::string& msg, const std::string& title,
562  const std::string& btn1, const std::string& btn2,
563  const std::string& btn3, const std::string& btndef) = 0;
564 
565  virtual std::pair<std::list<int>, int>
566  do_list_dialog (const std::list<std::string>& list,
567  const std::string& mode,
568  int width, int height,
569  const std::list<int>& initial_value,
570  const std::string& name,
571  const std::list<std::string>& prompt,
572  const std::string& ok_string,
573  const std::string& cancel_string) = 0;
574 
575  virtual std::list<std::string>
576  do_input_dialog (const std::list<std::string>& prompt,
577  const std::string& title,
578  const std::list<float>& nr,
579  const std::list<float>& nc,
580  const std::list<std::string>& defaults) = 0;
581 
582  virtual std::list<std::string>
583  do_file_dialog (const filter_list& filter, const std::string& title,
584  const std::string& filename, const std::string& dirname,
585  const std::string& multimode) = 0;
586 
587  virtual int
588  do_debug_cd_or_addpath_error (const std::string& file,
589  const std::string& dir,
590  bool addpath_option) = 0;
591 
592  virtual void do_change_directory (const std::string& dir) = 0;
593 
594  virtual void do_execute_command_in_terminal (const std::string& command) = 0;
595 
596  virtual void
597  do_set_workspace (bool top_level, bool debug,
598  const octave::symbol_scope& scope,
599  bool update_variable_editor) = 0;
600 
601  virtual void do_clear_workspace (void) = 0;
602 
603  virtual void do_set_history (const string_vector& hist) = 0;
604  virtual void do_append_history (const std::string& hist_entry) = 0;
605  virtual void do_clear_history (void) = 0;
606 
607  virtual void do_pre_input_event (void) = 0;
608  virtual void do_post_input_event (void) = 0;
609 
610  virtual void
611  do_enter_debugger_event (const std::string& file, int line) = 0;
612 
613  virtual void
614  do_execute_in_debugger_event (const std::string& file, int line) = 0;
615 
616  virtual void do_exit_debugger_event (void) = 0;
617 
618  virtual void do_update_breakpoint (bool insert,
619  const std::string& file, int line,
620  const std::string& cond) = 0;
621 
622  virtual void do_set_default_prompts (std::string& ps1, std::string& ps2,
623  std::string& ps4) = 0;
624 
625  virtual void do_show_preferences (void) = 0;
626 
627  virtual void do_show_doc (const std::string& file) = 0;
628 
629  virtual void do_register_doc (const std::string& file) = 0;
630 
631  virtual void do_unregister_doc (const std::string& file) = 0;
632 
633  virtual void
634  do_edit_variable (const std::string& name, const octave_value& val) = 0;
635 };
636 
637 #endif
octave_value arg_c
Definition: sylvester.cc:71
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
#define C(a, b)
Definition: Faddeeva.cc:246
The value of lines which begin with a space character are not saved in the history list A value of all commands are saved on the history list
Definition: oct-hist.cc:734
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6348
std::string filename
Definition: urlwrite.cc:121
std::string dirname(const std::string &path)
Definition: file-ops.cc:353
to define functions rather than attempting to enter them directly on the command line The block of commands is executed as soon as you exit the editor To avoid executing any simply delete all the lines from the buffer before leaving the editor When invoked with no edit the previously executed command
Definition: oct-hist.cc:587
octave_value arg
Definition: pr-output.cc:3244
static bool debug
octave_value arg_b
Definition: sylvester.cc:70
nd deftypefn *std::string name
Definition: sysdep.cc:647
F77_RET_T const F77_INT F77_CMPLX * A
octave_value retval
Definition: data.cc:6246
MArray< T > filter(MArray< T > &b, MArray< T > &a, MArray< T > &x, MArray< T > &si, int dim=0)
Definition: filter.cc:43
octave_value arg_a
Definition: sylvester.cc:69
p
Definition: lu.cc:138
std::string method
Definition: urlwrite.cc:123
void add_method(T *obj, void(T::*method)(void))
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888