Re: Action based undo or snapshot based undo?
Re: Action based undo or snapshot based undo?
- Subject: Re: Action based undo or snapshot based undo?
- From: Brock Brandenberg <email@hidden>
- Date: Thu, 30 Jan 2003 16:12:35 -0600
Hi Greg.
>
It sounds to me like our semantic issue is in distinguishing between
>
"model objects" and "attribute values". Or just that I didn't actually
>
define those terms when I was using them. There is a continuum in
>
possible designs of where you draw the line between _this_ is a model
>
object, and _that_ is an attribute value.
That's an excellent way to phrase it. I've been stumbling to express ideas
using the right terms, and this plus Bill's use of "operations" and
"actions" really helps make the concepts more definitive.
>
...
>
I guess the point that I'm trying to get to is that I think you end up
>
with a straightforward, working, easy to understand and maintain model
>
when you restrict your design so that the objects that are 'mutable'
>
include undo and notification internally, and anything else in your
>
model should be immutable and replaced every time it is changed by one
>
of the mutable objects.
I definitely agree. No arguments here.
>
> To clarify, I'm trying to make a distinction between undo actions which
>
> simply reverse user actions by sending the same message again with values
>
> that would restore the previous state, and undo actions that send a different
>
> message that result in restoration of a previous state. For example, actions
>
> like a color change can be reversed by performing the same method over again
>
> with different values. But other actions, like removing a node from a linked
>
> list cannot always be undone by simply re-inserting a node.
>
>
If not, try to redesign your model so that it does! (I know, I know,
>
easy for me to say...)
I'd love to, but we've been unable to come up with a working solution so
far. The innards are composed of "objects" that are structs pointing to
structs pointing to structs pointing to structs... And instead of a single,
nice linked list holding all the "objects" together, objects in the list
have additional linkages to other objects, which form linkage graphs that
are overlaid and dependent on the main linked list. When the main list
changes, it can break all kinds of other linkages, so we've chosen the
snapshot method to restore the list structure because it's bulletproof.
Brute force, but bulletproof. At least for a limited number of undos.
The program is much like a parametric 3D modeling program, but only in 2D.
So objects rely on multiple other objects for characteristics like position,
size and rotation, and when those objects go away, you have to break their
dependencies. Restoring all those linkages is the difficult part that I'm
grappling with since the core model is all done with pointers in structs.
Other mutable data is easy to undo using techniques like you mention, so we
only resort to restoring linkages thru snapshots for those operations that
have destructive effects on the list. It's all pretty clean since the list
is just an attribute of a model object, so the model is just restoring the
state of its attribute.
I'm by no means the expert in this, so I'm always looking for inspiration to
do things better. I can only express the problems that we have to deal with
and the solutions that we've come up with so far, and hopefully gain a
better understanding from others who have solved similar problems :-)
>
> If the node has children that maintain their properties due to the position
>
> and properties of the parent node, then removing the parent node can have
>
> very destructive effects on the linked list, and the list may need to be
>
> "restored" by reverting the state of the list (or at least a significant
>
> subset of it). In our case, we have too many inter-object dependencies to
>
> simply stitch a list back together by calling methods to re-establish links
>
> and other properties. Plus, we could lose precision by doing so due to the
>
> nature of floating point math.
>
>
When you insert a brand new node, don't those same children objects
>
need to be hooked up and have their properties set?
>
>
If this case never arises in your app right now (i.e. new nodes never
>
have children already or some such constraint), then consider that if
>
you support AppleScript for this part of your model that scripters are
>
going to expect to be able to detach, munge, and reattach objects in
>
other places, and that the built in Cocoa AppleScript support is going
>
to make this very trivial for you to support if you can just figure out
>
how to handle node insertions with child objects in a general way.
>
>
All that having been said, I do know what you are getting at here, and
>
it sounds like a pain in the **** to get right.
I definitely think we support things like insertions and deletions in a
general way. New nodes get default properties and become first class list
citizens right away, and orphaned nodes get moved to designated holding
places for later repositioning by the user. It's just the inter-object
dependencies that create the undo problems because of the complex linkages.
I sincerely appreciate the time and depth you spend responding to these
issues. Your thoughts will definitely help me think through things from an
altered viewpoint with a clearer definition of the concepts.
Thanks,
Brock
----- industrial design @ www.bergdesign.com ------
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.