GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
octave-link.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2013 John W. Eaton
4 Copyright (C) 2011-2013 Jacob Dawid
5 Copyright (C) 2011-2013 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 the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 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 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if !defined (octave_octave_link_h)
26 #define octave_octave_link_h 1
27 
28 #include <string>
29 
30 #include "event-queue.h"
31 
32 class octave_mutex;
33 class string_vector;
34 class workspace_element;
35 
36 // \class OctaveLink
37 // \brief Provides threadsafe access to octave.
38 // \author Jacob Dawid
39 //
40 // This class is a wrapper around octave and provides thread safety by
41 // buffering access operations to octave and executing them in the
42 // readline event hook, which lives in the octave thread.
43 
44 class
47 {
48 protected:
49 
50  octave_link (void);
51 
52 public:
53 
54  virtual ~octave_link (void) { }
55 
56  static void generate_events (void)
57  {
58  if (enabled ())
59  instance->do_generate_events ();
60  }
61 
62  // If disable is TRUE, then no additional events will be processed
63  // other than exit.
64 
65  static void process_events (bool disable = false)
66  {
67  if (enabled ())
68  {
69  if (disable)
70  instance->link_enabled = false;
71 
72  instance->do_process_events ();
73  }
74  }
75 
76  static void discard_events (void)
77  {
78  if (enabled ())
79  instance->do_discard_events ();
80  }
81 
82  static bool exit (int status)
83  {
84  bool retval = false;
85 
86  if (instance_ok ())
87  retval = instance->do_exit (status);
88 
89  return retval;
90  }
91 
92  template <class T>
93  static void post_event (T *obj, void (T::*method) (void))
94  {
95  if (enabled ())
96  instance->do_post_event (obj, method);
97  }
98 
99  template <class T, class A>
100  static void post_event (T *obj, void (T::*method) (A), A arg)
101  {
102  if (enabled ())
103  instance->do_post_event (obj, method, arg);
104  }
105 
106  template <class T, class A>
107  static void post_event (T *obj, void (T::*method) (const A&), const A& arg)
108  {
109  if (enabled ())
110  instance->do_post_event (obj, method, arg);
111  }
112 
113  template <class T, class A, class B>
114  static void post_event (T *obj, void (T::*method) (const A&, const B&),
115  const A& arg_a, const B& arg_b)
116  {
117  if (enabled ())
118  instance->do_post_event (obj, method, arg_a, arg_b);
119  }
120 
121  static void entered_readline_hook (void)
122  {
123  if (enabled ())
124  instance->do_entered_readline_hook ();
125  }
126 
127  static void finished_readline_hook (void)
128  {
129  if (enabled ())
130  instance->do_finished_readline_hook ();
131  }
132 
133  static bool
134  edit_file (const std::string& file)
135  {
136  return enabled () ? instance->do_edit_file (file) : false;
137  }
138 
139  static bool
140  prompt_new_edit_file (const std::string& file)
141  {
142  return enabled () ? instance->do_prompt_new_edit_file (file) : false;
143  }
144 
145  static int
146  message_dialog (const std::string& dlg, const std::string& msg,
147  const std::string& title)
148  {
149  return enabled () ? instance->do_message_dialog (dlg, msg, title) : 0;
150  }
151 
152  static std::string
153  question_dialog (const std::string& msg, const std::string& title,
154  const std::string& btn1, const std::string& btn2,
155  const std::string& btn3, const std::string& btndef)
156  {
157  return enabled () ? instance->do_question_dialog (msg, title, btn1,
158  btn2, btn3, btndef) : 0;
159  }
160 
161  static std::pair<std::list<int>, int>
162  list_dialog (const std::list<std::string>& list,
163  const std::string& mode,
164  int width, int height,
165  const std::list<int>& initial_value,
166  const std::string& name,
167  const std::list<std::string>& prompt,
168  const std::string& ok_string,
169  const std::string& cancel_string)
170  {
171  return enabled ()
172  ? instance->do_list_dialog (list, mode, width, height,
173  initial_value, name, prompt,
174  ok_string, cancel_string)
175  : std::pair<std::list<int>, int> ();
176  }
177 
178  static std::list<std::string>
179  input_dialog (const std::list<std::string>& prompt,
180  const std::string& title,
181  const std::list<float>& nr,
182  const std::list<float>& nc,
183  const std::list<std::string>& defaults)
184  {
185  return enabled ()
186  ? instance->do_input_dialog (prompt, title, nr, nc, defaults)
187  : std::list<std::string> ();
188  }
189 
190  typedef std::list<std::pair<std::string, std::string> > filter_list;
191 
192  static std::list<std::string>
193  file_dialog (const filter_list& filter, const std::string& title,
194  const std::string& filename, const std::string& dirname,
195  const std::string& multimode)
196  {
197  return enabled ()
198  ? instance->do_file_dialog (filter, title, filename, dirname,
199  multimode)
200  : std::list<std::string> ();
201  }
202 
203 
204  static int debug_cd_or_addpath_error (const std::string& file,
205  const std::string& dir,
206  bool addpath_option)
207  {
208  return enabled ()
209  ? instance->do_debug_cd_or_addpath_error (file, dir, addpath_option)
210  : 0;
211  }
212 
213  static void change_directory (const std::string& dir)
214  {
215  if (enabled ())
216  instance->do_change_directory (dir);
217  }
218 
219  // Preserves pending input.
220  static void execute_command_in_terminal (const std::string& command)
221  {
222  if (enabled ())
223  instance->do_execute_command_in_terminal (command);
224  }
225 
226  static void set_workspace (void);
227 
228  static void set_workspace (bool top_level,
229  const std::list<workspace_element>& ws)
230  {
231  if (enabled ())
232  instance->do_set_workspace (top_level, ws);
233  }
234 
235  static void clear_workspace (void)
236  {
237  if (enabled ())
238  instance->do_clear_workspace ();
239  }
240 
241  static void set_history (const string_vector& hist)
242  {
243  if (enabled ())
244  instance->do_set_history (hist);
245  }
246 
247  static void append_history (const std::string& hist_entry)
248  {
249  if (enabled ())
250  instance->do_append_history (hist_entry);
251  }
252 
253  static void clear_history (void)
254  {
255  if (enabled ())
256  instance->do_clear_history ();
257  }
258 
259  static void pre_input_event (void)
260  {
261  if (enabled ())
262  instance->do_pre_input_event ();
263  }
264 
265  static void post_input_event (void)
266  {
267  if (enabled ())
268  instance->do_post_input_event ();
269  }
270 
271  static void enter_debugger_event (const std::string& file, int line)
272  {
273  if (enabled ())
274  {
275  instance->debugging = true;
276 
277  instance->do_enter_debugger_event (file, line);
278  }
279  }
280 
281  static void execute_in_debugger_event (const std::string& file, int line)
282  {
283  if (enabled ())
284  instance->do_execute_in_debugger_event (file, line);
285  }
286 
287  static void exit_debugger_event (void)
288  {
289  if (enabled () && instance->debugging)
290  {
291  instance->debugging = false;
292 
293  instance->do_exit_debugger_event ();
294  }
295  }
296 
297  static void
298  update_breakpoint (bool insert, const std::string& file, int line)
299  {
300  if (enabled ())
301  instance->do_update_breakpoint (insert, file, line);
302  }
303 
304  static void connect_link (octave_link *);
305 
306  static void set_default_prompts (std::string& ps1, std::string& ps2,
307  std::string& ps4)
308  {
309  if (enabled ())
310  instance->do_set_default_prompts (ps1, ps2, ps4);
311  }
312 
313  static bool enabled (void)
314  {
315  return instance_ok () ? instance->link_enabled : false;
316  }
317 
318  static bool
319  show_preferences ()
320  {
321  if (enabled ())
322  {
323  instance->do_show_preferences ();
324  return true;
325  }
326  else
327  return false;
328  }
329 
330  static bool
331  show_doc (const std::string & file)
332  {
333  if (enabled ())
334  {
335  instance->do_show_doc (file);
336  return true;
337  }
338  else
339  return false;
340 
341  }
342 
343 private:
344 
346 
347  // No copying!
348 
349  octave_link (const octave_link&);
350 
352 
353  static bool instance_ok (void) { return instance != 0; }
354 
355 protected:
356 
357  // Semaphore to lock access to the event queue.
359 
360  // Event Queue.
362 
363  bool debugging;
365 
366  void do_generate_events (void);
367  void do_process_events (void);
368  void do_discard_events (void);
369 
370  template <class T>
371  void do_post_event (T *obj, void (T::*method) (void))
372  {
373  gui_event_queue.add_method (obj, method);
374  }
375 
376  template <class T, class A>
377  void do_post_event (T *obj, void (T::*method) (A), A arg)
378  {
379  gui_event_queue.add_method (obj, method, arg);
380  }
381 
382  template <class T, class A>
383  void do_post_event (T *obj, void (T::*method) (const A&), const A& arg)
384  {
385  gui_event_queue.add_method (obj, method, arg);
386  }
387 
388  void do_entered_readline_hook (void) { }
390 
391  virtual bool do_exit (int status) = 0;
392 
393  virtual bool do_edit_file (const std::string& file) = 0;
394  virtual bool do_prompt_new_edit_file (const std::string& file) = 0;
395 
396  virtual int
397  do_message_dialog (const std::string& dlg, const std::string& msg,
398  const std::string& title) = 0;
399 
400  virtual std::string
401  do_question_dialog (const std::string& msg, const std::string& title,
402  const std::string& btn1, const std::string& btn2,
403  const std::string& btn3, const std::string& btndef) = 0;
404 
405  virtual std::pair<std::list<int>, int>
406  do_list_dialog (const std::list<std::string>& list,
407  const std::string& mode,
408  int width, int height,
409  const std::list<int>& initial_value,
410  const std::string& name,
411  const std::list<std::string>& prompt,
412  const std::string& ok_string,
413  const std::string& cancel_string) = 0;
414 
415  virtual std::list<std::string>
416  do_input_dialog (const std::list<std::string>& prompt,
417  const std::string& title,
418  const std::list<float>& nr,
419  const std::list<float>& nc,
420  const std::list<std::string>& defaults) = 0;
421 
422  virtual std::list<std::string>
423  do_file_dialog (const filter_list& filter, const std::string& title,
424  const std::string& filename, const std::string& dirname,
425  const std::string& multimode) = 0;
426 
427  virtual int
428  do_debug_cd_or_addpath_error (const std::string& file,
429  const std::string& dir,
430  bool addpath_option) = 0;
431 
432  virtual void do_change_directory (const std::string& dir) = 0;
433 
434  virtual void do_execute_command_in_terminal (const std::string& command) = 0;
435 
436  virtual void
437  do_set_workspace (bool top_level,
438  const std::list<workspace_element>& ws) = 0;
439 
440  virtual void do_clear_workspace (void) = 0;
441 
442  virtual void do_set_history (const string_vector& hist) = 0;
443  virtual void do_append_history (const std::string& hist_entry) = 0;
444  virtual void do_clear_history (void) = 0;
445 
446  virtual void do_pre_input_event (void) = 0;
447  virtual void do_post_input_event (void) = 0;
448 
449  virtual void
450  do_enter_debugger_event (const std::string& file, int line) = 0;
451 
452  virtual void
453  do_execute_in_debugger_event (const std::string& file, int line) = 0;
454 
455  virtual void do_exit_debugger_event (void) = 0;
456 
457  virtual void do_update_breakpoint (bool insert,
458  const std::string& file, int line) = 0;
459 
460  virtual void do_set_default_prompts (std::string& ps1, std::string& ps2,
461  std::string& ps4) = 0;
462 
463  virtual void do_show_preferences (void) = 0;
464 
465  virtual void do_show_doc (const std::string &file) = 0;
466 };
467 
468 #endif // OCTAVELINK_H