[Date Prev][Date Next][Subject Prev][Subject Next][ Date Index][ Subject Index]

Re: Programming challenge: Undo




Thoughts, anyone?
As noted, logic is the key. Undo isn't easy - - I give as an example a program I use almost daily, Fontlab, which has extremely poor undo. Robert, you give as an example of something difficult to achieve the undoing of a sort command. Yet this is something all modern WPs can do. So how on earth do they do it? As you have noted, reversing the _logic_ of a command is impossible. Clearly, then, keeping a log of commands or keystrokes is not the answer. It looks like the answer -- which I imagine cannot be achieved by an external program writable even by such geniuses as Carl and Robert -- is that the program must know the entire state of a file at any given point. Robert, you state,
The only foolproof way to UnDo in XyWrite is to create multiple levels of "snapshots" --
and I wonder if this isn't, logically, the way it actually is done in WP programs? Or maybe there's a combination of approaches, to save memory and time? For example, whilst you are just inputting text, the program can simply record keystrokes. But when something drastic, like a sort command is invoked (or even a CH), then the program does have to have a way of recording its states before and after the command. Perhaps temporary files are written either to memory or disk? A great deal of the reason _why_ other programs are so slow may be just because they do have to record these states. Some of these issues (not directly applicable to XyWrite) are discussed here http://www.devsource.com/c/a/Using-VS/Implementing-a-Graphics-Undo-Command-with-the-Stack-Class/ Another bit of wisdom (all of this from googling 'programming an undo command') is 'The principle of Undo is straightforward - whenever we do anything to change the state of the data model, the previous state is recorded so it can be put back. We can record this previous state in different ways, either just record the whole state, or parts of it along with tags to tell us what was changed, or we can record actions and perform the opposite action to implement Undo. We'll be using a combination of these things. Cocoa automatically combines several undoable "recordings" into one Undoable action for each event, which really makes life very simple for us - we simply need to make sure the recording happens at each editable point of interest. ' 'Editable points of interest' is a tough one! The most depressing statement is, 'Usually, adding Undo as an afterthought is not a good idea - you need to design your application from the ground up to cope with the undo task.' So, very primitively, for XyWrite, this would be my suggestion. We have to record every state after a 'point of interest' - - and let's for the sake of argument, assume that 'point of interest' is even a single keystroke of text input, though ideally it should be a bit more elegant than that. We know we can't record the state of the file in memory unless we rewrite the program, and I assume that option is closed to us. That means the states have to be saved as temporary files. And it simply means that every time we press undo, our files is replaced by the previously saved state. I imagine it's possible that the time lag shouldn't be too great, provided files are reasonably small (by small I mean under 64K). Let's for the time being give up on 'points of interest' and simply assume that everything we do - - even typing a single letter - - is a point of interest. Unless, Robert, it's easy enough to distinguish any discrete event, solely of text typing, no matter how long, as a single point of interest. Or we could look at MSW and WP to see how they do it, for better or worse. That seems to me something you could do without too much effort. The only question is can it be done fast enough to be scarcely noticeable to the user? And let's look at how great the pauses are for substantial undos in an MSW document. I have a feeling a Xy-driven snapshot could actually be faster in _some_ circumstances. Ideally, then, the logic would be something like this: As long as the user is only typing unformatted plain text, record his keystrokes into memory, and when memory runs out, to disk. When the user does anything else, save the file to a temporary file. When undo is invoked, either reverse the keystrokes, or sequentially return the file to one of its previous states using the temporary files that have been saved. IF something like this were followed, then 'recording the keystrokes into memory' would work even for expanded view when a formatting command was being manually edited, n'est-ce-pas?