source: src/Actions/Action.hpp@ fae462

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since fae462 was 26b4eb4, checked in by Frederik Heber <heber@…>, 11 years ago

Added observable ActionStatusList to ActionQueue.

  • this allows to fetch Status messages from Actions at a central place.
  • Action::pushStatus() as befriended proxy to ActionQueue::pushStatus() added.
  • equipped ActionStatusList with a thread lock to protect access.
  • Property mode set to 100644
File size: 10.9 KB
Line 
1/*
2 * Action.hpp
3 *
4 * Created on: Dec 8, 2009
5 * Author: crueger
6 */
7
8#ifndef ACTION_HPP_
9#define ACTION_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include <iosfwd>
17#include <string>
18
19#include <boost/preprocessor/list/adt.hpp>
20
21/** Used in .def files in paramdefaults define to set that no default value exists.
22 * We define NOPARAM_DEFAULT here, as it is used in .def files and needs to be present
23 * before these are included.
24 */
25#define NOPARAM_DEFAULT BOOST_PP_NIL
26
27/** Nicely visible short-hand for push a status message
28 *
29 */
30#ifndef STATUS
31#define STATUS(msg) pushStatus(msg)
32#endif
33
34// forward declaration
35template <typename T> class Registry;
36
37namespace MoleCuilder {
38 class ActionHistory;
39 class ActionQueue;
40 class ActionRegistry;
41 class ActionSequence;
42}
43class ActionSequenceTest;
44class Dialog;
45
46#include "Actions/ActionParameters.hpp"
47#include "Actions/ActionState.hpp"
48#include "Actions/ActionTrait.hpp"
49
50
51namespace MoleCuilder {
52
53/** Actions are Command patterns to allow for undoing and redoing.
54 *
55 * Each specific Action derives from this class to implement a certain functionality.
56 *
57 * Actions describe something that has to be done.
58 * Actions can be passed around, stored, performed and undone (Command-Pattern:
59 * http://en.wikipedia.org/wiki/Command_pattern).
60 *
61 * Unique to each Action is its ActionTrait, i.e. the options it requires
62 * to perform a certain function. E.g. in order to execute a "add atom" Action
63 * we need to know a position and an element. These options have certain
64 * properties, see \ref OptionTrait and \ref ActionTrait wherein these are stored.
65 * Essentially, each option is stored as an \ref OptionTrait instance and
66 * contains the token, default value, a description, the type, ...
67 *
68 * ActionTrait itself is also an OptionTrait because the command token may actually
69 * coincide with an option-token. E.g. this allows "...--add-atom 3" to mean
70 * both execute the action under token "add-atom" and that the option "add-atom"
71 * (the new atom's \ref element number) should contain 3.
72 *
73 * \ref ActionTrait contains a map of all associated options. With this in the cstor
74 * we register not only the Action with the \ref ActionRegistry but also each of
75 * its \link options OptionTrait \endlink with the \ref OptionRegistry.
76 *
77 * The token of the option is unique, but two Action's may share the same token if:
78 * -# they have the same default value
79 * -# they have the same type
80 *
81 * This requirement is easy because if you need to store some option of another
82 * type, simply think of a new suitable name for it.
83 *
84 * The actual value, i.e. "3" in the "add-atom" example, is taken from the
85 * ValueStorage, see \ref Dialog for how this is possible.
86 *
87 * \note There is a unit test that checks on the consistency of all registered
88 * options, also in "--enable-debug"-mode assertions will check that an option
89 * has not been registered before under another type.
90 *
91 */
92class Action
93{
94 //!> grant ActionQueue access to undo() and redo()
95 friend class ActionHistory;
96 //!> grant ActionQueue access to call()
97 friend class ActionQueue;
98 //!> grant ActionRegistry access to cstors (for ActionRegistry::fillRegistry())
99 friend class ActionRegistry;
100 //!> grant ActionSequence access to Action's private stuff
101 friend class ActionSequence;
102 //!> grant all Registry templates access to cstor and dstor (for Registry<T>::cleanup())
103 template <typename T> friend class ::Registry;
104 //!> TextMenu needs to instantiate some specific Actions, grant access to cstor
105 friend class TextMenu;
106
107 // some unit tests on Actions
108 friend class ::ActionSequenceTest;
109public:
110
111 enum QueryOptions {Interactive, NonInteractive};
112
113protected:
114 /**
115 * Standard constructor of Action Base class
116 *
117 * All Actions need to have a name. The second flag indicates, whether the action should
118 * be registered with the ActionRegistry. If the Action is registered the name of the
119 * Action needs to be unique for all Actions that are registered.
120 *
121 * \note NO reference for \a _Traits as we do have to copy it, otherwise _Traits would have
122 * to be present throughout the program's run.
123 *
124 * \param Traits information class to this action
125 */
126 Action(const ActionTrait &_Traits);
127 virtual ~Action();
128
129 /**
130 * This method is used to call an action. The basic operations for the Action
131 * are carried out and if necessary/possible the Action is added to the History
132 * to allow for undo of this action.
133 *
134 * If the call needs to undone you have to use the History, to avoid destroying
135 * invariants used by the History.
136 *
137 * Note that this call can be Interactive (i.e. a dialog will ask the user for
138 * necessary information) and NonInteractive (i.e. the information will have to
139 * be present already within the ValueStorage class or else a MissingArgumentException
140 * is thrown)
141 */
142 void call();
143
144public:
145 /**
146 * This method provides a flag that indicates if an undo mechanism is implemented
147 * for this Action. If this is true, and this action was called last, you can
148 * use the History to undo this action.
149 */
150 virtual bool canUndo()=0;
151
152 /**
153 * This method provides a flag, that indicates if the Action changes the state of
154 * the application in a way that needs to be undone for the History to work.
155 *
156 * If this is false the Action will not be added to the History upon calling. However
157 * Actions called before this one will still be available for undo.
158 */
159 virtual bool shouldUndo()=0;
160
161 /**
162 * Indicates whether the Action can do it's work at the moment. If this
163 * is false calling the action will result in a no-op.
164 */
165 virtual bool isActive();
166
167 /**
168 * Returns the name of the Action.
169 */
170 const std::string getName() const;
171
172 /**
173 * returns a detailed help message.
174 */
175 const std::string help() const;
176
177 /** Clones the Action.
178 *
179 */
180 virtual Action* clone(enum QueryOptions flag = Interactive) const=0;
181
182 /** Prepares the Action's parameters.
183 *
184 */
185 virtual void prepare(enum QueryOptions flag = Interactive);
186
187 /** Prints what would be necessary to add the Action from the Command Line Interface.
188 *
189 * \param ost output stream to print to
190 */
191 virtual void outputAsCLI(std::ostream &ost) const=0;
192
193 /** Prints what would be necessary to add the Action from a Python script
194 *
195 * \param ost output stream to print to
196 * \param prefix package prefix to be used
197 */
198 virtual void outputAsPython(std::ostream &ost, const std::string &prefix) const=0;
199
200 /**
201 * Traits resemble all necessary information that "surrounds" an action, such as
202 * its name (for ActionRegistry and as ref from string to instance and vice versa),
203 * which menu, which position, what parameters, their types, if it is itself a
204 * parameter and so on ...
205 *
206 * Note that is important that we do not use a reference here. We want to copy the
207 * information in the Action's constructor and have it contained herein. Hence, we
208 * also have our own copy constructor for ActionTrait. Information should be
209 * encapsulated in the Action, no more references to the outside than absolutely
210 * necessary.
211 */
212 const ActionTrait Traits;
213
214protected:
215 /** Removes the static entities Action::success and Action::failure.
216 * This is only to be called on the program's exit, i.e. in cleanUp(),
217 * as these static entities are used throughout all Actions.
218 */
219 static void removeStaticStateEntities();
220
221 /** Creates the static entities Action::success and Action::failure.
222 * This is only to be called by ActionHistory.
223 */
224 static void createStaticStateEntities();
225
226 /**
227 * This method is called by the History, when an undo is performed. It is
228 * provided with the corresponding state produced by the performCall or
229 * performRedo method and needs to provide a state that can be used for redo.
230 */
231 ActionState::ptr undo(ActionState::ptr);
232
233 /**
234 * This method is called by the History, when a redo is performed. It is
235 * provided with the corresponding state produced by the undo method and
236 * needs to produce a State that can then be used for another undo.
237 */
238 ActionState::ptr redo(ActionState::ptr);
239
240 /**
241 * This special state can be used to indicate that the Action was successful
242 * without providing a special state. Use this if your Action does not need
243 * a specialized state.
244 */
245 static ActionState::ptr success;
246
247 /**
248 * This special state can be returned, to indicate that the action could not do it's
249 * work, was aborted by the user etc. If you return this state make sure to transactionize
250 * your Actions and unroll the complete transaction before this is returned.
251 */
252 static ActionState::ptr failure;
253
254 /**
255 * This creates the dialog requesting the information needed for this action from the user
256 * via means of the user interface.
257 */
258 Dialog * createDialog();
259
260 /** Virtual function that starts the timer.
261 *
262 */
263 virtual void startTimer() const {};
264
265 /** Virtual function that ends the timer.
266 *
267 */
268 virtual void endTimer() const {};
269
270 /** Function pass-through for ActionQueue::insertAction().
271 *
272 * This pass-through is present to allow each derived Action access to private
273 * ActionQueue::insertAction() which is not possible otherwise as friendship
274 * is not inherited.
275 *
276 */
277 static void insertAction(Action *_action, enum Action::QueryOptions state);
278
279 /** Proxy function to grant all derived Actions access to
280 * ActionQueue::pushStatus().
281 *
282 * \param _msg status message to push
283 */
284 void pushStatus(const std::string& _msg);
285
286private:
287
288 /**
289 * This is called internally before the action is processed. This adds necessary queries
290 * to a given dialog to obtain parameters for the user for processing the action accordingly.
291 * The dialog will be given to the user before Action::performCall() is initiated, values
292 * are transfered via ValueStorage.
293 */
294 virtual Dialog * fillDialog(Dialog*)=0;
295
296 /**
297 * This is called internally when the call is being done. Implement this method to do the actual
298 * work of the Action. Implement this in your Derived classes. Needs to return a state that can be
299 * used to undo the action.
300 */
301 virtual ActionState::ptr performCall()=0;
302
303 /**
304 * This is called internally when the undo process is chosen. This Method should use the state
305 * produced by the performCall method to return the state of the application to the state
306 * it had before the Action.
307 */
308 virtual ActionState::ptr performUndo(ActionState::ptr)=0;
309
310 /**
311 * This is called internally when the redo process is chosen. This method shoudl use the state
312 * produced by the performUndo method to return the application to the state it should have after
313 * the action.
314 *
315 * Often this method can be implement to re-use the performCall method. However if user interaction
316 * or further parameters are needed, those should be taken from the state and not query the user
317 * again.
318 */
319 virtual ActionState::ptr performRedo(ActionState::ptr)=0;
320};
321
322}
323
324#endif /* ACTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.