source: src/Actions/ActionQueue.hpp@ 99c705

Candidate_v1.6.1 ChemicalSpaceEvaluator
Last change on this file since 99c705 was 559293, checked in by Frederik Heber <frederik.heber@…>, 7 years ago

ActionQueue has predicates to check if current Action is Process or MakroAction.

  • Property mode set to 100644
File size: 9.6 KB
RevLine 
[628577]1/*
2 * ActionQueue.hpp
3 *
4 * Created on: Aug 16, 2013
5 * Author: heber
6 */
7
8#ifndef ACTIONQUEUE_HPP_
9#define ACTIONQUEUE_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include "CodePatterns/Singleton.hpp"
17
[29b52b]18#include "CodePatterns/Observer/Channels.hpp"
19#include "CodePatterns/Observer/Observable.hpp"
[74459a]20
21#ifdef HAVE_ACTION_THREAD
[415ddd]22#include <boost/thread.hpp>
[74459a]23#endif
[690741]24#include <vector>
[1d3563]25
[f54cda]26#include "Actions/Action.hpp"
[b5b01e]27#include "Actions/ActionState.hpp"
[26b4eb4]28#include "Actions/ActionStatusList.hpp"
[628577]29
[74459a]30#ifdef HAVE_ACTION_THREAD
[415ddd]31void stopQueue();
32void waitQueue();
[74459a]33#endif
[415ddd]34
[11d433]35class CommandLineParser;
36
[628577]37namespace MoleCuilder {
38
[6367dd]39class ActionHistory;
[ed3944]40class ActionRegistry;
41class ActionTrait;
[f3db60]42class DryRunAdvocate;
[628577]43
[29b52b]44namespace Queuedetail {
45 template <class T> const T* lastChanged()
46 {
47 ASSERT(0, "Queuedetail::lastChanged() - only specializations may be used.");
48 return NULL;
49 }
50}
51
[628577]52/** This class combines the whole handling of Actions into a single class.
53 *
[1d3563]54 * It spawns new Actions by its internal ActionRegistry. Spawned Actions are
55 * automatically queued and placed into a History after execution.
[628577]56 */
[29b52b]57class ActionQueue : public Singleton<ActionQueue>, public Observable
[628577]58{
59 friend class Singleton<ActionQueue>;
60public:
[690741]61 typedef std::vector<std::string> ActionTokens_t;
[af5384]62 typedef std::vector< Action * > ActionQueue_t;
[1d3563]63
[29b52b]64 //!> channels for this observable
65 enum NotificationType {
66 ActionQueued, // new action was queued
67 NotificationType_MAX // denotes the maximum of available notification types
68 };
69
70 //>! access to last changed element (atom or molecule)
71 template <class T> const T* lastChanged() const
72 { return Queuedetail::lastChanged<T>(); }
73
[05c989]74 /** Queues the Action with \a name to be called.
75 *
[7fc447]76 * \param name token of Action to actionqueue
[f54cda]77 * \param state whether Actions needs to be filled via a Dialog or not
[05c989]78 */
[f54cda]79 void queueAction(const std::string &name, enum Action::QueryOptions state = Action::Interactive);
80
[1d3563]81 /** Returns the spawned action by token \a name.
82 *
[7fc447]83 * Action is checked into internal actionqueue.
[1d3563]84 *
[10aee4]85 * \return ref to newly spawned action
[1d3563]86 */
[10aee4]87 const Action& getActionByName(const std::string &name);
[1d3563]88
89 /** Checks whether the Action is known by the given \a name.
90 *
91 * \param name token of action to check
92 * \return true - token is known, false - else
93 */
[a6ceab]94 bool isActionKnownByName(const std::string &name) const;
[1d3563]95
[126867]96 /** Register an Action with the ActionRegistry.
97 *
98 * \param _action action to add
99 */
100 void registerAction(Action *_action);
101
[690741]102 /** Returns the vector with the tokens of all currently known Actions.
103 *
104 * \return list of all tokens
105 */
106 const ActionTokens_t getListOfActions() const;
107
108 /** Returns the trait to an Action.
109 *
110 * \param name name of Action
111 * \return const ref to its default Trait.
112 */
[a6ceab]113 const ActionTrait& getActionsTrait(const std::string &name) const;
[690741]114
[7fc447]115 /** Print the current contents of the actionqueue as CLI instantiated list of Actions.
[46b181]116 *
117 * This is useful for storing the current session.
118 *
119 * \param output output stream to print to
120 */
121 void outputAsCLI(std::ostream &output) const;
122
[7fc447]123 /** Print the current contents of the actionqueue as Python instantiated list of Actions.
[477012]124 *
125 * This is useful for storing the current session.
126 *
127 * \param output output stream to print to
128 */
129 void outputAsPython(std::ostream &output) const;
130
[af5384]131 /** Undoes last called Acfriend void ::cleanUp();tion.
[6367dd]132 *
133 */
134 void undoLast();
135
136 /** Redoes last undone Action.
137 *
138 */
139 void redoLast();
140
[c01fec]141 /** Checks whether there is one completed Action stored in ActionHistory in the past.
142 *
143 * @return true - at least one Action to undo present, false - else
144 */
145 bool canUndo() const;
146
147 /** Checks whether there is one completed Action stored in ActionHistory in the future.
148 *
149 * @return true - at least one Action to redo present, false - else
150 */
151 bool canRedo() const;
152
[a61dbb]153 /** Return status of last executed action.
154 *
155 * \return true - action executed correctly, false - else
156 */
157 bool getLastActionOk() const
158 { return lastActionOk; }
159
[26b4eb4]160 /** Getter to ref to list of status messages.
161 *
162 * This is meant for UIs to registers as Observables.
163 *
164 * \return ref to StatusList variable
165 */
166 ActionStatusList& getStatusList()
167 { return StatusList; }
168
[f3db60]169 /** Getter for isDryRun state flag.
170 *
171 * \return true - ActionQueue does not execute Actions but skips, false - else
172 */
173 bool getDryRun() const
174 { return dryrun_flag; }
175
[a87d1e2]176 /** States whether the ActionQueue is currently executing Actions or done executing.
177 *
178 * \return true - ActionQueue is done executing Actions.
179 */
180 bool isIdle() const;
181
[559293]182 /** States whether the current Action in the ActionQueue is a Process.
183 *
184 * \return true - ActionQueue is currently executing a process.
185 */
186 bool isProcess() const;
187
188 /** States whether the current Action in the ActionQueue is a MakroAction.
189 *
190 * \return true - ActionQueue is currently executing a MakroAction.
191 */
192 bool isMakroAction() const;
193
194 /** Getter to the current Action.
195 *
196 * \note Using this ref is only useful during the execution of the Action, e.g.
197 * when an Action inside the ActionSequence of a MakroAction needs access to the
198 * MakroAction itself (to signal stop). \sa MoleCuilder::ForceAnnealingAction::performCall()
199 *
200 * \warning Due to the multi-threaded nature of the ActionQueue this is very
201 * dangerous to use in other circumstances.
202 *
203 * \return const ref to the currently executed action
204 */
205 const Action& getCurrentAction() const;
206
[6367dd]207private:
208 //!> grant Action access to internal history functions.
209 friend class Action;
[11d433]210 //!> grant CommandLineParser access to stop and clearQueue()
211 friend class ::CommandLineParser;
[f3db60]212 //!> grant Advocate access to setting dryrun
213 friend class DryRunAdvocate;
[6367dd]214
[10aee4]215 /** Queues the Action with \a name to be called.
216 *
217 * \param _action action to add
218 * \param state whether Actions needs to be filled via a Dialog or not
219 */
220 void queueAction(const Action * const _action, enum Action::QueryOptions state = Action::Interactive);
221
[6367dd]222 /** Wrapper function to add state to ActionHistory.
223 *
224 * \param _Action Action whose state to add
225 * \param _state state to add
226 */
227 void addElement(Action* _Action, ActionState::ptr _state);
228
[26b4eb4]229 /** Advocate function to add status message to the list.
230 *
231 */
232 void pushStatus(const std::string &_msg)
233 { StatusList.pushMessage(_msg); }
234
[6367dd]235 /** Wrapper function to clear ActionHistory.
236 *
237 */
238 void clear();
239
[601ef8]240 /** Clears all actions present in the actionqueues from \a _fromAction.
[7f1a1a]241 *
[601ef8]242 * @param _fromAction 0 if all Actions to clear or else
[7f1a1a]243 */
[601ef8]244 void clearQueue(const size_t _fromAction = 0);
[7f1a1a]245
[74459a]246#ifdef HAVE_ACTION_THREAD
[10aee4]247 boost::thread &getRunThread()
248 { return run_thread; }
[601ef8]249
250 /** Clears the temporary queue.
251 *
252 */
253 void clearTempQueue();
254
255 /** Sets the run_thread_isIdle flag.
256 *
257 * @param _flag state to set to
258 */
259 void setRunThreadIdle(const bool _flag);
260
[415ddd]261 /** Runs the ActionQueue.
262 *
263 */
264 void run();
265
266 friend void ::stopQueue();
267
268 /** Stops the internal thread.
269 *
270 */
271 void stop();
272
273 friend void ::waitQueue();
274
275 /** Wait till all currently queued actions are processed.
276 *
277 */
278 void wait();
[601ef8]279
280 /** Moves all action from tempqueue into real queue.
281 *
282 */
283 void insertTempQueue();
284
[74459a]285#endif
[415ddd]286
[975b83]287 /** Insert an action after CurrentAction.
288 *
289 * This is implemented only to allow action's COMMAND to work. If we
290 * were to use queueAction, actions would come after all other already
291 * present actions.
292 */
293 void insertAction(Action *_action, enum Action::QueryOptions state);
294
[f3db60]295 /** Sets the current state of the \a isDryRun flag.
296 *
297 * \param _dryrun true - Actions will not get executed anymore, false - else
298 */
299 void setDryRun(const bool _dryrun)
300 { dryrun_flag = _dryrun; }
301
302 /** Checks whether next Action should be skipped or not.
303 *
304 * \param _nextaction next action to execute to inspect whether it unsets dryrun_flag
305 * \return true - dryrun_flag set and \a _nextaction is not unsetting dry run
306 */
307 bool isDryRun(const Action *_nextaction) const;
308
[628577]309private:
[1d3563]310 /** Private cstor for ActionQueue.
311 *
312 * Must be private as is singleton.
313 *
314 */
[628577]315 ActionQueue();
[1d3563]316
317 /** Dstor for ActionQueue.
318 *
319 */
[628577]320 ~ActionQueue();
321
[29b52b]322private:
323 friend const Action *Queuedetail::lastChanged<Action>();
324 static const Action *_lastchangedaction;
325
[628577]326 //!> ActionRegistry to spawn new actions
[ed3944]327 ActionRegistry *AR;
[1d3563]328
[6367dd]329 //!> ActionHistory is for undoing and redoing actions, requires ActionRegistry fully initialized
330 ActionHistory *history;
331
[7fc447]332 //!> internal actionqueue of actions
333 ActionQueue_t actionqueue;
[af5384]334
[601ef8]335 //!> indicates that the last action has failed
336 bool lastActionOk;
337
[7fc447]338 //!> point to current action in actionqueue
[af5384]339 size_t CurrentAction;
[415ddd]340
[a87d1e2]341#ifdef HAVE_ACTION_THREAD
[415ddd]342 //!> internal temporary actionqueue of actions used by insertAction()
343 ActionQueue_t tempqueue;
344
345 //!> internal thread to call Actions
346 boost::thread run_thread;
347
348 //!> internal mutex to synchronize access to queue
[94232b]349 mutable boost::mutex mtx_queue;
[415ddd]350
351 //!> conditional variable notifying when run_thread is idling
352 boost::condition_variable cond_idle;
353
354 //!> flag indicating whether run_thread is idle or not
355 bool run_thread_isIdle;
356
357 //!> internal mutex to synchronize access to run_thread_isIdle
[94232b]358 mutable boost::mutex mtx_idle;
[74459a]359#endif
[26b4eb4]360
361 //!> internal list of status messages from Actions for UIs to display
362 ActionStatusList StatusList;
[f3db60]363
364 //!> internal flag whether to call or skip actions (i.e. do a dry run)
365 bool dryrun_flag;
[628577]366};
[8859b5]367namespace Queuedetail {
368 template <> inline const Action* lastChanged<Action>() { return ActionQueue::_lastchangedaction; }
369}
[628577]370
371};
372
373#endif /* ACTIONQUEUE_HPP_ */
Note: See TracBrowser for help on using the repository browser.