[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: Design for undo/redo support in drgeo/* code...



Je reprends plus en profondeur la réponse que j'avais
faite il y a quelques jours notamment comment sauvegarder
un objet effacé, recréer un objet effacé et comment 
résoudre le problème que tu avais évoqué. 
Oops I'm writting in french...


> And now here is an example of how to use that class based on the
> example of the command "removeItem()".  First we have to sub-class the
> drgeoCommand class:
> 
>   class drgeoRemoveItemCommand {
>   public:
>     ~drgeoRemoveItemCommand ();
>     drgeoRemoveItemCommand (drgeoFigure *aFigure, const char *aItem);
> 
>     void Execute ();
>     void Unexecute ();
>   private:
>     // We keep all the information for undo/redo in the private part.
>     drgeoFigure *mFigure;
>     char *mItem;
>     XXX *mBackup;
>   };
> 
> Here is now a start of implementation of the methods of this class:
> 
>   drgeoRemoveItemCommand::~drgeoRemoveItemCommand ()
>   {
>     if (mBackup)
>       delete mBackup;
>   }
> 
>   drgeoRemoveItemCommand::drgeoRemoveItemCommand (drgeoFigure *aFigure,
> 						  const char *aItem)
>   {
>     mFigure = aFigure;
>     mItem = aItem;
>     mBackup = NULL;
>   }
> 
>   void drgeoRemoveItemCommand::Execute ()
>   {
>     // Before removing the item, we must save data about it, so that
>     // it can be restored later.  Is suggest to keep information about
>     // it as an XML data structure.
>     mBackup = mFigure->saveItem (mItem);
> 
>     mFigure->_removeItem (mItem);
>   }

CAUTION,
Removing an item can result in removing several items if this item
has ancestors. So better go through a list.

> 
>   void drgeoRemoveItemCommand::Unexecute ()
>   {
>     // We have to re-create the item from the data we have previously
>     // saved.  I suggest that we use an XML data structure.
> 
>     mFigure->restoreItem (mBackup);
>   }

Alright, we can use a xml structure to save the deleted object. 
I suggest reusing the existing method save of the class geometricObject.
In the resulting xml strucuture an ancestor is identified with its reference.
The counter part of the save method is the class builder that required a
xmlNodePtr, a hash table and the list of the existing item in the figure.
So the hack will start there by using a dedicated hash table for this.
The hash will exist as long as undo are on the pipe, so it will be an attribute
of the drgeoFigure class. The key of the hash table are the id of
the item and the value the reference to the item. 
Each time an item is deleted its parents are added in the hash table using
the parent reference as both the key and value.

Concerning the problem you show it's now just a matter 
of updating in the hash table the value associated with 
the [AB] id key when [AB] is recreated,the key of [AB] can't change 
as it's used in XML strucured of the deleted C point.

When [AB] is deleted, we need to keep the reference of [AB] (it's a key 
because we previously delete C) in the command, then when [AB] is rebuilt, 
the value assiocated with the key can be updated.
The hash table is reseted when an operation is performed.

Oh, I just realize that you formulate unappropriatly your exemple,
I think you mean:

   * create point A.
 
   * create point B.
 
   * create segment [AB].
 
   * create C the middle of segment [AB].
 
   * remove C.
 
   * remove [AB].
 
   * redo [AB].
 
   * redo C.
 

But well the same problem appears with the other example.
And the situation is a much complicated.


Hilaire

--
http://www.ofset.org