• entries
    743
  • comments
    1924
  • views
    579538

Undo and redo and all that jazz

Sign in to follow this  
Aardvajk

378 views

No pictures today, nothing really new to share in that respect.

I've now got undo and redo working with the selection system (selection is the only thing implemented that actually modifies the state of the model at the moment). I really needed to get cracking on this as I wasn't prepared to write any more code that modified the model state until I had this working.

I have a ptr_stack class (a wrapper around a ptr_vector which is my version of boost::ptr_vector). The model contains two ptr_stack >'s - the UndoStack and the RedoStack.

UndoAction is the base class for what I am hoping will just be three types of undo actions - those that modify the current vertices or faces, those that add vertices or faces and those that remove vertices or faces.

UndoAction looks like this:

[source lang="cpp"]
class UndoAction
{
public:
virtual ~UndoAction(){ }

virtual void Undo(Model &M)=0;
virtual UndoAction *Redo(Model &M)=0;
};
[/source]

Undo() obviously does what it says on the tin - it reverses whatever changes are stored in the UndoAction concrete instance. Redo()'s responsibility is to return a new UndoAction instance that basically reverses whatever changes this instance performs.

So it is just a case of messing about with the undo and redo stacks in response to Undo() and Redo() methods on the model. For example:

[source lang="cpp"]
void Model::Undo()
{
if(!UndoStack.empty())
{
RedoStack.push(new stx::ptr_stack());

while(!UndoStack.top().empty())
{
RedoStack.top().push(UndoStack.top().top().Redo(*this));

UndoStack.top().top().Undo(*this);
UndoStack.top().pop();
}

UndoStack.pop();
}
}
[/source]

Whenever a new UndoAction is pushed in response to some kind of modification of the model, the RedoStack gets cleared. Seems to work fine so far.

I changed the Model interface so that external code can only access its data in a read-only fashion, meaning any modification of the model has to be done via member functions of the Model class. This means that I can control the undo and redo stacks all centrally within the implementation of Model rather than have it peppered throughout the code base.

The model also has BeginUndoSequence() and EndUndoSequence() methods that external code can call to group a series of actions into a single undo/redo step. You know the sort of thing. Blah blah.

So quite a milestone really. Next up is Delete then the Move tool, then a vertex creation tool, and a system to create and reverse faces. From there, I can actually start making more complex models with the editor itself rather than keep staring at this stupid cube.

I can then move on to loading and saving this model and we are starting to get somewhere.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now