source: src/Actions/Action.hpp@ c38826

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 c38826 was e4afb4, checked in by Frederik Heber <heber@…>, 14 years ago

Huge refactoring: Introduction of Traits to Actions.

This change is really big but the introduction of the Trait concept (at least
in its current light form) is so fundamental that lots of pieces had to be
changed in order to get everything working.

The main point why it was necessary to add these traits in the first place was
to comfortably allow for adding extension of Actions information-wise, i.e.
with stuff that is only important for the QtUI, such as icons, or tooltips, ...
This extra information should not be stored with Action itself, as it has
nothing to do with the workings of the Action. And neither should it get
stored with some blown-out-of-proportions MapOfActions class ...

The gist of the change is as follows:

  • OptionTrait contains the token, description, shortform and type of an option, such as ("position", "position in space, none, typeid(Vector)).
  • ActionTrait is the derived form for actions where additionally MenuPosition and MenuName are stored (and probably more to come for the GUI), also we have a set of OptionTrait instances, one for each option of the Action.
  • Action then contains this ActionTrait, specialized for each Action.
  • the preprocessor macros have been enhanced to gather all this information from the .def files.
  • MapOfActions is gone. Completely. Most of its use was to store this extra information and the ValueStorage part now is just in class ValueStorage.
  • ValueStorage is no more an interface to MapOfActions but as the name says a (type-safe) ValueStorage.

Listing the (remaining) changes in alphabetical order of the class:

  • Action
    • member value ::name dropped, ::getName() uses ActionTraits::getName()
    • new define NODEFAULT which is used in paramdefaults in .def files
    • all derived actions classes such as Process, Calculations, MakroAction,... have been adapated to use the ActionTrait concept as well.
  • ActionHistory
    • extraced RedoAction and UndoAction, shifted implementation into their own object files and they use .def files as well (i.e. streamlined with method used for other actions)
  • MenuDescription
    • contain information on Menus such as name, ...
    • new unit test checks for consistency
  • molecule
    • const member functions: Copy(), Output() and OutputBonds()
  • OptionRegistry
    • new registry class for options only
    • we want the same type throughout the code for each token, e.g. "position"
    • the registry containts checks for consistency
  • OptionTrait
    • default values are specified in paramdefaults, none are given by NODEFAULT
    • introduced default for translate-atoms, point-correlation, pair-correlation
  • Registry pattern
    • new unit test, but only sceleton code so far
  • ...Query, also ...Pipe
    • atoms, molecule and elements are now all const
    • also ValueStorage's signatures all have const therein
  • ValueStorage
    • set/queryCurrentValue from MapOfActions
    • at times VectorValue has been in .def files where Vector was in the signature. This is cleared. Such stuff is only present for e.g. BoxVector being queried as a Vector. But this is a feature and intended.
  • World
    • most of the (un)selection functions now work on const atoms and molecules
    • in one case we need a const_cast to remove this, but this is intentional, as the vector of selected atoms stores non-const pointers and this is ok.

There is only one test which had to be changed slightly because a specific
option token as "position" must now have the same type everywhere, e.g. always
Vector.

  • TESTFIX: Simple_configuration/2: --position -> --domain-position (and associated to BoxVector)
  • Property mode set to 100644
File size: 24.5 KB
Line 
1/*
2 * Action.h
3 *
4 * Created on: Dec 8, 2009
5 * Author: crueger
6 */
7
8#ifndef ACTION_H_
9#define ACTION_H_
10
11#include <string>
12#include <boost/shared_ptr.hpp>
13
14/** Used in .def files in paramdefaults define to set that no default value exists.
15 * We define NODEFAULT here, as it is used in .def files and needs to be present
16 * before these are included.
17 */
18#define NODEFAULT std::string()
19
20// forward declaration
21
22class ActionState;
23class ActionSequence;
24class Dialog;
25
26#include "Actions/ActionTraits.hpp"
27
28/**
29 * @file
30 * <H1> Action Howto </H1>
31 *
32 * <H2> Introduction </H2>
33 *
34 * Actions are used in object oriented design as a replacement for callback functions.
35 * In most ways Actions can be used in the same way that callbacks were used in non
36 * OO-Systems, but can contain support for several extra mechanism such as undo/redo
37 * or progress indicators.
38 *
39 * The main purpose of an action class is to contain small procedures, that can be repeatedly
40 * called. These procedures can also be stored, passed around, so that the execution of an
41 * action can happen quite far away from the place of creation. For a detailed description of
42 * the Action pattern see GOF:1996.
43 *
44 * <H3> How to use an action </H3>
45 *
46 * The process of using an action is as easy as calling the call() method of the action. The
47 * action will then do whatever it is supposed to do. If it is an action that can be undone, it
48 * will also register itself in the history to make itself available for undo. To undo the last
49 * action, you can either use the undoLast() method inside the ActionHistory class or call the
50 * UndoAction also provided by the ActionHistory. If an action was undone it will be available for
51 * redo, using the redoLast() method of the ActionHistory or the RedoAction also provided by this
52 * class. To check whether undo/redo is available at any moment you can use the hasUndo() or
53 * hasRedo() method respectively.
54 *
55 * Note that an Action always has two functions createDialog() and performCall(). The former
56 * returns a Dialog filled with query...() functions for all information that we need from the
57 * user. The latter must not contain any interaction but just uses these values (which are
58 * temporarily stored by class ValueStorage) to perform the Action.
59 *
60 * Furthermore, there is a global action function that makes the action callable with already
61 * present parameters (i.e. without user interaction and for internal use within the code only).
62 * This function is basically just a macro, that puts the parameters into the ValueStorage and
63 * calls Action::call(Action::NonInteractive).
64 *
65 * Actions can be set to be active or inactive. If an action is set to inactive it is signaling, that
66 * some condition necessary for this action to be executed is not currently met. For example the
67 * UndoAction will set itself to inactive, when there is no action at that time that can be undone.
68 * Using call() on an inactive Action results in a no-op. You can query the state of an action using
69 * the isActive() method.
70 *
71 * The undo capabilities of actions come in three types as signaled by two boolean flags (one
72 * combination of these flags is left empty as can be seen later).
73 * <ul>
74 * <li/> The first flag indicates if the undo mechanism for this action should be considered at all, i.e.
75 * if the state of the application changes in a way that needs to be reverted. Actions that should
76 * consider the undo mechanism are for example adding a molecule, moving atoms, changing
77 * the name of a molecule etc. Changing the View-Area on the other hand should be an action that
78 * does not consider the undo mechanism. This flag can be queried using the shouldUndo() method.
79 *
80 * <li/> The second flag indicates whether the changes can be undo for this action. If this flag is true
81 * the action will be made available for undo using the ActionHistory class and the actions of this
82 * class. If this flag is false while the shoudlUndo() flag is true this means that this action
83 * changes the state of the application changes in a way that cannot be undone, but might cause
84 * the undo of previous actions to fail. In this case the whole History is cleared, as to keep
85 * the state of the application intact by avoiding dangerous undos. This flag can be queried
86 * using the canUndo() method.
87 *</ul>
88 *
89 * Each action has a name, that can be used to identify it throughout the run of the application.
90 * This name can be retrieved using the getName() method. Most actions also register themselves with
91 * a global structure, called the ActionRegistry. Actions that register themselves need to have a
92 * unique name for the whole application. If the name is known these actions can be retrieved from
93 * the registry by their name and then be used as normal.
94 *
95 * <H2> Building your own actions </H2>
96 *
97 * Building actions is easy. Each specific ...Action is derived from the base class Action.
98 * In order to create all the reoccuring stuff, macros have been created which you can simply
99 * include and then don't need to worry about it.
100 * There are three major virtual functions: performCall(), performUndo(), performRedo() which
101 * you have to write, to equip your action with some actual capabilities.
102 * Each Action definition and implementation consists of of three files:
103 * -# cpp: contains performX() which you have to write, also some boilerplate functions which are
104 * constructed automatically when including your def and "Actions/action_impl_pre.hpp"
105 * -# hpp: boilerplate definitions created simply by including your def and
106 * "Actions/action_impl_header.hpp"
107 * -# def: macro definitions of all your parameters and additional variables needed for the state,
108 * also name and category and token of your action.
109 *
110 * Best thing to do is look at one of the already present triples and you should soon understand
111 * what you have to add:
112 * -# pick the right category, i.e. the right folder in src/Actions
113 * -# pick the right name
114 * -# decide which parameters your actions need and what the type, the variable name and the token
115 * to reference it from the command-line should be. Check whether already present and fitting
116 * tokens exists, e.g. "position" as token for a Vector representing a position.
117 * -# consider which additional information you need to undo your action
118 * -# don't forget to include your .def file followed by "action_impl_pre.hpp" in .cpp or
119 * "action_impl_header.hpp" in the .hpp
120 * -# continue to write the functionality of your action in performCall(), undo and redo in performUndo()
121 * and performRedo().
122 * -# You should indicate whether the action supports undo by implementing the shouldUndo() and
123 * canUndo() methods to return the appropriate flags.
124 *
125 * <H3> Specific notes on the macros </H3>
126 *
127 * The following functions are created by the macros, i.e. you don't need to worry about it:
128 *
129 * Any user interaction should be placed into the dialog returned by fillDialog().
130 *
131 * Also, create the global function to allow for easy calling of your function internally (i.e.
132 * without user interaction). It should have the name of the Action class without the suffix Action.
133 *
134 * The constructor of your derived class also needs to call the Base constructor, passing it the
135 * name of the Action and a flag indicating whether this action should be made available in the
136 * registry. WARNING: Do not use the virtual getName() method of the derived action to provide the
137 * constructor with the name, even if you overloaded this method to return a constant. Doing this
138 * will most likely not do what you think it does (see: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5
139 * if you want to know why this wont work)
140 *
141 * <H3> Interfacing your Action with the Undo mechanism </H3>
142 *
143 * The performX() methods need to comply to a simple standard to allow for undo and redo. The first
144 * convention in this standard concerns the return type. All methods that handle calling, undoing
145 * or redoing return an object of Action::state_ptr. This is a smart pointer to a State object, that
146 * can be used to store state information that is needed by your action for later redo. A rename
147 * Action for example would need to store which object has been renamed and what the old name was.
148 * A move Action on the other hand would need to store the object that has been moved as well as the
149 * old position. If your Action does not need to store any kind of information for redo you can
150 * simply return Action::success and skip the rest of this paragraph. If your action has been
151 * abborted you can return Action::failure, which indicates to the history mechanism that this
152 * action should not be stored.
153 *
154 * If your Action needs any kind of information to undo its execution, you need to store this
155 * information in the state that is returned by the performCall() method. Since no assumptions
156 * can be made on the type or amount of information the ActionState base class is left empty.
157 * To use this class you need to derive a YourActionState class from the ActionState base class
158 * adding your data fields and accessor functions. Upon undo the ActionState object produced
159 * by the corresponding performCall() is then passed to the performUndo() method which should
160 * typecast the ActionState to the appropriate sub class, undo all the changes and produce
161 * a State object that can be used to redo the action if neccessary. This new state object is
162 * then used if the redo mechanism is invoked and passed to the performRedo() function, which
163 * again produces a State that can be used for performUndo().
164 *
165 * <H3> Outline of the implementation of Actions </H3>
166 *
167 * To sum up the actions necessary to build actions here is a brief outline of things methioned
168 * in the last paragraphs:
169 *
170 * <H4> Basics </H4>
171 *
172 * <ul>
173 * <li/> create parameter tupels (type, token, reference), put into def. Access them later in
174 * the performX() via the structure params.###.
175 * <li/> think of name, category and token for your action, put into def
176 * <li/> create additional state variables tupels (type, reference) for storing extra information
177 * that you need for undo/redo in the ActionState. You can always access the parameters
178 * of your Action by state.params.### (i.e. they are copied to the state by default).
179 * <li/> implement performCall(), first line should be calling of getParametersfromValueStorage().
180 * <li/> performUndo(), performRedo()
181 * <li/> implement the functions that return the flags for the undo mechanism, i.e. true/false.
182 * </ul>
183 *
184 * <H4> Implementing performX() methods </H4>
185 *
186 * <ul>
187 * <li/> performCall():
188 * <ul>
189 * <li/> first line should be calling of getParametersfromValueStorage().
190 * <li/> Access your parameters by the structure params.### (where ### stands for the reference/
191 * variable name chosen in the tupel).
192 * <li/> do whatever is needed to make the action work
193 * <li/> if the action was abborted return Action::failure
194 * <li/> if the action needs to save a state return a custom state object
195 * <li/> otherwise return Action::success
196 * </ul>
197 * <li/> performUndo():
198 * <ul>
199 * <li/> typecast the ActionState pointer to a Pointer to YourActionState if necessary
200 * <li/> undo the action using the extra information and the Action's parameters in the state
201 * <li/> produce a new state that can be used for redoing and return it
202 * </ul>
203 * <li/> performRedo():
204 * <ul>
205 * <li/> take the ActionState produced by performUndo and typecast it to a pointer to YourActionState if necessary
206 * <li/> redo the undone action using the extra information and the Action's parameters in the state
207 * <li/> produce a new state that can be used by performUndo() and return it
208 * </ul>
209 * </ul>
210 *
211 * <H2> Advanced techniques </H2>
212 *
213 * <H3> Predefined Actions </H3>
214 *
215 * To make construction of actions easy there are some predefined actions. Namely these are
216 * the MethodAction and the ErrorAction.
217 *
218 * The method action can be used to turn any function with empty arguments and return type void
219 * into an action (also works for functors with those types). Simply pass the constructor for the
220 * MethodAction a name to use for this action, the function to call inside the performCall()
221 * method and a flag indicating if this action should be made retrievable inside the registry
222 * (default is true). MethodActions always report themselves as changing the state of the
223 * application but cannot be undone. i.e. calling MethodActions will always cause the ActionHistory
224 * to be cleared.
225 *
226 * ErrorActions can be used to produce a short message using the Log() << Verbose() mechanism of
227 * the molecuilder. Simply pass the constructor a name for the action, the message to show upon
228 * calling this action and the flag for the registry (default is again true). Error action
229 * report that they do not change the state of the application and are therefore not considered
230 * for undo.
231 *
232 * <H3> Sequences of Actions and MakroActions </H3>
233 *
234 * <H4> Building sequences of Actions </H4>
235 *
236 * Actions can be chained to sequences using the ActionSequence class. Once an ActionSequence is
237 * constructed it will be initially empty. Any Actions can then be added to the sequence using the
238 * addAction() method of the ActionSequence class. The last added action can be removed using the
239 * removeLastAction() method. If the construction of the sequence is done, you can use the
240 * callAll() method. Each action called this way will register itself with the History to allow
241 * separate undo of all actions in the sequence.
242 *
243 * <H4> Building larger Actions from simple ones </H4>
244 *
245 * Using the pre-defined class MakroAction it is possible to construct bigger actions from a sequence
246 * of smaller ones. For this you first have to build a sequence of the actions using the ActionSequence
247 * as described above. Then you can construct a MakroAction passing it a name, the sequence to use
248 * and as usual a flag for the registry. You can then simply call the complete action-sequence through
249 * this makro action using the normal interface. Other than with the direct use of the action sequence
250 * only the complete MakroAction is registered inside the history, i.e. the complete sequence can be
251 * undone at once. Also there are a few caveats you have to take care of when using the MakroAction:
252 * <ul>
253 * <li/> All Actions as well as the sequence should exclusively belong to the MakroAction. This
254 * especially means, that the destruction of these objects should be handled by the MakroAction.
255 * <li/> none of the Actions inside the MakroAction should be registered with the registry, since the
256 * registry also assumes sole ownership of the actions.
257 * <li/> Do not remove or add actions from the sequence once the MakroAction has been constructed, since this
258 * might brake important assumptions for the undo/redo mechanism
259 * </ul>
260 *
261 * <H3> Special kinds of Actions </H3>
262 *
263 * To make the usage of Actions more versatile there are two special kinds of actions defined,
264 * that contain special mechanisms. These are defined inside the class Process, for actions that
265 * take some time and indicate their own progress, and in the class Calculations for actions that
266 * have a retrievable result.
267 *
268 * <H4> Processes </H4>
269 *
270 * Processes are Actions that might take some time and therefore contain special mechanisms
271 * to indicate their progress to the user. If you want to implement a process you can follow the
272 * guidelines for implementing actions. In addition to the normal Action constructor parameters,
273 * you also need to define the number of steps the process takes to finish (use 0 if that number is
274 * not known upon construction). At the beginning of your process you then simply call start() to
275 * indicate that the process is taking up its work. You might also want to set the number of steps it
276 * needs to finish, if it has changed since the last invocation/construction. You can use the
277 * setMaxSteps() method for this. Then after each finished step of calulation simply call step(),
278 * to let the indicators know that it should update itself. If the number of steps is not known
279 * at the time of calculation, you should make sure the maxSteps field is set to 0, either through
280 * the constructor or by using setMaxSteps(0). Indicators are required to handle both processes that
281 * know the number of steps needed as well as processes that cannot predict when they will be finished.
282 * Once your calculation is done call stop() to let every indicator know that the process is done with
283 * the work and to let the user know.
284 *
285 * Indicators that want to know about processes need to implement the Observer class with all the
286 * methods defined there. They can then globally sign on to all processes using the static
287 * Process::AddObserver() method and remove themselves using the Process::RemoveObserver()
288 * methods. When a process starts it will take care that the notification for this process
289 * is invoked at the right time. Indicators should not try to observe a single process, but rather
290 * be ready to observe the status of any kind of process using the methods described here.
291 *
292 * <H4> Calculations </H4>
293 *
294 * Calculations are special Actions that also return a result when called. Calculations are
295 * always derived from Process, so that the progress of a calculation can be shown. Also
296 * Calculations should not contain side-effects and not consider the undo mechanism.
297 * When a Calculation is called using the Action mechanism this will cause it to calculate
298 * the result and make it available using the getResult() method. Another way to have a Calculation
299 * produce a result is by using the function-call operator. When this operator is used, the Calculation
300 * will try to return a previously calculated and cached result and only do any actuall calculations
301 * when no such result is available. You can delete the cached result using the reset() method.
302 */
303
304
305/**
306 * Base class for all actions.
307 *
308 * Actions describe something that has to be done.
309 * Actions can be passed around, stored, performed and undone (Command-Pattern).
310 */
311class Action
312{
313friend class ActionSequence;
314friend class ActionHistory;
315public:
316
317 enum QueryOptions {Interactive, NonInteractive};
318
319 /**
320 * This type is used to store pointers to ActionStates while allowing multiple ownership
321 */
322 typedef boost::shared_ptr<ActionState> state_ptr;
323
324 /**
325 * Standard constructor of Action Base class
326 *
327 * All Actions need to have a name. The second flag indicates, whether the action should
328 * be registered with the ActionRegistry. If the Action is registered the name of the
329 * Action needs to be unique for all Actions that are registered.
330 *
331 * \note NO reference for \a _Traits as we do have to copy it, otherwise _Traits would have
332 * to be present throughout the program's run.
333 *
334 * \param Traits information class to this action
335 * \param _doRegister whether to register with ActionRegistry
336 */
337 Action(const ActionTraits &_Traits, bool _doRegister=true);
338 virtual ~Action();
339
340 /**
341 * This method is used to call an action. The basic operations for the Action
342 * are carried out and if necessary/possible the Action is added to the History
343 * to allow for undo of this action.
344 *
345 * If the call needs to undone you have to use the History, to avoid destroying
346 * invariants used by the History.
347 *
348 * Note that this call can be Interactive (i.e. a dialog will ask the user for
349 * necessary information) and NonInteractive (i.e. the information will have to
350 * be present already within the ValueStorage class or else a MissingArgumentException
351 * is thrown)
352 */
353 void call(enum QueryOptions state = Interactive);
354
355 /**
356 * This method provides a flag that indicates if an undo mechanism is implemented
357 * for this Action. If this is true, and this action was called last, you can
358 * use the History to undo this action.
359 */
360 virtual bool canUndo()=0;
361
362 /**
363 * This method provides a flag, that indicates if the Action changes the state of
364 * the application in a way that needs to be undone for the History to work.
365 *
366 * If this is false the Action will not be added to the History upon calling. However
367 * Actions called before this one will still be available for undo.
368 */
369 virtual bool shouldUndo()=0;
370
371 /**
372 * Indicates whether the Action can do it's work at the moment. If this
373 * is false calling the action will result in a no-op.
374 */
375 virtual bool isActive();
376
377 /**
378 * Returns the name of the Action.
379 */
380 const std::string getName();
381
382 /**
383 * Traits resemble all necessary information that "surrounds" an action, such as
384 * its name (for ActionRegistry and as ref from string to instance and vice versa),
385 * which menu, which position, what parameters, their types, if it is itself a
386 * parameter and so on ...
387 *
388 * Note that is important that we do not use a reference here. We want to copy the
389 * information in the Action's constructor and have it contained herein. Hence, we
390 * also have our own copy constructor for ActionTraits. Information should be
391 * encapsulated in the Action, no more references to the outside than absolutely
392 * necessary.
393 */
394 const ActionTraits Traits;
395
396protected:
397 /**
398 * This method is called by the History, when an undo is performed. It is
399 * provided with the corresponding state produced by the performCall or
400 * performRedo method and needs to provide a state that can be used for redo.
401 */
402 state_ptr undo(state_ptr);
403
404 /**
405 * This method is called by the Histor, when a redo is performed. It is
406 * provided with the corresponding state produced by the undo method and
407 * needs to produce a State that can then be used for another undo.
408 */
409 state_ptr redo(state_ptr);
410
411 /**
412 * This special state can be used to indicate that the Action was successfull
413 * without providing a special state. Use this if your Action does not need
414 * a speciallized state.
415 */
416 static state_ptr success;
417
418 /**
419 * This special state can be returned, to indicate that the action could not do it's
420 * work, was abborted by the user etc. If you return this state make sure to transactionize
421 * your Actions and unroll the complete transaction before this is returned.
422 */
423 static state_ptr failure;
424
425 /**
426 * This creates the dialog requesting the information needed for this action from the user
427 * via means of the user interface.
428 */
429 Dialog * createDialog();
430
431private:
432
433 /**
434 * This is called internally before the Action::performCall(). It initializes the
435 * necessary ActionParameters by retrieving the values from ValueStorage.
436 */
437 virtual void getParametersfromValueStorage()=0;
438
439 /**
440 * This is called internally before the action is processed. This adds necessary queries
441 * to a given dialog to obtain parameters for the user for processing the action accordingly.
442 * The dialog will be given to the user before Action::performCall() is initiated, values
443 * are transfered via ValueStorage.
444 */
445 virtual Dialog * fillDialog(Dialog*)=0;
446
447 /**
448 * This is called internally when the call is being done. Implement this method to do the actual
449 * work of the Action. Implement this in your Derived classes. Needs to return a state that can be
450 * used to undo the action.
451 */
452 virtual state_ptr performCall()=0;
453
454 /**
455 * This is called internally when the undo process is chosen. This Method should use the state
456 * produced by the performCall method to return the state of the application to the state
457 * it had before the Action.
458 */
459 virtual state_ptr performUndo(state_ptr)=0;
460
461 /**
462 * This is called internally when the redo process is chosen. This method shoudl use the state
463 * produced by the performUndo method to return the application to the state it should have after
464 * the action.
465 *
466 * Often this method can be implement to re-use the performCall method. However if user interaction
467 * or further parameters are needed, those should be taken from the state and not query the user
468 * again.
469 */
470 virtual state_ptr performRedo(state_ptr)=0;
471};
472
473/**
474 * This class can be used by actions to save the state.
475 *
476 * It is implementing a memento pattern. The base class is completely empty,
477 * since no general state internals can be given. The Action performing
478 * the Undo should downcast to the apropriate type.
479 */
480class ActionState{
481public:
482 ActionState(){}
483 virtual ~ActionState(){}
484};
485
486/**
487 * This class can be used by actions to contain parameters.
488 *
489 * The base class is completely empty, since no general parameters can be given. The
490 * Action performing the function should construct its own parameter class derived
491 * from it.
492 */
493class ActionParameters{
494public:
495 ActionParameters(){}
496 virtual ~ActionParameters(){}
497};
498
499#endif /* ACTION_H_ */
Note: See TracBrowser for help on using the repository browser.