From: Erik V. <eri...@hc...> - 2006-07-17 20:23:57
|
Please also keep in mind, that some actions sometimes have side effects of a different nature. For instance, buying the first 4-train rusts all 2-trains. Undoing this buy also must move all these 2-trains back from the bit bucket (actually a Bank portfolio named scrapHeap) to the companies that last owned these. All these side effects must be done and undone as one action! It is not practical to define separate action classes for each possible combination of direct and indirect effects. It is much easier to work with very simple "movements" or whatever you would like to call these subactions. So I would propose: - An Action class, with do() and undo() methods, containing an ArrayList of Move objects. - An abtract Move class, which is the parent of all concrete Moves. - A bunch of XxxMove class, e.g. CashMove, TileMove, CertificateMove etc., each of which represents a specific type of minimal change. Each of the Move objects would also have do() and undo() methods, undo() being identical to do() with to and from swapped. Action.do() would call the do() method of each of the contained Move objects. Similar with undo. Erik. > -----Original Message----- > From: rai...@li... > [mailto:rai...@li...] On Behalf > Of brett lentz > Sent: 17 July 2006 20:44 > To: Development list for Rails: an 18xx game > Subject: Re: [Rails-devel] Undo / Redo design > > I was just thinking, that there's another option that exists. > > I'm thinking that it probably will require more work than the other > options, but it may be beneficial for us to do it because of the > advantages in simplifying some of the complexity of the application. > > We can define a parent object (Action) and/or interface (Actionable) > for our model objects to inherit from. > > Each object then, inherits a basic Do and Undo methods that can be > overridden when needed. For classes that do more than one thing, the > Do method can take the name of the action to take, and call the > associated methods that will take the desired action. > > Then, the UI code can be reworked to call these Do and Undo methods > and we can make all other methods private to prevent them from being > called directly. > > >From there, we can create a stack and assure that each Do method adds > its parent object to the stack. This makes Undoing a matter of popping > the object off the stack and calling the Undo method. Any calling > parameters can be accessed via an array held by the object. > > > ---Brett > > On 7/17/06, Erik Vos <eri...@hc...> wrote: > > I have also thought about this subject in the past weeks. > > > > Usually an action falls apart in several sub-action > > (which I tend to call moves). An Action can contain any > > number of moves; the determining factor is which combination > > of moves constitute an "atomic" action, i.e. a series of > > moves (changes) that must be executed and possibly undone > as a whole. > > > > For instance, selling a share involves at least: > > 1. The movement of a certificate from a player's portfolio > > to the Bank Pool (another rportfolio), > > 2. The movement of some cash from the Bank to the selling > > player (both are CashHolders). > > 3. A price drop, accompanied by the movement of the > > company's token on the Stock Chart. > > > > One could express this in XML as follows (this does not mean > > that I want to store the Undo stack in that way, although > > it is an option): > > <Action> > > <MoveCertificate company=PRR seqno=2 from=Player-1 to=Pool/> > > <MoveCash amount=67 from=bank to=Player-1/> > > <MovePrice company=PRR from=G6 to=G7/> > > </Action> > > > > For many type of actions this is easy to implement, as many > > movements already exist in much this way in the existing code > > (see for instance Bank.transferCash() and > Portfolio.transferCertificate()). > > Of course, it becomes tricky when state changes enter the picture. > > For instance, a just floated company must be unfloated in an Undo, > > and such an activity does not yet exist. > > > > I am thinking to build up an Action gradually. > > As soon as the user's request has been validated in StockRound or > > OperationRound, Action.start() is called, which creates a > new (empty) > > Action object. > > Then the changes are executed, each being registered in the > > Action object as additional moves, > > e.g. with Action.add(new MoveCash (...)). > > Finally Action.end() is called, closing the action (and perhaps > > executing it, see below). > > > > Action.undo() should then undo the last action. > > > > Stacking can be easily added this way. > > > > One main decision to take is whether the changes should be executed > > parallel to creating the Action object (so that the existing code > > remains much the same), or that it is the Action object that, > > when finished, actually performs the changes. > > > > Perhaps the latter option is better, as it enforces developers > > to implement all changes, including state changes, in a > symmetric way. > > > > I think this is a similar (or perhaps the same) choice as you > > have presented below. > > > > Erik. > > > > > > > -----Original Message----- > > > From: rai...@li... > > > [mailto:rai...@li...] On Behalf > > > Of brett lentz > > > Sent: 17 July 2006 07:31 > > > To: Development list for Rails: an 18xx game > > > Subject: [Rails-devel] Undo / Redo design > > > > > > I've been thinking about how to approach implementing Undo/Redo. > > > > > > It seems to me that there are two basic strategies that we > > > can attempt. > > > > > > In each of them, we need to create a stack to store > actions. Then, we > > > can place the stack in front of or after the code to execute the > > > action. > > > > > > The basic flow would look something like this: > > > > > > Stack before Action (Stack as EventHandler): > > > 1. Stack object receives call from UI to take an action. > > > 2. Stack stores action taken > > > 3. Stack object calls model object to resolve action. > > > > > > Stack after Action (Stack as a Listener): > > > 1. Model code receives call to act. > > > 2. Model resolves action > > > 3. Model notifies Stack object of action just taken. > > > > > > > > > I haven't really done much of an analysis of which > approach would be > > > more work or have additional implications. There also > could be other > > > approaches I haven't thought of, as well. > > > > > > What are your thoughts on this? Is there a solution with an > > > obvious advantage? > > > > > > > > > ----Brett. > > > > > -------------------------------------------------------------- > ----------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the > chance to share your > opinions on IT & business topics through brief surveys -- and > earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge > &CID=DEVDEV > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > > |