source: src/Actions/ActionQueue.hpp@ 9a4949

Last change on this file since 9a4949 was 9a4949, checked in by Frederik Heber <heber@…>, 10 years ago

Added extra flag run_thread_running to ActionQueue.

  • helgrind admonished race conditions when thread is joined. This did not fix them but should be safer as we cannot know whether the other thread has already been started when suddenly shutting down molecuilder due to an exception.
  • Property mode set to 100644
File size: 7.3 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;
[628577]42
[29b52b]43namespace Queuedetail {
44 template <class T> const T* lastChanged()
45 {
46 ASSERT(0, "Queuedetail::lastChanged() - only specializations may be used.");
47 return NULL;
48 }
49}
50
[628577]51/** This class combines the whole handling of Actions into a single class.
52 *
[1d3563]53 * It spawns new Actions by its internal ActionRegistry. Spawned Actions are
54 * automatically queued and placed into a History after execution.
[628577]55 */
[29b52b]56class ActionQueue : public Singleton<ActionQueue>, public Observable
[628577]57{
58 friend class Singleton<ActionQueue>;
59public:
[690741]60 typedef std::vector<std::string> ActionTokens_t;
[af5384]61 typedef std::vector< Action * > ActionQueue_t;
[1d3563]62
[29b52b]63 //!> channels for this observable
64 enum NotificationType {
65 ActionQueued, // new action was queued
66 NotificationType_MAX // denotes the maximum of available notification types
67 };
68
69 //>! access to last changed element (atom or molecule)
70 template <class T> const T* lastChanged() const
71 { return Queuedetail::lastChanged<T>(); }
72
[05c989]73 /** Queues the Action with \a name to be called.
74 *
[7fc447]75 * \param name token of Action to actionqueue
[f54cda]76 * \param state whether Actions needs to be filled via a Dialog or not
[05c989]77 */
[f54cda]78 void queueAction(const std::string &name, enum Action::QueryOptions state = Action::Interactive);
79
80 /** Queues the Action with \a name to be called.
81 *
82 * \param _action action to add
83 * \param state whether Actions needs to be filled via a Dialog or not
84 */
[7f1a1a]85 void queueAction(const Action * const _action, enum Action::QueryOptions state = Action::Interactive);
[05c989]86
[1d3563]87 /** Returns the spawned action by token \a name.
88 *
[7fc447]89 * Action is checked into internal actionqueue.
[1d3563]90 *
91 * \return pointer to newly spawned action
92 */
[a6ceab]93 Action* getActionByName(const std::string &name);
[1d3563]94
95 /** Checks whether the Action is known by the given \a name.
96 *
97 * \param name token of action to check
98 * \return true - token is known, false - else
99 */
[a6ceab]100 bool isActionKnownByName(const std::string &name) const;
[1d3563]101
[126867]102 /** Register an Action with the ActionRegistry.
103 *
104 * \param _action action to add
105 */
106 void registerAction(Action *_action);
107
[690741]108 /** Returns the vector with the tokens of all currently known Actions.
109 *
110 * \return list of all tokens
111 */
112 const ActionTokens_t getListOfActions() const;
113
114 /** Returns the trait to an Action.
115 *
116 * \param name name of Action
117 * \return const ref to its default Trait.
118 */
[a6ceab]119 const ActionTrait& getActionsTrait(const std::string &name) const;
[690741]120
[7fc447]121 /** Print the current contents of the actionqueue as CLI instantiated list of Actions.
[46b181]122 *
123 * This is useful for storing the current session.
124 *
125 * \param output output stream to print to
126 */
127 void outputAsCLI(std::ostream &output) const;
128
[7fc447]129 /** Print the current contents of the actionqueue as Python instantiated list of Actions.
[477012]130 *
131 * This is useful for storing the current session.
132 *
133 * \param output output stream to print to
134 */
135 void outputAsPython(std::ostream &output) const;
136
[af5384]137 /** Undoes last called Acfriend void ::cleanUp();tion.
[6367dd]138 *
139 */
140 void undoLast();
141
142 /** Redoes last undone Action.
143 *
144 */
145 void redoLast();
146
[a61dbb]147 /** Return status of last executed action.
148 *
149 * \return true - action executed correctly, false - else
150 */
151 bool getLastActionOk() const
152 { return lastActionOk; }
153
[74459a]154#ifdef HAVE_ACTION_THREAD
[415ddd]155 boost::thread &getRunThread()
156 { return run_thread; }
[74459a]157#endif
[af5384]158
[26b4eb4]159 /** Getter to ref to list of status messages.
160 *
161 * This is meant for UIs to registers as Observables.
162 *
163 * \return ref to StatusList variable
164 */
165 ActionStatusList& getStatusList()
166 { return StatusList; }
167
[6367dd]168private:
169 //!> grant Action access to internal history functions.
170 friend class Action;
[11d433]171 //!> grant CommandLineParser access to stop and clearQueue()
172 friend class ::CommandLineParser;
[6367dd]173
174 /** Wrapper function to add state to ActionHistory.
175 *
176 * \param _Action Action whose state to add
177 * \param _state state to add
178 */
179 void addElement(Action* _Action, ActionState::ptr _state);
180
[26b4eb4]181 /** Advocate function to add status message to the list.
182 *
183 */
184 void pushStatus(const std::string &_msg)
185 { StatusList.pushMessage(_msg); }
186
[6367dd]187 /** Wrapper function to clear ActionHistory.
188 *
189 */
190 void clear();
191
[7f1a1a]192 /** Clears all actions currently present in the actionqueues.
193 *
194 */
195 void clearQueue();
196
[74459a]197#ifdef HAVE_ACTION_THREAD
[415ddd]198 /** Runs the ActionQueue.
199 *
200 */
201 void run();
202
203 friend void ::stopQueue();
204
205 /** Stops the internal thread.
206 *
207 */
208 void stop();
209
210 friend void ::waitQueue();
211
212 /** Wait till all currently queued actions are processed.
213 *
214 */
215 void wait();
[74459a]216#endif
[415ddd]217
[975b83]218 /** Insert an action after CurrentAction.
219 *
220 * This is implemented only to allow action's COMMAND to work. If we
221 * were to use queueAction, actions would come after all other already
222 * present actions.
223 */
224 void insertAction(Action *_action, enum Action::QueryOptions state);
225
[415ddd]226 /** Moves all action from tempqueue into real queue.
227 *
228 */
229 void insertTempQueue();
230
[628577]231private:
[1d3563]232 /** Private cstor for ActionQueue.
233 *
234 * Must be private as is singleton.
235 *
236 */
[628577]237 ActionQueue();
[1d3563]238
239 /** Dstor for ActionQueue.
240 *
241 */
[628577]242 ~ActionQueue();
243
[29b52b]244private:
245 friend const Action *Queuedetail::lastChanged<Action>();
246 static const Action *_lastchangedaction;
247
[628577]248 //!> ActionRegistry to spawn new actions
[ed3944]249 ActionRegistry *AR;
[1d3563]250
[6367dd]251 //!> ActionHistory is for undoing and redoing actions, requires ActionRegistry fully initialized
252 ActionHistory *history;
253
[7fc447]254 //!> internal actionqueue of actions
255 ActionQueue_t actionqueue;
[af5384]256
[7fc447]257 //!> point to current action in actionqueue
[af5384]258 size_t CurrentAction;
[415ddd]259
260 //!> internal temporary actionqueue of actions used by insertAction()
261 ActionQueue_t tempqueue;
262
[a61dbb]263 //!> indicates that the last action has failed
264 bool lastActionOk;
265
[74459a]266#ifdef HAVE_ACTION_THREAD
[415ddd]267 //!> internal mutex to synchronize access to queue
268 boost::mutex mtx_queue;
269
270 //!> conditional variable notifying when run_thread is idling
271 boost::condition_variable cond_idle;
272
273 //!> flag indicating whether run_thread is idle or not
274 bool run_thread_isIdle;
275
276 //!> internal mutex to synchronize access to run_thread_isIdle
[23b6cf]277 boost::mutex mtx_run_thread_isIdle;
[74459a]278#endif
[26b4eb4]279
280 //!> internal list of status messages from Actions for UIs to display
281 ActionStatusList StatusList;
[23b6cf]282
283 // set run_thread to end such that others are initialized first (especially mutexes)
284#ifdef HAVE_ACTION_THREAD
[9a4949]285 //!> internal flag to tell whether run_thread is still running
286 bool run_thread_running;
287
[23b6cf]288 //!> internal thread to call Actions
289 boost::thread run_thread;
290#endif
[628577]291};
[8859b5]292namespace Queuedetail {
293 template <> inline const Action* lastChanged<Action>() { return ActionQueue::_lastchangedaction; }
294}
[628577]295
296};
297
298#endif /* ACTIONQUEUE_HPP_ */
Note: See TracBrowser for help on using the repository browser.