source: src/Actions/Action.hpp@ 725a1d

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 725a1d was a82f61, checked in by Frederik Heber <heber@…>, 10 years ago

Added Action::setOptionValue() which allows setting the option via a string.

  • this is preparatory for allowing the creation of MakroActions inside the code. We need to set the options without going through dialogs in some way or another and without being completely inside the Actions as is the case for the COMMAND variants and the python function calls.
  • Property mode set to 100644
File size: 11.2 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 /** Sets the option defined by \a _token to \a _value for this action.
201 *
202 * This is needed when constructing MakroActions.
203 *
204 * \param _token token of the option
205 * \param _value new value
206 */
207 virtual void setOptionValue(const std::string &_token, const std::string &_value)=0;
208
209 /**
210 * Traits resemble all necessary information that "surrounds" an action, such as
211 * its name (for ActionRegistry and as ref from string to instance and vice versa),
212 * which menu, which position, what parameters, their types, if it is itself a
213 * parameter and so on ...
214 *
215 * Note that is important that we do not use a reference here. We want to copy the
216 * information in the Action's constructor and have it contained herein. Hence, we
217 * also have our own copy constructor for ActionTrait. Information should be
218 * encapsulated in the Action, no more references to the outside than absolutely
219 * necessary.
220 */
221 const ActionTrait Traits;
222
223protected:
224 /** Removes the static entities Action::success and Action::failure.
225 * This is only to be called on the program's exit, i.e. in cleanUp(),
226 * as these static entities are used throughout all Actions.
227 */
228 static void removeStaticStateEntities();
229
230 /** Creates the static entities Action::success and Action::failure.
231 * This is only to be called by ActionHistory.
232 */
233 static void createStaticStateEntities();
234
235 /**
236 * This method is called by the History, when an undo is performed. It is
237 * provided with the corresponding state produced by the performCall or
238 * performRedo method and needs to provide a state that can be used for redo.
239 */
240 ActionState::ptr undo(ActionState::ptr);
241
242 /**
243 * This method is called by the History, when a redo is performed. It is
244 * provided with the corresponding state produced by the undo method and
245 * needs to produce a State that can then be used for another undo.
246 */
247 ActionState::ptr redo(ActionState::ptr);
248
249 /**
250 * This special state can be used to indicate that the Action was successful
251 * without providing a special state. Use this if your Action does not need
252 * a specialized state.
253 */
254 static ActionState::ptr success;
255
256 /**
257 * This special state can be returned, to indicate that the action could not do it's
258 * work, was aborted by the user etc. If you return this state make sure to transactionize
259 * your Actions and unroll the complete transaction before this is returned.
260 */
261 static ActionState::ptr failure;
262
263 /**
264 * This creates the dialog requesting the information needed for this action from the user
265 * via means of the user interface.
266 */
267 Dialog * createDialog();
268
269 /** Virtual function that starts the timer.
270 *
271 */
272 virtual void startTimer() const {};
273
274 /** Virtual function that ends the timer.
275 *
276 */
277 virtual void endTimer() const {};
278
279 /** Function pass-through for ActionQueue::insertAction().
280 *
281 * This pass-through is present to allow each derived Action access to private
282 * ActionQueue::insertAction() which is not possible otherwise as friendship
283 * is not inherited.
284 *
285 */
286 static void insertAction(Action *_action, enum Action::QueryOptions state);
287
288 /** Proxy function to grant all derived Actions access to
289 * ActionQueue::pushStatus().
290 *
291 * \param _msg status message to push
292 */
293 void pushStatus(const std::string& _msg);
294
295private:
296
297 /**
298 * This is called internally before the action is processed. This adds necessary queries
299 * to a given dialog to obtain parameters for the user for processing the action accordingly.
300 * The dialog will be given to the user before Action::performCall() is initiated, values
301 * are transfered via ValueStorage.
302 */
303 virtual Dialog * fillDialog(Dialog*)=0;
304
305 /**
306 * This is called internally when the call is being done. Implement this method to do the actual
307 * work of the Action. Implement this in your Derived classes. Needs to return a state that can be
308 * used to undo the action.
309 */
310 virtual ActionState::ptr performCall()=0;
311
312 /**
313 * This is called internally when the undo process is chosen. This Method should use the state
314 * produced by the performCall method to return the state of the application to the state
315 * it had before the Action.
316 */
317 virtual ActionState::ptr performUndo(ActionState::ptr)=0;
318
319 /**
320 * This is called internally when the redo process is chosen. This method shoudl use the state
321 * produced by the performUndo method to return the application to the state it should have after
322 * the action.
323 *
324 * Often this method can be implement to re-use the performCall method. However if user interaction
325 * or further parameters are needed, those should be taken from the state and not query the user
326 * again.
327 */
328 virtual ActionState::ptr performRedo(ActionState::ptr)=0;
329};
330
331}
332
333#endif /* ACTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.