/* * ActionQueue.hpp * * Created on: Aug 16, 2013 * Author: heber */ #ifndef ACTIONQUEUE_HPP_ #define ACTIONQUEUE_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/Singleton.hpp" #ifdef HAVE_ACTION_THREAD #include #endif #include #include "Actions/Action.hpp" #include "Actions/ActionState.hpp" #ifdef HAVE_ACTION_THREAD void stopQueue(); void waitQueue(); #endif namespace MoleCuilder { class ActionHistory; class ActionRegistry; class ActionTrait; /** This class combines the whole handling of Actions into a single class. * * It spawns new Actions by its internal ActionRegistry. Spawned Actions are * automatically queued and placed into a History after execution. */ class ActionQueue : public Singleton { friend class Singleton; public: typedef std::vector ActionTokens_t; typedef std::vector< Action * > ActionQueue_t; /** Queues the Action with \a name to be called. * * \param name token of Action to actionqueue * \param state whether Actions needs to be filled via a Dialog or not */ void queueAction(const std::string &name, enum Action::QueryOptions state = Action::Interactive); /** Queues the Action with \a name to be called. * * \param _action action to add * \param state whether Actions needs to be filled via a Dialog or not */ void queueAction(Action *_action, enum Action::QueryOptions state = Action::Interactive); /** Returns the spawned action by token \a name. * * Action is checked into internal actionqueue. * * \return pointer to newly spawned action */ Action* getActionByName(const std::string &name); /** Checks whether the Action is known by the given \a name. * * \param name token of action to check * \return true - token is known, false - else */ bool isActionKnownByName(const std::string &name) const; /** Register an Action with the ActionRegistry. * * \param _action action to add */ void registerAction(Action *_action); /** Returns the vector with the tokens of all currently known Actions. * * \return list of all tokens */ const ActionTokens_t getListOfActions() const; /** Returns the trait to an Action. * * \param name name of Action * \return const ref to its default Trait. */ const ActionTrait& getActionsTrait(const std::string &name) const; /** Print the current contents of the actionqueue as CLI instantiated list of Actions. * * This is useful for storing the current session. * * \param output output stream to print to */ void outputAsCLI(std::ostream &output) const; /** Print the current contents of the actionqueue as Python instantiated list of Actions. * * This is useful for storing the current session. * * \param output output stream to print to */ void outputAsPython(std::ostream &output) const; /** Undoes last called Acfriend void ::cleanUp();tion. * */ void undoLast(); /** Redoes last undone Action. * */ void redoLast(); #ifdef HAVE_ACTION_THREAD boost::thread &getRunThread() { return run_thread; } #endif private: //!> grant Action access to internal history functions. friend class Action; /** Wrapper function to add state to ActionHistory. * * \param _Action Action whose state to add * \param _state state to add */ void addElement(Action* _Action, ActionState::ptr _state); /** Wrapper function to clear ActionHistory. * */ void clear(); #ifdef HAVE_ACTION_THREAD /** Runs the ActionQueue. * */ void run(); friend void ::stopQueue(); /** Stops the internal thread. * */ void stop(); friend void ::waitQueue(); /** Wait till all currently queued actions are processed. * */ void wait(); #endif /** Insert an action after CurrentAction. * * This is implemented only to allow action's COMMAND to work. If we * were to use queueAction, actions would come after all other already * present actions. */ void insertAction(Action *_action, enum Action::QueryOptions state); /** Moves all action from tempqueue into real queue. * */ void insertTempQueue(); private: /** Private cstor for ActionQueue. * * Must be private as is singleton. * */ ActionQueue(); /** Dstor for ActionQueue. * */ ~ActionQueue(); //!> ActionRegistry to spawn new actions ActionRegistry *AR; //!> ActionHistory is for undoing and redoing actions, requires ActionRegistry fully initialized ActionHistory *history; //!> internal actionqueue of actions ActionQueue_t actionqueue; //!> point to current action in actionqueue size_t CurrentAction; //!> internal temporary actionqueue of actions used by insertAction() ActionQueue_t tempqueue; #ifdef HAVE_ACTION_THREAD //!> internal thread to call Actions boost::thread run_thread; //!> internal mutex to synchronize access to queue boost::mutex mtx_queue; //!> conditional variable notifying when run_thread is idling boost::condition_variable cond_idle; //!> flag indicating whether run_thread is idle or not bool run_thread_isIdle; //!> internal mutex to synchronize access to run_thread_isIdle boost::mutex mtx_idle; #endif }; }; #endif /* ACTIONQUEUE_HPP_ */