/* * ActionSequenze.cpp * * Created on: Dec 17, 2009 * Author: crueger */ #include "Actions/ActionSequence.hpp" #include "Actions/Action.hpp" #include "Helpers/Assert.hpp" using namespace std; ActionSequence::ActionSequence() {} ActionSequence::~ActionSequence() {} void ActionSequence::addAction(Action* _action){ actions.push_back(_action); } Action* ActionSequence::removeLastAction(){ if(actions.empty()) { return 0; } else { Action* theAction; theAction = actions.back(); actions.pop_back(); return theAction; } } // this method is used outside the ActionModule // Each action registers itself with the history void ActionSequence::callAll(){ for(actionSet::iterator it=actions.begin(); it!=actions.end(); it++){ // we want to have a global bookkeeping for all actions in the sequence, so // we bypass the normal call (*it)->call(); } } // This method is used internally when MakroActions are constructed. // In this case only the makro Action should be registered and // handle the states ActionSequence::stateSet ActionSequence::callAll(bool){ stateSet states; for(actionSet::iterator it=actions.begin(); it!=actions.end(); it++){ // we want to have a global bookkeeping for all actions in the sequence, so // we bypass the normal call Action::state_ptr state = (*it)->performCall(); states.push_back(state); } return states; } ActionSequence::stateSet ActionSequence::undoAll(stateSet states){ ASSERT(canUndo(),"Trying to undo a sequence that contains methods that can't be undone"); stateSet res; actionSet::reverse_iterator actionRit = actions.rbegin(); stateSet::reverse_iterator stateRit = states.rbegin(); for(;actionRit!=actions.rend();++actionRit,++stateRit){ ASSERT(stateRit!=states.rend(),"End of states prematurely reached."); if((*actionRit)->shouldUndo()){ Action::state_ptr newState = (*actionRit)->performUndo(*stateRit); // The order of the states has to correspond to the order of the actions // this is why we have to add at the beginning res.push_front(newState); } else{ res.push_front(Action::success); } } return res; } ActionSequence::stateSet ActionSequence::redoAll(stateSet states){ stateSet res; actionSet::iterator actionIt = actions.begin(); stateSet::iterator stateIt = states.begin(); for(;actionIt!=actions.end();++actionIt,++stateIt){ ASSERT(stateIt!=states.end(),"End of states prematurely reached."); if((*actionIt)->shouldUndo()){ Action::state_ptr newState =(*actionIt)->performRedo(*stateIt); res.push_back(newState); } else{ res.push_back(Action::success); } } return res; } bool ActionSequence::canUndo(){ bool canUndo=true; for(deque::iterator it=actions.begin(); it!=actions.end(); ++it){ if((*it)->shouldUndo()){ canUndo &= (*it)->canUndo(); } } return canUndo; } bool ActionSequence::shouldUndo(){ bool shouldUndo = false; for(deque::iterator it=actions.begin();it!=actions.end();++it){ shouldUndo |= (*it)->shouldUndo(); } return shouldUndo; }