标签云

微信群

扫码加入我们

WeChat QR Code

I'm writing a structural modeling tool for a civil enginering application. I have one huge model class representing the entire building, which include collections of nodes, line elements, loads, etc. which are also custom classes.

I have already coded an undo engine which saves a deep-copy after each modification to the model. Now I started thinking if I could have coded differently. Instead of saving the deep-copies, I could perhaps save a list of each modifier action with a corresponding reverse modifier. So that I could apply the reverse modifiers to the current model to undo, or the modifiers to redo.

I can imagine how you would carry out simple commands that change object properties, etc. But how about complex commands? Like inserting new node objects to the model and adding some line objects which keep references to the new nodes.

How would one go about implementing that?


If I add the comment "Undo Algorthim" will that make it so I can search "Undo Algorithm" and find this? That's what I searched for and I found something closed as a duplicate.

2018年08月16日17分12秒

hay,I also want to develope undo/redo in the application we are developing.We use QT4 framework and need to have many complex undo/redo actions..I was wondering , have you succeed using Command-Pattern ?

2018年08月16日17分12秒

umanga: It worked but it wasn't easy. The hardest part was keeping track of references. For example, when a Frame object is deleted, its child objects: Nodes, Loads acting on it and many other user assignments needed to be kept to be reinserted when undone. But some of these child objects were shared with other objects, and undo/redo logic became quite complex. If the model wasn't that large, I would keep the memento approach; it is much easier to implement.

2018年08月17日17分12秒

this is a fun problem to work on, think about how source code repos do it, like svn (they keep the diffs between commits).

2018年08月17日17分12秒

This is basically how the undo engine in Cocoa, NSUndoManager, works.

2018年08月17日17分12秒

If you use a database (eg sqlite) as your file format this can be almost automatic

2018年08月17日17分12秒

If you augment this by tracking dependencies introduced by changes to the model, then you could potentially have an undo tree system (i.e. if I change the width of a girder, then go do some work on a separate component, I can come back and undo the girder changes without losing the other stuff). The UI for that might be a little unwieldy but it would be much more powerful than a traditional linear undo.

2018年08月17日17分12秒

Can you explain this id's vs pointers idea more? Surely a pointer/memory address works just as well as id?

2018年08月16日17分12秒

Not really, this addresses his initial approach. He's asking for an alternative approach. The initial being storing the full state for each step while the latter being storing only the "diffs".

2018年08月16日17分12秒

I’ve never thought of paste as cut^-1.

2018年08月16日17分12秒

Actually, the Paint.NET code is no longer available, but you can get the forked code.google.com/p/paint-mono

2018年08月17日17分12秒

What you described looks more like a Command than a Memento.

2018年08月17日17分12秒

What would you put in the deque?

2018年08月17日17分12秒

In my case I put the current state of the operations I wanted undo/redo functionality for. By having two deques (undo/redo) i do undo on the undo queue (pop first item) and insert it into the redo dequeue. If the number of items in the dequeues exceed the prefered size i pop an item of the tail.

2018年08月16日17分12秒

What you describe actually IS a design pattern :). The problem with this approach is when your state takes a lot of memory - keeping several dozens of state version then becomes unpractical or even impossible.

2018年08月17日17分12秒

This sounds increasingly unworkable as the size of your model grows.

2018年08月17日17分12秒

In what way? This approach keeps working without changes as new "things" are added to each object. Performance could be an issue as the serialized form of the objects grows in size - but this hasn't been a major problem. The system has been under continuous development for 20+ years and is in use by 1000s of users.

2018年08月17日17分12秒

Please post your comments as answer only if you are confident to provide solutions! Otherwise prefer to post it as comment under the question! (if it doesn't allow to do so now! please wait till you get good reputation)

2018年08月17日17分12秒