Changeset 67e2b3 for src/Actions


Ignore:
Timestamp:
Mar 24, 2010, 4:26:21 PM (15 years ago)
Author:
Tillmann Crueger <crueger@…>
Branches:
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
Children:
5b0b98
Parents:
ce1d8c
Message:

Added methods that allow bookkeeping of actions for undo/redo methods

Location:
src/Actions
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/Action.cpp

    rce1d8c r67e2b3  
    1212
    1313using namespace std;
     14
     15// this object is only ever used as indicator.
     16ActionState success_val;
     17
     18ActionState *Action::success = &success_val;
    1419
    1520Action::Action(std::string _name,bool _doRegister) :
     
    2732  return name;
    2833}
     34
     35void Action::call(){
     36  // forward to private virtual
     37  performCall();
     38}
     39ActionState* Action::undo(ActionState* _state) {
     40  // forward to private virtual
     41  return performUndo(_state);
     42}
     43ActionState* Action::redo(ActionState* _state) {
     44  // forward to private virtual
     45  return performRedo(_state);
     46}
  • src/Actions/Action.hpp

    rce1d8c r67e2b3  
    1111#include <string>
    1212
     13// forward declaration
     14
     15class ActionState;
     16class ActionSequence;
     17
    1318/**
    1419 * Base class for all actions.
     
    2126class Action
    2227{
    23 protected:
     28friend class ActionSequence;
    2429public:
    2530  Action(std::string _name,bool _doRegister=true);
    2631  virtual ~Action();
    2732
    28   virtual void call()=0;
    29   virtual void undo()=0;
     33  // this method only handles the infrastructure
     34  // actuall action is passed on to a private virtual
     35  void call();
     36  ActionState* undo(ActionState*);
     37  ActionState* redo(ActionState*);
     38
    3039  virtual bool canUndo()=0;
    31   //virtual bool shouldUndo()=0;
     40  virtual bool shouldUndo()=0;
    3241
    3342  virtual const std::string getName();
    3443
     44protected:
     45  static ActionState* success;
     46
    3547private:
     48  virtual ActionState* performCall()=0;
     49  virtual ActionState* performUndo(ActionState*)=0;
     50  virtual ActionState* performRedo(ActionState*)=0;
     51
    3652  std::string name;
    3753};
    3854
     55/**
     56 * This class can be used by actions to save the state.
     57 *
     58 * It is implementing a memento pattern. The base class is completely empty,
     59 * since no general state internals can be given. The Action performing
     60 * the Undo should downcast to the apropriate type.
     61 */
     62class ActionState{
     63public:
     64  ActionState(){}
     65  virtual ~ActionState(){}
     66};
     67
    3968#endif /* ACTION_H_ */
  • src/Actions/ActionSequence.cpp

    rce1d8c r67e2b3  
    88#include "Actions/ActionSequence.hpp"
    99#include "Actions/Action.hpp"
     10
     11#include "Helpers/Assert.hpp"
    1012
    1113using namespace std;
     
    3436}
    3537
    36 void ActionSequence::callAll(){
    37   deque<Action*>::iterator it;
    38   for(it=actions.begin(); it!=actions.end(); it++)
    39     (*it)->call();
     38ActionSequence::stateSet ActionSequence::callAll(){
     39  stateSet states;
     40  for(actionSet::iterator it=actions.begin(); it!=actions.end(); it++){
     41    // we want to have a global bookkeeping for all actions in the sequence, so
     42    // we bypass the normal call
     43    ActionState *state = (*it)->performCall();
     44    states.push_back(state);
     45  }
     46  return states;
    4047}
    4148
    42 void ActionSequence::undoAll(){
    43   deque<Action*>::reverse_iterator rit;
    44   for(rit=actions.rbegin(); rit!=actions.rend(); rit++)
    45     (*rit)->undo();
     49ActionSequence::stateSet ActionSequence::undoAll(deque<ActionState*> states){
     50  ASSERT(canUndo(),"Trying to undo a sequence that contains methods that can't be undone");
     51  stateSet res;
     52  actionSet::reverse_iterator actionRit = actions.rbegin();
     53  stateSet::reverse_iterator stateRit = states.rbegin();
     54  for(;actionRit!=actions.rend();++actionRit,++stateRit){
     55    ASSERT(stateRit!=states.rend(),"End of states prematurely reached.");
     56    if((*actionRit)->shouldUndo()){
     57      ActionState *newState = (*actionRit)->performUndo(*stateRit);
     58      // The order of the states has to correspond to the order of the actions
     59      // this is why we have to add at the beginning
     60      res.push_front(newState);
     61    }
     62    else{
     63      res.push_front(Action::success);
     64    }
     65  }
     66  return res;
     67}
     68
     69ActionSequence::stateSet ActionSequence::redoAll(deque<ActionState*> states){
     70  stateSet res;
     71  actionSet::iterator actionIt = actions.begin();
     72  stateSet::iterator stateIt = states.begin();
     73  for(;actionIt!=actions.end();++actionIt,++stateIt){
     74    ASSERT(stateIt!=states.end(),"End of states prematurely reached.");
     75    if((*actionIt)->shouldUndo()){
     76      ActionState *newState =(*actionIt)->performRedo(*stateIt);
     77      res.push_back(newState);
     78    }
     79    else{
     80      res.push_back(Action::success);
     81    }
     82  }
     83  return res;
    4684}
    4785
    4886bool ActionSequence::canUndo(){
    4987  bool canUndo=true;
    50   deque<Action*>::iterator it;
    51   for(it=actions.begin(); it!=actions.end(); it++)
    52     canUndo &= (*it)->canUndo();
     88  for(deque<Action*>::iterator it=actions.begin(); it!=actions.end(); ++it){
     89    if((*it)->shouldUndo()){
     90      canUndo &= (*it)->canUndo();
     91    }
     92  }
    5393  return canUndo;
    5494}
     95
     96bool ActionSequence::shouldUndo(){
     97  bool shouldUndo = false;
     98  for(deque<Action*>::iterator it=actions.begin();it!=actions.end();++it){
     99    shouldUndo |= (*it)->shouldUndo();
     100  }
     101  return shouldUndo;
     102}
  • src/Actions/ActionSequence.hpp

    rce1d8c r67e2b3  
    1212
    1313class Action;
     14class ActionState;
    1415
    1516/**
     
    1920{
    2021public:
     22  typedef std::deque<Action*> actionSet;
     23  typedef std::deque<ActionState*> stateSet;
     24
    2125  ActionSequence();
    2226  virtual ~ActionSequence();
     
    2529  Action* removeLastAction();
    2630
    27   void callAll();
    28   void undoAll();
     31  stateSet callAll();
     32  stateSet undoAll(stateSet);
     33  stateSet redoAll(stateSet);
    2934
    3035  bool canUndo();
     36  bool shouldUndo();
    3137
    3238private:
    33   std::deque<Action*> actions;
     39  actionSet actions;
    3440};
    3541
  • src/Actions/Calculation.hpp

    rce1d8c r67e2b3  
    2929   * from menu Items or other places.
    3030   */
    31   virtual void call();
    32   virtual void undo();
    3331  virtual bool canUndo();
     32
     33  virtual bool shouldUndo();
    3434
    3535  /**
     
    6464  virtual T* doCalc()=0;
    6565private:
     66  virtual ActionState* performCall();
     67  virtual ActionState* performUndo(ActionState*);
     68  virtual ActionState* performRedo(ActionState*);
     69
    6670  bool done;
    6771};
  • src/Actions/Calculation_impl.hpp

    rce1d8c r67e2b3  
    2929
    3030template<typename T>
    31 void Calculation<T>::call(){
     31ActionState* Calculation<T>::performCall(){
    3232  reset();
    3333  (*this)();
     34  return Action::success;
    3435}
    3536
    3637template<typename T>
    37 void Calculation<T>::undo(){}
     38ActionState* Calculation<T>::performUndo(ActionState*){
     39  ASSERT(0,"Cannot undo a calculation");
     40  return Action::success;
     41}
     42template<typename T>
     43ActionState* Calculation<T>::performRedo(ActionState*){
     44  ASSERT(0,"Cannot redo a calculation");
     45  return Action::success;
     46}
    3847
    3948template<typename T>
    4049bool Calculation<T>::canUndo()
     50{
     51  return false;
     52}
     53
     54template<typename T>
     55bool Calculation<T>::shouldUndo()
    4156{
    4257  return false;
  • src/Actions/ErrorAction.cpp

    rce1d8c r67e2b3  
    1111#include "log.hpp"
    1212#include "verbose.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    2425}
    2526
    26 void ErrorAction::call() {
     27ActionState* ErrorAction::performCall() {
    2728  Log() << Verbose(0) << errorMsg << endl;
     29  return Action::success;
    2830}
    29 void ErrorAction::undo() {
     31ActionState* ErrorAction::performUndo(ActionState*) {
     32  ASSERT(0,"Undo called for an ErrorAction");
     33  return Action::success;
     34}
     35
     36ActionState* ErrorAction::performRedo(ActionState*) {
     37  ASSERT(0,"Redo called for an ErrorAction");
     38  return Action::success;
    3039}
    3140
     
    3342  return false;
    3443}
     44
     45bool ErrorAction::shouldUndo(){
     46  return false;
     47}
  • src/Actions/ErrorAction.hpp

    rce1d8c r67e2b3  
    1818  virtual ~ErrorAction();
    1919
    20   virtual void call();
    21   virtual void undo();
    2220  virtual bool canUndo();
     21  virtual bool shouldUndo();
    2322
    2423private:
     24
     25  virtual ActionState* performCall();
     26  virtual ActionState* performUndo(ActionState*);
     27  virtual ActionState* performRedo(ActionState*);
     28
    2529  std::string errorMsg;
    2630};
  • src/Actions/MakroAction.cpp

    rce1d8c r67e2b3  
    1111#include "Actions/Action.hpp"
    1212#include "Actions/ActionSequence.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     16
     17class MakroActionState : public ActionState{
     18public:
     19  MakroActionState(ActionSequence::stateSet _states) :
     20    states(_states)
     21  {}
     22  virtual ~MakroActionState(){
     23    for(ActionSequence::stateSet::iterator iter=states.begin();
     24        iter!=states.end();++iter){
     25      delete *iter;
     26    }
     27  }
     28
     29  ActionSequence::stateSet states;
     30};
    1531
    1632MakroAction::MakroAction(string _name,ActionSequence* _actions,bool _doRegister) :
     
    3046
    3147
    32 void MakroAction::call(){
    33   actions->callAll();
     48ActionState* MakroAction::performCall(){
     49  ActionSequence::stateSet states = actions->callAll();
     50  return new MakroActionState(states);
    3451}
    3552
    36 void MakroAction::undo() {
    37   actions->undoAll();
     53ActionState* MakroAction::performUndo(ActionState* _state) {
     54  MakroActionState *state = dynamic_cast<MakroActionState*>(_state);
     55  ASSERT(state,"Type mismatch for the state of the MakroAction");
     56  ActionSequence::stateSet states = actions->undoAll(state->states);
     57  return new MakroActionState(states);
    3858}
    3959
     
    4161  return actions->canUndo();
    4262}
     63
     64bool MakroAction::shouldUndo() {
     65  return actions->shouldUndo();
     66}
  • src/Actions/MakroAction.hpp

    rce1d8c r67e2b3  
    2626  virtual ~MakroAction();
    2727
    28   virtual void call();
    29   virtual void undo();
    30   virtual bool canUndo();
     28  bool canUndo();
     29  bool shouldUndo();
    3130
    3231private:
     32  virtual ActionState* performCall();
     33  virtual ActionState* performUndo(ActionState*);
     34  virtual ActionState* performRedo(ActionState*);
     35
    3336  ActionSequence *actions;
    3437};
  • src/Actions/ManipulateAtomsProcess.cpp

    rce1d8c r67e2b3  
    1111
    1212#include "World.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    2425{}
    2526
    26 void ManipulateAtomsProcess::call(){
     27ActionState* ManipulateAtomsProcess::performCall(){
    2728  World::getInstance().doManipulate(this);
     29  return Action::success;
    2830}
    2931
    30 void ManipulateAtomsProcess::undo(){
     32ActionState* ManipulateAtomsProcess::performUndo(ActionState*){
     33  ASSERT(0,"Undo called for a ManipulateAtomsProcess");
     34  return Action::success;
     35}
    3136
     37ActionState* ManipulateAtomsProcess::performRedo(ActionState*){
     38  ASSERT(0,"Redo called for a ManipulateAtomsProcess");
     39  return Action::success;
    3240}
    3341
    3442bool ManipulateAtomsProcess::canUndo(){
    3543  return false;
     44}
     45
     46bool ManipulateAtomsProcess::shouldUndo(){
     47  return true;
    3648}
    3749
  • src/Actions/ManipulateAtomsProcess.hpp

    rce1d8c r67e2b3  
    2323  virtual ~ManipulateAtomsProcess();
    2424
    25   virtual void call();
    26   virtual void undo();
    2725  virtual bool canUndo();
     26  virtual bool shouldUndo();
    2827
    2928  virtual void doManipulate(World *);
    3029private:
     30
     31  virtual ActionState* performCall();
     32  virtual ActionState* performUndo(ActionState*);
     33  virtual ActionState* performRedo(ActionState*);
     34
    3135  AtomDescriptor descr;
    3236  boost::function<void(atom*)> operation;
  • src/Actions/MethodAction.cpp

    rce1d8c r67e2b3  
    1010#include <string>
    1111
    12 #include "MethodAction.hpp"
     12#include "Actions/MethodAction.hpp"
     13#include "Helpers/Assert.hpp"
    1314
    1415using namespace std;
     
    2122
    2223MethodAction::~MethodAction()
    23 {
    24   // TODO Auto-generated destructor stub
     24{}
     25
     26
     27ActionState* MethodAction::performCall() {
     28  executeMethod();
     29  // we don't have a state to save so we return Action::success
     30  return Action::success;
    2531}
    2632
     33ActionState* MethodAction::performUndo(ActionState*) {
     34  ASSERT(0,"Cannot undo a MethodAction");
     35  return Action::success;
     36}
    2737
    28 void MethodAction::call() {
    29   executeMethod();
    30 }
    31 void MethodAction::undo() {
    32 
     38ActionState* MethodAction::performRedo(ActionState*){
     39  ASSERT(0,"Cannot redo a MethodAction");
     40  return Action::success;
    3341}
    3442
     
    3644  return false;
    3745}
     46
     47bool MethodAction::shouldUndo(){
     48  return true;
     49}
  • src/Actions/MethodAction.hpp

    rce1d8c r67e2b3  
    2222  MethodAction(std::string _name,boost::function<void()> _executeMethod,bool _doRegister=true);
    2323  virtual ~MethodAction();
     24  virtual bool canUndo();
     25  virtual bool shouldUndo();
    2426
    25   virtual void call();
    26   virtual void undo();
    27   virtual bool canUndo();
     27private:
     28  virtual ActionState* performCall();
     29  virtual ActionState* performUndo(ActionState*);
     30  virtual ActionState* performRedo(ActionState*);
     31
    2832
    2933  boost::function<void()> executeMethod; //!< this stores the method to be called
    30 
    31 
    3234};
    3335
  • src/Actions/small_actions.cpp

    rce1d8c r67e2b3  
    1414/****** ChangeMoleculeNameAction *****/
    1515
     16// memento to remember the state when undoing
     17
     18class ChangeMoleculeNameState : public ActionState {
     19public:
     20  ChangeMoleculeNameState(molecule* _mol,std::string _lastName) :
     21    mol(_mol),
     22    lastName(_lastName)
     23  {}
     24  molecule* mol;
     25  std::string lastName;
     26};
     27
    1628char ChangeMoleculeNameAction::NAME[] = "Change filename of Molecule";
    1729
     
    2436{}
    2537
    26 void ChangeMoleculeNameAction::call() {
     38ActionState* ChangeMoleculeNameAction::performCall() {
    2739  string filename;
    2840  molecule *mol = NULL;
     
    3143  dialog->queryMolecule("Enter index of molecule: ",&mol,molecules);
    3244  dialog->queryString("Enter name: ",&filename);
     45
    3346  if(dialog->display()) {
     47    string oldName = mol->getName();
    3448    mol->setName(filename);
     49    delete dialog;
     50    return new ChangeMoleculeNameState(mol,oldName);
    3551  }
    36 
    37   delete dialog;
     52  return 0;
    3853}
    3954
    40 void ChangeMoleculeNameAction::undo() {
     55ActionState* ChangeMoleculeNameAction::performUndo(ActionState* _state) {
     56  ChangeMoleculeNameState *state = dynamic_cast<ChangeMoleculeNameState*>(_state);
     57  ASSERT(state,"State passed to ChangeMoleculeNameAction::performUndo did not have correct type");
    4158
     59  string newName = state->mol->getName();
     60  state->mol->setName(state->lastName);
     61
     62  return new ChangeMoleculeNameState(state->mol,newName);
     63}
     64
     65ActionState* ChangeMoleculeNameAction::performRedo(ActionState *_state){
     66  // Undo and redo have to do the same for this action
     67  return performUndo(_state);
    4268}
    4369
    4470bool ChangeMoleculeNameAction::canUndo() {
    45   return false;
     71  return true;
    4672}
    4773
  • src/Actions/small_actions.hpp

    rce1d8c r67e2b3  
    1414  virtual ~ChangeMoleculeNameAction();
    1515
    16   void call();
    17   void undo();
    1816  bool canUndo();
    1917  bool shouldUndo();
     
    2119  virtual const std::string getName();
    2220private:
     21  virtual ActionState* performCall();
     22  virtual ActionState* performUndo(ActionState*);
     23  virtual ActionState* performRedo(ActionState*);
     24
    2325  MoleculeListClass *molecules;
    2426  static char NAME[];
Note: See TracChangeset for help on using the changeset viewer.