source: src/Actions/Action.hpp@ d93d2c

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 d93d2c was 10aee4, checked in by Frederik Heber <heber@…>, 9 years ago

Cleaned up ActionQueue's interface: Actions are always cloned.

  • Action's dstor needs to be public as we have a clone() function.
  • ActionRegistrys' (and AQ's) getActionByName now returns const ref. We must not return a ptr as it may not get deleted elsewhere. We are handing out prototypes.
  • queueAction(action*,...) is private to prevent leakage, queueAction(string, ...) is the public interface.
  • some other small functions are now private, too.
  • MakroActions now need to clone() the prototype on prepare() and delete them on unprepare().
  • ActionSequence deletes contained actions.
  • FIX: ActionSequenceUnitTest cannot check on not-called property of removed actions anymore as these are gone now (they are deleted on removal and they are cloned on insertion).
  • DOCU: Updated documentation on Actions.
  • Property mode set to 100644
File size: 11.3 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
113 /** Destructor for class Action.
114 *
115 * Needs to be public as clone() is a public function.
116 *
117 */
118 virtual ~Action();
119
120protected:
121 /**
122 * Standard constructor of Action Base class
123 *
124 * All Actions need to have a name. The second flag indicates, whether the action should
125 * be registered with the ActionRegistry. If the Action is registered the name of the
126 * Action needs to be unique for all Actions that are registered.
127 *
128 * \note NO reference for \a _Traits as we do have to copy it, otherwise _Traits would have
129 * to be present throughout the program's run.
130 *
131 * \param Traits information class to this action
132 */
133 Action(const ActionTrait &_Traits);
134
135 /**
136 * This method is used to call an action. The basic operations for the Action
137 * are carried out and if necessary/possible the Action is added to the History
138 * to allow for undo of this action.
139 *
140 * If the call needs to undone you have to use the History, to avoid destroying
141 * invariants used by the History.
142 *
143 * Note that this call can be Interactive (i.e. a dialog will ask the user for
144 * necessary information) and NonInteractive (i.e. the information will have to
145 * be present already within the ValueStorage class or else a MissingArgumentException
146 * is thrown)
147 */
148 void call();
149
150public:
151 /**
152 * This method provides a flag that indicates if an undo mechanism is implemented
153 * for this Action. If this is true, and this action was called last, you can
154 * use the History to undo this action.
155 */
156 virtual bool canUndo()=0;
157
158 /**
159 * This method provides a flag, that indicates if the Action changes the state of
160 * the application in a way that needs to be undone for the History to work.
161 *
162 * If this is false the Action will not be added to the History upon calling. However
163 * Actions called before this one will still be available for undo.
164 */
165 virtual bool shouldUndo()=0;
166
167 /**
168 * Indicates whether the Action can do it's work at the moment. If this
169 * is false calling the action will result in a no-op.
170 */
171 virtual bool isActive() const;
172
173 /**
174 * Returns the name of the Action.
175 */
176 const std::string getName() const;
177
178 /**
179 * returns a detailed help message.
180 */
181 const std::string help() const;
182
183 /** Clones the Action.
184 *
185 */
186 virtual Action* clone(enum QueryOptions flag = Interactive) const=0;
187
188 /** Prepares the Action's parameters.
189 *
190 */
191 virtual void prepare(enum QueryOptions flag = Interactive);
192
193 /** Prints what would be necessary to add the Action from the Command Line Interface.
194 *
195 * \param ost output stream to print to
196 */
197 virtual void outputAsCLI(std::ostream &ost) const=0;
198
199 /** Prints what would be necessary to add the Action from a Python script
200 *
201 * \param ost output stream to print to
202 * \param prefix package prefix to be used
203 */
204 virtual void outputAsPython(std::ostream &ost, const std::string &prefix) const=0;
205
206 /** Sets the option defined by \a _token to \a _value for this action.
207 *
208 * This is needed when constructing MakroActions.
209 *
210 * \param _token token of the option
211 * \param _value new value
212 */
213 virtual void setOptionValue(const std::string &_token, const std::string &_value)=0;
214
215 /**
216 * Traits resemble all necessary information that "surrounds" an action, such as
217 * its name (for ActionRegistry and as ref from string to instance and vice versa),
218 * which menu, which position, what parameters, their types, if it is itself a
219 * parameter and so on ...
220 *
221 * Note that is important that we do not use a reference here. We want to copy the
222 * information in the Action's constructor and have it contained herein. Hence, we
223 * also have our own copy constructor for ActionTrait. Information should be
224 * encapsulated in the Action, no more references to the outside than absolutely
225 * necessary.
226 */
227 const ActionTrait Traits;
228
229protected:
230 /** Removes the static entities Action::success and Action::failure.
231 * This is only to be called on the program's exit, i.e. in cleanUp(),
232 * as these static entities are used throughout all Actions.
233 */
234 static void removeStaticStateEntities();
235
236 /** Creates the static entities Action::success and Action::failure.
237 * This is only to be called by ActionHistory.
238 */
239 static void createStaticStateEntities();
240
241 /**
242 * This method is called by the History, when an undo is performed. It is
243 * provided with the corresponding state produced by the performCall or
244 * performRedo method and needs to provide a state that can be used for redo.
245 */
246 ActionState::ptr undo(ActionState::ptr);
247
248 /**
249 * This method is called by the History, when a redo is performed. It is
250 * provided with the corresponding state produced by the undo method and
251 * needs to produce a State that can then be used for another undo.
252 */
253 ActionState::ptr redo(ActionState::ptr);
254
255 /**
256 * This special state can be used to indicate that the Action was successful
257 * without providing a special state. Use this if your Action does not need
258 * a specialized state.
259 */
260 static ActionState::ptr success;
261
262 /**
263 * This special state can be returned, to indicate that the action could not do it's
264 * work, was aborted by the user etc. If you return this state make sure to transactionize
265 * your Actions and unroll the complete transaction before this is returned.
266 */
267 static ActionState::ptr failure;
268
269 /**
270 * This creates the dialog requesting the information needed for this action from the user
271 * via means of the user interface.
272 */
273 Dialog * createDialog();
274
275 /** Virtual function that starts the timer.
276 *
277 */
278 virtual void startTimer() const {};
279
280 /** Virtual function that ends the timer.
281 *
282 */
283 virtual void endTimer() const {};
284
285 /** Function pass-through for ActionQueue::insertAction().
286 *
287 * This pass-through is present to allow each derived Action access to private
288 * ActionQueue::insertAction() which is not possible otherwise as friendship
289 * is not inherited.
290 *
291 */
292 static void insertAction(Action *_action, enum Action::QueryOptions state);
293
294 /** Proxy function to grant all derived Actions access to
295 * ActionQueue::pushStatus().
296 *
297 * \param _msg status message to push
298 */
299 void pushStatus(const std::string& _msg);
300
301private:
302
303 /**
304 * This is called internally before the action is processed. This adds necessary queries
305 * to a given dialog to obtain parameters for the user for processing the action accordingly.
306 * The dialog will be given to the user before Action::performCall() is initiated, values
307 * are transfered via ValueStorage.
308 */
309 virtual Dialog * fillDialog(Dialog*)=0;
310
311 /**
312 * This is called internally when the call is being done. Implement this method to do the actual
313 * work of the Action. Implement this in your Derived classes. Needs to return a state that can be
314 * used to undo the action.
315 */
316 virtual ActionState::ptr performCall()=0;
317
318 /**
319 * This is called internally when the undo process is chosen. This Method should use the state
320 * produced by the performCall method to return the state of the application to the state
321 * it had before the Action.
322 */
323 virtual ActionState::ptr performUndo(ActionState::ptr)=0;
324
325 /**
326 * This is called internally when the redo process is chosen. This method shoudl use the state
327 * produced by the performUndo method to return the application to the state it should have after
328 * the action.
329 *
330 * Often this method can be implement to re-use the performCall method. However if user interaction
331 * or further parameters are needed, those should be taken from the state and not query the user
332 * again.
333 */
334 virtual ActionState::ptr performRedo(ActionState::ptr)=0;
335};
336
337}
338
339#endif /* ACTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.