Generic Undo-Framework?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Generic Undo-Framework?

Andreas Tönne
All,

I am looking (for a customer) for existing work and possibly services for a
generic Undo-framework for VisualWorks 7.5.

Background: my customer has a GUI application with a sophisticated and
rather complex domain model, which up to now was very resistant against
implementing Undo functionality. The domain model is too complex and large
to be stored as a whole for Undo steps.

Possible solutions that we discussed where to model and record macro (GUI)
activities on the domain that entail their own undo.
Also on the other end of the spectrum we think about a transactional system
on the domain itself, where each GUI activity would trigger one
transactional context to be unrolled on Undo. Because of the complexity of
the domain logic, such transaction system needs to be put ontop of the
domain classes transparently (e.g. MethodWrapper technology)

Does anyone know of work on generic solutions for such Undo functionality?
Presentations, papers, frameworks?

Thank you,

Andreas

--
Andreas Tönne
Lead Consultant
Cincom Systems GmbH & Co. oHG
Tel.: +49 6196 9003 100
Mobile: +49 172 6159272

Geschäftsführer/Managing Directors: Thomas M. Nies, Gerald L. Shawhan
oHG mit Sitz/based in Schwalbach/Ts. (Amtsgericht Königstein/Ts. HRA
2653)
Pers. haftender Gesellschafter/Partner liable to unlimited extent:
Cincom Systems Verwaltungsgesellschaft mbH (Amtsgericht Königstein/
Ts. HRB 5069)

Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Karsten Kusche
I just implemented such a framework a couple of weeks ago, it's called
UnDo and it's in the public repository (i published as guest by accident).

it's implemented with Cocoa's undo-implementation in mind, which i think
is pretty simple. You just create an UndoManager and send it
#registerUndoFor: aTarget. then you send your message to the returned
object and it records this. when you send undo to the manager it'll
apply this recorded action.

registering an undo while an undo is performed will automatically put
this onto the redo stack.

so if you have a class "person" and the #name: method is implemented
like this:

name: newName
    (self undoManager registerUndoFor: self) name: name.
    name := newName.

it should be able to undo and redo the name changes just by sending
#undo and #redo to its undo manager.

Kind Regards
Karsten


Andreas Tönne wrote:

> All,
>
> I am looking (for a customer) for existing work and possibly services for a
> generic Undo-framework for VisualWorks 7.5.
>
> Background: my customer has a GUI application with a sophisticated and
> rather complex domain model, which up to now was very resistant against
> implementing Undo functionality. The domain model is too complex and large
> to be stored as a whole for Undo steps.
>
> Possible solutions that we discussed where to model and record macro (GUI)
> activities on the domain that entail their own undo.
> Also on the other end of the spectrum we think about a transactional system
> on the domain itself, where each GUI activity would trigger one
> transactional context to be unrolled on Undo. Because of the complexity of
> the domain logic, such transaction system needs to be put ontop of the
> domain classes transparently (e.g. MethodWrapper technology)
>
> Does anyone know of work on generic solutions for such Undo functionality?
> Presentations, papers, frameworks?
>
> Thank you,
>
> Andreas
>
>  

--
Karsten Kusche - Dipl.Inf. - [hidden email]
Georg Heeg eK - Köthen
Handelsregister: Amtsgericht Dortmund A 12812

Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Alan Knight-2
In reply to this post by Andreas Tönne
I'm aware of two classes of mechanisms for modelling such things. One is by using the Command pattern, where commands know how to undo themselves, as used in the Refactoring Browser. However, this could be hard to retrofit onto a large existing system. The other is to do some level of copying and be able to revert it. An example of this can be found in ObjectTransaction in Glorp. The ObjectTransaction class has minimal dependencies on the rest of Glorp, mostly for Dialect portability operations, and would be quite easy to extract.

The difficulty with the copying approaches is that you don't want to copy the entire transitive closure of domain objects, and you also want to avoid copying non-domain objects (e.g. blocks, their containing methods, their containing classes, their superclasses and subclasses, etc.). If using Glorp, or something similar, then the constraint is fairly easy. Non-persistent objects don't count, and you are likely to have uninstantiated proxies as stopping points.

In a more general context, you would need to define a way to register the transitive closure from an object you were interested in, and define stopping points for it. I had reasonable success just stopping at blocks, classes, and primitives, but that was for fairly simple usage.

At 09:24 AM 1/7/2008, Andreas Tönne wrote:
All,

I am looking (for a customer) for existing work and possibly services for a
generic Undo-framework for VisualWorks 7.5.

Background: my customer has a GUI application with a sophisticated and
rather complex domain model, which up to now was very resistant against
implementing Undo functionality. The domain model is too complex and large
to be stored as a whole for Undo steps.

Possible solutions that we discussed where to model and record macro (GUI)
activities on the domain that entail their own undo.
Also on the other end of the spectrum we think about a transactional system
on the domain itself, where each GUI activity would trigger one
transactional context to be unrolled on Undo. Because of the complexity of
the domain logic, such transaction system needs to be put ontop of the
domain classes transparently (e.g. MethodWrapper technology)

Does anyone know of work on generic solutions for such Undo functionality?
Presentations, papers, frameworks?

Thank you,

Andreas

--
Andreas Tönne
Lead Consultant
Cincom Systems GmbH & Co. oHG
Tel.: +49 6196 9003 100
Mobile: +49 172 6159272

Geschäftsführer/Managing Directors: Thomas M. Nies, Gerald L. Shawhan
oHG mit Sitz/based in Schwalbach/Ts. (Amtsgericht Königstein/Ts. HRA
2653)
Pers. haftender Gesellschafter/Partner liable to unlimited extent:
Cincom Systems Verwaltungsgesellschaft mbH (Amtsgericht Königstein/
Ts. HRB 5069)

--
Alan Knight [|], Cincom Smalltalk Development
Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Andreas Tönne
In reply to this post by Andreas Tönne
Re: Generic Undo-Framework? Alan,

thank you. I meant the Command pattern (am I too old to rethink my Smalltalk in stylish patterns? :-) when I wrote about modeling macro activities. Thank you for pointing me to the RB and ObjectTransaction. Copying, even with cleverly defined closures, is out of scope. The domain is a complex graph of significant size but unfortunatly some activities can have global consequences, e.g. triggering re-routing. Hence the alternative idea of recording changes at the instvar level.

Andreas

Am 07.01.2008 15:38 Uhr schrieb "Alan Knight" unter <[hidden email]>:

I'm aware of two classes of mechanisms for modelling such things. One is by using the Command pattern, where commands know how to undo themselves, as used in the Refactoring Browser. However, this could be hard to retrofit onto a large existing system. The other is to do some level of copying and be able to revert it. An example of this can be found in ObjectTransaction in Glorp. The ObjectTransaction class has minimal dependencies on the rest of Glorp, mostly for Dialect portability operations, and would be quite easy to extract.

The difficulty with the copying approaches is that you don't want to copy the entire transitive closure of domain objects, and you also want to avoid copying non-domain objects (e.g. blocks, their containing methods, their containing classes, their superclasses and subclasses, etc.). If using Glorp, or something similar, then the constraint is fairly easy. Non-persistent objects don't count, and you are likely to have uninstantiated proxies as stopping points.

In a more general context, you would need to define a way to register the transitive closure from an object you were interested in, and define stopping points for it. I had reasonable success just stopping at blocks, classes, and primitives, but that was for fairly simple usage.

At 09:24 AM 1/7/2008, Andreas Tönne wrote:
All,

I am looking (for a customer) for existing work and possibly services for a
generic Undo-framework for VisualWorks 7.5.

Background: my customer has a GUI application with a sophisticated and
rather complex domain model, which up to now was very resistant against
implementing Undo functionality. The domain model is too complex and large
to be stored as a whole for Undo steps.

Possible solutions that we discussed where to model and record macro (GUI)
activities on the domain that entail their own undo.
Also on the other end of the spectrum we think about a transactional system
on the domain itself, where each GUI activity would trigger one
transactional context to be unrolled on Undo. Because of the complexity of
the domain logic, such transaction system needs to be put ontop of the
domain classes transparently (e.g. MethodWrapper technology)

Does anyone know of work on generic solutions for such Undo functionality?
Presentations, papers, frameworks?

Thank you,

Andreas


--
Andreas Tönne
Lead Consultant
Cincom Systems GmbH & Co. oHG
Tel.: +49 6196 9003 100
Mobile: +49 172 6159272

Geschäftsführer/Managing Directors: Thomas M. Nies, Gerald L. Shawhan
oHG mit Sitz/based in Schwalbach/Ts. (Amtsgericht Königstein/Ts. HRA  
2653)
Pers. haftender Gesellschafter/Partner liable to unlimited extent:
Cincom Systems Verwaltungsgesellschaft mbH (Amtsgericht Königstein/
Ts. HRB 5069)
Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Reinout Heeck
In reply to this post by Andreas Tönne
Andreas Tönne wrote:

> All,
>
> I am looking (for a customer) for existing work and possibly services for a
> generic Undo-framework for VisualWorks 7.5.
>
> Background: my customer has a GUI application with a sophisticated and
> rather complex domain model, which up to now was very resistant against
> implementing Undo functionality. The domain model is too complex and large
> to be stored as a whole for Undo steps.
>
> Possible solutions that we discussed where to model and record macro (GUI)
> activities on the domain that entail their own undo.
> Also on the other end of the spectrum we think about a transactional system
> on the domain itself, where each GUI activity would trigger one
> transactional context to be unrolled on Undo. Because of the complexity of
> the domain logic, such transaction system needs to be put ontop of the
> domain classes transparently (e.g. MethodWrapper technology)
>
> Does anyone know of work on generic solutions for such Undo functionality?
> Presentations, papers, frameworks?

The Google query
   site:citeseer.ist.psu.edu undo
probably presents plenty papers to ponder.


R
-

Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Annick
In reply to this post by Andreas Tönne
Hi,

You might also look at GF-ST simple framework.
Annick Fron

Le 7 janv. 08 à 15:24, Andreas Tönne a écrit :

> All,
>
> I am looking (for a customer) for existing work and possibly  
> services for a
> generic Undo-framework for VisualWorks 7.5.
>
> Background: my customer has a GUI application with a sophisticated and
> rather complex domain model, which up to now was very resistant  
> against
> implementing Undo functionality. The domain model is too complex  
> and large
> to be stored as a whole for Undo steps.
>
> Possible solutions that we discussed where to model and record  
> macro (GUI)
> activities on the domain that entail their own undo.
> Also on the other end of the spectrum we think about a  
> transactional system
> on the domain itself, where each GUI activity would trigger one
> transactional context to be unrolled on Undo. Because of the  
> complexity of
> the domain logic, such transaction system needs to be put ontop of the
> domain classes transparently (e.g. MethodWrapper technology)
>
> Does anyone know of work on generic solutions for such Undo  
> functionality?
> Presentations, papers, frameworks?
>
> Thank you,
>
> Andreas
>
> --
> Andreas Tönne
> Lead Consultant
> Cincom Systems GmbH & Co. oHG
> Tel.: +49 6196 9003 100
> Mobile: +49 172 6159272
>
> Geschäftsführer/Managing Directors: Thomas M. Nies, Gerald L. Shawhan
> oHG mit Sitz/based in Schwalbach/Ts. (Amtsgericht Königstein/Ts. HRA
> 2653)
> Pers. haftender Gesellschafter/Partner liable to unlimited extent:
> Cincom Systems Verwaltungsgesellschaft mbH (Amtsgericht Königstein/
> Ts. HRB 5069)
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Alan Knight-2
In reply to this post by Andreas Tönne
OK, although I will note that copying often isn't nearly as expensive as people think it might be.

At 09:53 AM 1/7/2008, Andreas Tönne wrote:
Alan,

thank you. I meant the Command pattern (am I too old to rethink my Smalltalk in stylish patterns? :-) when I wrote about modeling macro activities. Thank you for pointing me to the RB and ObjectTransaction. Copying, even with cleverly defined closures, is out of scope. The domain is a complex graph of significant size but unfortunatly some activities can have global consequences, e.g. triggering re-routing. Hence the alternative idea of recording changes at the instvar level.

Andreas

Am 07.01.2008 15:38 Uhr schrieb "Alan Knight" unter <[hidden email]>:

I'm aware of two classes of mechanisms for modelling such things. One is by using the Command pattern, where commands know how to undo themselves, as used in the Refactoring Browser. However, this could be hard to retrofit onto a large existing system. The other is to do some level of copying and be able to revert it. An example of this can be found in ObjectTransaction in Glorp. The ObjectTransaction class has minimal dependencies on the rest of Glorp, mostly for Dialect portability operations, and would be quite easy to extract.

The difficulty with the copying approaches is that you don't want to copy the entire transitive closure of domain objects, and you also want to avoid copying non-domain objects (e.g. blocks, their containing methods, their containing classes, their superclasses and subclasses, etc.). If using Glorp, or something similar, then the constraint is fairly easy. Non-persistent objects don't count, and you are likely to have uninstantiated proxies as stopping points.

In a more general context, you would need to define a way to register the transitive closure from an object you were interested in, and define stopping points for it. I had reasonable success just stopping at blocks, classes, and primitives, but that was for fairly simple usage.

At 09:24 AM 1/7/2008, Andreas Tönne wrote:
All,

I am looking (for a customer) for existing work and possibly services for a
generic Undo-framework for VisualWorks 7.5.

Background: my customer has a GUI application with a sophisticated and
rather complex domain model, which up to now was very resistant against
implementing Undo functionality. The domain model is too complex and large
to be stored as a whole for Undo steps.

Possible solutions that we discussed where to model and record macro (GUI)
activities on the domain that entail their own undo.
Also on the other end of the spectrum we think about a transactional system
on the domain itself, where each GUI activity would trigger one
transactional context to be unrolled on Undo. Because of the complexity of
the domain logic, such transaction system needs to be put ontop of the
domain classes transparently (e.g. MethodWrapper technology)

Does anyone know of work on generic solutions for such Undo functionality?
Presentations, papers, frameworks?

Thank you,

Andreas



--
Andreas Tönne
Lead Consultant
Cincom Systems GmbH & Co. oHG
Tel.: +49 6196 9003 100
Mobile: +49 172 6159272

Geschäftsführer/Managing Directors: Thomas M. Nies, Gerald L. Shawhan
oHG mit Sitz/based in Schwalbach/Ts. (Amtsgericht Königstein/Ts. HRA 
2653)
Pers. haftender Gesellschafter/Partner liable to unlimited extent:
Cincom Systems Verwaltungsgesellschaft mbH (Amtsgericht Königstein/
Ts. HRB 5069)

--
Alan Knight [|], Cincom Smalltalk Development
Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Andre Schnoor
Alan Knight wrote:
OK, although I will note that copying often isn't nearly as expensive as people think it might be.


Fully agree. In my composition applications, for instance, I'm dealing with complex heterogeneous nested structures with a fair amount of cycles and redundancy (caching). I am able to undo hours worth of extensive editing without problems (hundreds of steps). Provided your objects fit into memory and don't carry heavy payloads (images, blobs, massive text), partially copying them is quite efficient.

I'm using a class tree of 25 specialized UndoActions, each of which is responsible for backung up and restoring a particular part of a structure only. As opposed to recording edit actions like the RB,  this has the advantage of a single UndoAction being suitable for a larger number of edit actions (The downside is I can't support Redo this way).

From my experience, implementing the undo feature is impossible without a deep understanding of the structures and dependencies of your domain models. Hence, a "generic" undo framework may not be efficient in all cases.


Andre

Reply | Threaded
Open this post in threaded view
|

Re: Generic Undo-Framework?

Alan Knight-2
At 03:50 AM 1/8/2008, Andre Schnoor wrote:
Alan Knight wrote:
OK, although I will note that copying often isn't nearly as expensive as people think it might be.

Fully agree. In my composition applications, for instance, I'm dealing with complex heterogeneous nested structures with a fair amount of cycles and redundancy (caching). I am able to undo hours worth of extensive editing without problems (hundreds of steps). Provided your objects fit into memory and don't carry heavy payloads (images, blobs, massive text), partially copying them is quite efficient.

I'm using a class tree of 25 specialized UndoActions, each of which is responsible for backung up and restoring a particular part of a structure only. As opposed to recording edit actions like the RB,  this has the advantage of a single UndoAction being suitable for a larger number of edit actions (The downside is I can't support Redo this way).

From my experience, implementing the undo feature is impossible without a deep understanding of the structures and dependencies of your domain models. Hence, a "generic" undo framework may not be efficient in all cases.

I ended up being very happy with the way the underlying undo/transaction mechanism worked in Glorp, which is extremely generic. The main understanding that you need is understanding where you can prune copying/which objects may be affected by a change. Rather than copying whole chunks and then putting them back as whole chunks, it copies the state and restores it to the same objects when necessary, and I found this to work really well.

But with knowledge of semantics, you definitely can do some cool things. One of the nicest undo frameworks I remember was from a C++ solid modelling library (from many years ago). It used the command pattern and had complete undo and redo, and it was extremely simple. But this was because they only really had three operations. Intersection, Union, and, um, something else that I can't remember right now, and compositions of those. And the undo of a composed operation was just undoing each of its components in reverse order.


--
Alan Knight [|], Cincom Smalltalk Development