File: DocumentThread.hh

package info (click to toggle)
cadabra2 2.4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 78,732 kB
  • sloc: ansic: 133,450; cpp: 92,064; python: 1,530; javascript: 203; sh: 184; xml: 182; objc: 53; makefile: 51
file content (165 lines) | stat: -rw-r--r-- 5,288 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

#pragma once

#include <queue>
#include <mutex>
#include <stack>
#include <map>

#include "DataCell.hh"
#include "tree.hh"

namespace cadabra {

	class ActionBase;
	class ActionAddCell;
	class ActionPositionCursor;
	class ActionRemoveCell;
	class ActionSetRunStatus;
	class ActionSplitCell;
	class ActionInsertText;
	class ActionCompleteText;
	class ActionEraseText;
	class ComputeThread;
	class GUIBase;

	/// \ingroup clientserver
	///
	/// A base class with all the logic to manipulate a Cadabra
	/// notebook document. Relies on the various objects derived from
	/// ActionBase in order to get actual work done. All methods here
	/// will always run on the GUI thread.
	///
	/// In order to implement a GUI, derive from both DocumentThread
	/// and GUIBase and then implement the virtual functions of the
	/// latter (those implement basic insertion/removal of notebook
	/// cells; the logic to figure out which ones and to implement the
	/// undo/redo stack is all in the GUI-agnostic DocumentThread).


	class DocumentThread {
		public:
			DocumentThread(GUIBase *);

			/// It is not possible to copy-construct a DocumentThread as
			/// it holds on to resources which are not easily copied
			/// (such as GUI elements).

			DocumentThread(const DocumentThread&)=delete;

			/// Let the notebook know about the ComputeThread so that it
			/// can send cells for evaluation. Notebook does NOT own this
			/// pointer.

			virtual void set_compute_thread(ComputeThread *);

			/// Ensure that the gui has an up-to-date representation of the
			/// dtree. Traverses the entire tree so is expensive to run and
			/// should only be used when loading new documents or creating
			/// a new canvas view.

			void build_visual_representation();

			/// All changes to the document should be made by submitting
			/// ActionBase derived objects to the 'queue_action' function,
			/// so that an undo stack can be kept. They are then processed
			/// by calling the 'process_action_queue' method (only
			/// available from this thread).

			void queue_action(std::shared_ptr<ActionBase>);

			/// Setup an empty new document with a single Python input cell.

			void new_document();

			/// Load a new notebook from a JSON string. Should only be called
			/// from the GUI thread. Will cancel any pending operations on the
			/// existing notebook (if present) first.

			void load_from_string(const std::string&);

			virtual void on_interactive_output(const nlohmann::json& msg);

			virtual void set_progress(const std::string& msg, int cur_step, int total_steps);

			/// One undo step.
			void undo();

			/// Find string, return match, or a (doc.end(), std::string::npos).
			std::pair<DTree::iterator, size_t> find_string(DTree::iterator start_it, size_t start_pos, const std::string& f, bool case_ins) const;
			
			friend ActionBase;
			friend ActionAddCell;
			friend ActionPositionCursor;
			friend ActionRemoveCell;
			friend ActionSplitCell;
			friend ActionSetRunStatus;
			friend ActionInsertText;
			friend ActionCompleteText;			
			friend ActionEraseText;

			class Prefs {
				public:
					using ColorMap = std::map<std::string, std::string>;
					Prefs(bool use_defaults = false);
					void save();
					int font_step;
					bool highlight;
					bool is_registered;
					bool is_anonymous;
					std::map<std::string, ColorMap> colours;
					std::string git_path;
					std::string python_path;
					bool move_into_new_cell;
					bool tab_completion;
				private:
					nlohmann::json data;
					std::string    config_path;
				};
			Prefs prefs;

			/// Set user details which will be sent to the Cadabra log
			/// server.

			void set_user_details(const std::string& name, const std::string& email, const std::string& affiliation);

		protected:
			GUIBase       *gui;
			ComputeThread *compute;

			/// The actual document tree. This object is only modified on
			/// the GUI thread, either directly by code in
			/// DocumentThread, or by code in the various objects derived
			/// from ActionBase. In particular, ComputeThread cannot
			/// access this tree directly.

			DTree          doc;

			/// The action undo/redo/todo stacks and logic to execute
			/// them. These stacks can be accessed from both the
			/// DocumentThread as well as the ComputeThread (the latter
			/// does it through the DocumentThread::queue_action method),
			/// so they need a mutex to access them.

			std::mutex                                       stack_mutex;
			typedef std::stack<std::shared_ptr<ActionBase> > ActionStack;
			ActionStack                                      undo_stack, redo_stack;
			std::queue<std::shared_ptr<ActionBase> >         pending_actions;
			bool                                             disable_stacks;

			/// Process the action queue. It is allowed to call queue_action() above
			/// while this is running. So a running action can add more actions.

			void                                             process_action_queue();
			virtual bool on_unhandled_error(const std::exception& err);



			/// Help system
			enum class help_t { algorithm, property, latex, none };
			bool help_type_and_topic(const std::string& before, const std::string& after,
			                         help_t& help_type, std::string& help_topic) const;

		};

	}