Newsgroups: rec.arts.int-fiction
Path: news.duke.edu!newsgate.duke.edu!nntp-out.monmouth.com!newspeer.monmouth.com!news.maxwell.syr.edu!arclight.uoregon.edu!news.tufts.edu!blanket.mitre.org!world!buzzard
From: buzzard@world.std.com (Sean T Barrett)
Subject: Re: [inform] conversation menus
Message-ID: <G69B9I.CDD@world.std.com>
Date: Thu, 28 Dec 2000 02:36:54 GMT
References: <slrn94ithq.12i.cerutti@localhost.localdomain> <20001227113214.10677.00000020@ng-cl1.aol.com> <92dan7$4bs$1@news5.svr.pol.co.uk>
Organization: The World Public Access UNIX, Brookline, MA
Lines: 61
Xref: news.duke.edu rec.arts.int-fiction:81712

Jon Ingold <ji207@cam.ac.uk> wrote:
>OKB -- not okblacke <brenbarn@aol.comRemove> wrote:
>>I will try.  It's not as simple as making it use up a turn, though,
>>so it may take me a while.
>
>Yeah, it is - just put in @save_undo somewhere relevant. I think

Consider the following to be documentation for what the Inform libs do
(since the existing docs just helpfully say "! Undo handling!"):

The problem is that if you only have one level of undo saving,
there's a bit of trickiness; if you do it in the following order:

   process previous command
   save_undo
   get user input
   process this command

then when the user tries to UNDO, the undo just undoes the typing
in of the command UNDO itself, and doesn't go anywhere.

On the other hand, if you

   process previous command
   get user input
   save_undo
   process the current command

then when you type "UNDO", it undoes to right after you typed
the command--and you immediately retype the previous
command, and sit in an infinite loop.  So you have to refine
it to

   process previous command
   get user input
   if it's UNDO, process it
   save_undo
   process the current command

Now, if you carry that out as written, you'll successfully UNDO
the previous command... and then immediately re-execute it, because
the previous save_undo was right after typing the command, when
we were about to carry it out; so you have to refine it to

   process previous command
   get user input
   if it's UNDO, process it
   save_undo
   if return code indicates we just restored, jump back to 'get user input'
   process the current command

It's not that many lines of code once you understand what's going
on--although I found it easier to figure it out in the abstract and
then verify that the Inform code had that form, rather than try to
guess it from the code, since it's not apparent from the code what
problems are being avoided.

SeanB
(The easier solution is to get an interpreter that supports multiple
levels of undo, and restore back two levels at a time; I leave the
detailed analysis to the interested reader, all one of you.)
