[Date Prev][Date Next][Subject Prev][Subject Next][
Date Index][
Subject Index]
Re: Programming challenge: Undo
- Subject: Re: Programming challenge: Undo
- From: Bill Troop billtroop@xxxxxxxx
- Date: Sat, 28 Jun 2008 00:20:53 +0100
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?