From: Stefan F. <ste...@we...> - 2010-08-16 19:45:23
|
A rather longish discussion of implementation details to follow. Mainly information for Erik. Stefan A side-effect of the new game history is that it allows to jump around between very different game states, switching round types and phases on the fly. This acts as a advanced test on the undo mechanism and overall it works very well. However there are still some bugs to discover, which might also act as examples to avoid confusing the undo/redo mechanism: * The toolTip on hexes was not updated correctly after undo/redos (still showing the tile information from the previous state), as the update was controlled only by the tile/token lay UI classes and not the game backend. I shortly considered a ToolTipModel approach, but I realized that is much easier to update the toolTip at the time it is requested by the user. I would still like to move the code to create the toolTip string from the UI GUIHex class to the game MapHex class to reduce the amount of processing and calls to the game classes from the UI class. Or is there a reason to avoid that, Erik? It seems to me that now all UI elements update correctly after undo (I recently added a PresidentModel to update the president column). * A more subtle problem arose from a 18EU test: After going back from a major turns to a minor ones during the green phase, the minor was suddenly allowed to lay a green tile. This occured as the tileLayPerColour state change triggers a call to the operatingCompany variable inside the OperatingRound instance. This variable itself however is not a state variable itself, but gets only initialized from the state variable operatingCompanyObject at the begin of the companies' action generation. Thus during the undo Rails assume that the tileLayPerColour request is still for the major company, as the operatingRound is not updated. I admit that I have introduced the operatingCompanyObject myself and did not think about this problem at that time: The lesson to learn here is to strongly avoid working with non-state variables, which simply contain a reference to a state variable. This is an wide open door for bugs & troubles a long time later. Either use the state variable directly or encapsulate it to a method call, if the state mechanism seems to unwieldy. |
From: Erik V. <eri...@xs...> - 2010-08-16 20:48:08
|
Stefan, I'll come back to your remarks later this week. I do have thoughts on these matters, but no time right now. Erik. -----Original Message----- From: Stefan Frey [mailto:ste...@we...] Sent: Monday 16 August 2010 21:46 To: 'Development list for Rails: an 18xx game' Subject: [Rails-devel] Some (multi-)undo related bugs A rather longish discussion of implementation details to follow. Mainly information for Erik. Stefan A side-effect of the new game history is that it allows to jump around between very different game states, switching round types and phases on the fly. This acts as a advanced test on the undo mechanism and overall it works very well. However there are still some bugs to discover, which might also act as examples to avoid confusing the undo/redo mechanism: * The toolTip on hexes was not updated correctly after undo/redos (still showing the tile information from the previous state), as the update was controlled only by the tile/token lay UI classes and not the game backend. I shortly considered a ToolTipModel approach, but I realized that is much easier to update the toolTip at the time it is requested by the user. I would still like to move the code to create the toolTip string from the UI GUIHex class to the game MapHex class to reduce the amount of processing and calls to the game classes from the UI class. Or is there a reason to avoid that, Erik? It seems to me that now all UI elements update correctly after undo (I recently added a PresidentModel to update the president column). * A more subtle problem arose from a 18EU test: After going back from a major turns to a minor ones during the green phase, the minor was suddenly allowed to lay a green tile. This occured as the tileLayPerColour state change triggers a call to the operatingCompany variable inside the OperatingRound instance. This variable itself however is not a state variable itself, but gets only initialized from the state variable operatingCompanyObject at the begin of the companies' action generation. Thus during the undo Rails assume that the tileLayPerColour request is still for the major company, as the operatingRound is not updated. I admit that I have introduced the operatingCompanyObject myself and did not think about this problem at that time: The lesson to learn here is to strongly avoid working with non-state variables, which simply contain a reference to a state variable. This is an wide open door for bugs & troubles a long time later. Either use the state variable directly or encapsulate it to a method call, if the state mechanism seems to unwieldy. ---------------------------------------------------------------------------- -- This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ Rails-devel mailing list Rai...@li... https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Erik V. <eri...@xs...> - 2010-08-18 21:06:54
|
* The toolTip on hexes was not updated correctly after undo/redos (still showing the tile information from the previous state), as the update was controlled only by the tile/token lay UI classes and not the game backend. I shortly considered a ToolTipModel approach, but I realized that is much easier to update the toolTip at the time it is requested by the user. I would still like to move the code to create the toolTip string from the UI GUIHex class to the game MapHex class to reduce the amount of processing and calls to the game classes from the UI class. Or is there a reason to avoid that, Erik? [EV] Let me restate the long-term architectural goal (which surely is no news to you): that one day Rails should support client-server operation, where one client per player communicates real-time with a central server over the Internet. Although we are not very close to reaching this goal, I always use it as a background for any architectural decisions. I want to work towards it, not away from it. In this concept, the client (UI) can obtain any info it needs for display in three different ways: (1) All static info can be obtained from the objects after these have been initialised as is done currently. This occurs independently in both client and server. (IIRC Brett once made a case to push all static info from server to client as well as the dynamic info mentioned below. I would that cosnsider that a more extreme vision than mine, and certainly possible, but it'll probably be a further development). Any dynamic (state) info is not directly accessible to the client. As far as the client needs it for display, it can get such info in two ways: (2) By having dynamic info be pushed from the server to the client (by sending that info to connected clients, or queueing it for disconnected clients). This should happen with all information that must be displayed by all clients alike: tiles, tokens, money, shares, messages etc. Basically this amounts to all dynamic info that the GUI needs. This server push has already been implemented for a large part of that info, but certainly not yet for all of it. (3) By having dynamic info be pulled by the client from the server. Currently this is done in many cases by direct server method calls, as Rails originally did for all such info. I think we should continue to get away from that. Network latency and the need to keep all clients on the same footing are just two reasons why I find this unattractive. We might encounter exceptional cases that where this approach would be a good solution, but I don't think there will be many such cases. -- What does this mean for the tooltips? Once the UI knows which tiles and tokens are laid in what locations and positions, almost all tooltip info is static and can be composed from locally available data as in approach (1). I think the only missing bit is the current phase (for the offboard revenue values). Getting to know about tiles and tokens is a bit tricky. Tile info is already pushed via approach (2) (see GUIHex.update()). This is not the case for tokens yet, for which the server is pulled (3) when a tile is (re-)drawn (see, for instance, GUIHex.paintStationTokens()). The latter process obviously needs to be replaced by a server-push driven one (2). The current phase is currently also pulled (3), but, as all clients need it, it will also have to be server-pushed (2). We probably need a phase model. My conclusion is, that in the end it will be possible to compose the tooltips in the UI only (1), and that there is no real need to involve the server. But to get the tooltips right now, I concur with your proposal that tooltips can best be created when requested by the user. For now it will be acceptable to call the server, if possible via a common interface that is also used by the drawing code. As said, later on all info will be locally available after being pushed by the server. Other approaches are feasible. In (2) the tooltips would be composed in the server, and pushed by MapHex on any change. The catch is, that we should be careful not to oversee cases when the text must change: all such cases should trigger all relevant MapHex models to update their views. That's added complexity I'd rather avoid. In this particular case, even method (3) might be an option, because tooltips only need to be displayed on request. However, I fear that the slower tooltip appearance (because of latency) could be a bit annoying. I don't think we should go this way. My opinion therefore is, that we should leave tooltip composition in the UI (but fix it as discussed). -- A separate issue is, that the tooltips currently aren't multi-lingual. IMO that should change. -- Talking about internet play and multi-linguality: I envisage that clients playing the same game could use different languages. This would mean, that all multi-linguality must ultimately be achieved in the client/UI anyway, not in the server/game-engine. Each message will then be pushed as a keyword with its parameter values rather than as full text. -- Sorry that this response to only one of Stefan's questions was even longer than his whole message. But in any case now you all know what I might (or might not) find myself working on after I have retired next year, if not implementing new 18xx games, or doing other interesting things.... Erik. |
From: Stefan F. <ste...@we...> - 2010-08-18 21:52:30
|
Erik: thanks for outlining your approach. What makes things difficult to discuss, but easier to implement is the fact, that Rails has an additional layer of explicit models for the UI, which transform the game elements in something more digestible for the Take the example of shares, for which the ShareModel combines the information of the certificate portfolios. Something similar would be a ToolTipModel that generates toolTip String from the deeper game model elements. This was my motiviation to suggest the move of the generation of the ToolTip text to the game(.model) classes. I am very much agnostic, how the information is passed around between client/server model/UI, any of your solutions is a valid one. In the case of ToolTip it seems to me that the pull approach is efficient. One could even start pulling the data as soon as a user hoovers over a hex, the ToolTip display is already delayed by definition. My vision for online play currently is not a split in remote clients and a centralized server, but rather have each player a client/server combination locally (similar to what we have now) and merely pass around the actions between the server instances. Each client than still gets update from the local server instance, thus keeping network traffic at a minimum. My current idea is to use the XMPP(rotocol), better known as Jabber, which allows to pass around serialized objects or xml/json messages with existing Java libraries (e.g. Smack). This would strongly leverage on existing infrastructure. Again a rather long text for such a simple fix ;-) Stefan On Wednesday, August 18, 2010 11:06:49 pm Erik Vos wrote: > * The toolTip on hexes was not updated correctly after undo/redos (still > showing the tile information from the previous state), as the update was > controlled only by the tile/token lay UI classes and not the game backend. > I shortly considered a ToolTipModel approach, but I realized that is much > easier to update the toolTip at the time it is requested by the user. > I would still like to move the code to create the toolTip string from the > UI > > GUIHex class to the game MapHex class to reduce the amount of processing > and > > calls to the game classes from the UI class. > Or is there a reason to avoid that, Erik? > > [EV] Let me restate the long-term architectural goal (which surely is no > news to you): that one day Rails should support client-server operation, > where one client per player communicates real-time with a central server > over the Internet. Although we are not very close to reaching this goal, I > always use it as a background for any architectural decisions. I want to > work towards it, not away from it. > > In this concept, the client (UI) can obtain any info it needs for display > in three different ways: > > (1) All static info can be obtained from the objects after these have been > initialised as is done currently. This occurs independently in both client > and server. > (IIRC Brett once made a case to push all static info from server to client > as well as the dynamic info mentioned below. I would that cosnsider that a > more extreme vision than mine, and certainly possible, but it'll probably > be a further development). > > Any dynamic (state) info is not directly accessible to the client. As far > as the client needs it for display, it can get such info in two ways: > > (2) By having dynamic info be pushed from the server to the client (by > sending that info to connected clients, or queueing it for disconnected > clients). This should happen with all information that must be displayed by > all clients alike: tiles, tokens, money, shares, messages etc. Basically > this amounts to all dynamic info that the GUI needs. This server push has > already been implemented for a large part of that info, but certainly not > yet for all of it. > > (3) By having dynamic info be pulled by the client from the server. > Currently this is done in many cases by direct server method calls, as > Rails originally did for all such info. I think we should continue to get > away from that. Network latency and the need to keep all clients on the > same footing are just two reasons why I find this unattractive. We might > encounter exceptional cases that where this approach would be a good > solution, but I don't think there will be many such cases. > > -- > > What does this mean for the tooltips? > > Once the UI knows which tiles and tokens are laid in what locations and > positions, almost all tooltip info is static and can be composed from > locally available data as in approach (1). I think the only missing bit is > the current phase (for the offboard revenue values). > > Getting to know about tiles and tokens is a bit tricky. Tile info is > already pushed via approach (2) (see GUIHex.update()). This is not the > case for tokens yet, for which the server is pulled (3) when a tile is > (re-)drawn (see, for instance, GUIHex.paintStationTokens()). The latter > process obviously needs to be replaced by a server-push driven one (2). > > The current phase is currently also pulled (3), but, as all clients need > it, it will also have to be server-pushed (2). We probably need a phase > model. > > My conclusion is, that in the end it will be possible to compose the > tooltips in the UI only (1), and that there is no real need to involve the > server. But to get the tooltips right now, I concur with your proposal that > tooltips can best be created when requested by the user. For now it will be > acceptable to call the server, if possible via a common interface that is > also used by the drawing code. As said, later on all info will be locally > available after being pushed by the server. > > Other approaches are feasible. In (2) the tooltips would be composed in the > server, and pushed by MapHex on any change. The catch is, that we should be > careful not to oversee cases when the text must change: all such cases > should trigger all relevant MapHex models to update their views. That's > added complexity I'd rather avoid. > > In this particular case, even method (3) might be an option, because > tooltips only need to be displayed on request. However, I fear that the > slower tooltip appearance (because of latency) could be a bit annoying. I > don't think we should go this way. > > My opinion therefore is, that we should leave tooltip composition in the UI > (but fix it as discussed). |
From: Erik V. <eri...@xs...> - 2010-08-19 20:19:45
|
Stefan, I remember Brett also once proposed Jabber to be used in the way you suggest. That certainly seems a viable solution to me, and much easier to achieve than mine; whether or not internet-play development would end there, I don't know. In any case, in your approach it doesn't matter much in which way the UI gets updated. And, as I already said, the tooltips can be done in any way. Although the current Rails Model/View implementation allows pulling, I don't see the added value of it when only used that way. Its strength is enabling the push through the Observable/Observer pattern. For pulling, a direct (or, perhaps in the future: remote) method call works just as well. In other words, I only see value in a separate ToolTipModel if the tooltips are pushed. And even then, why not have the existing MapHex model do the same job? It's already there, waiting for you to be enhanced... Just my ideas, all this; I don't want to keep you from doing Good Things your way. However, discussions like these, which I very much appreciate, might help to prevent us drifting apart too much... :-) Erik. -----Original Message----- From: Stefan Frey [mailto:ste...@we...] Sent: Wednesday 18 August 2010 23:52 To: Development list for Rails: an 18xx game Subject: Re: [Rails-devel] Some (multi-)undo related bugs Erik: thanks for outlining your approach. What makes things difficult to discuss, but easier to implement is the fact, that Rails has an additional layer of explicit models for the UI, which transform the game elements in something more digestible for the Take the example of shares, for which the ShareModel combines the information of the certificate portfolios. Something similar would be a ToolTipModel that generates toolTip String from the deeper game model elements. This was my motiviation to suggest the move of the generation of the ToolTip text to the game(.model) classes. I am very much agnostic, how the information is passed around between client/server model/UI, any of your solutions is a valid one. In the case of ToolTip it seems to me that the pull approach is efficient. One could even start pulling the data as soon as a user hoovers over a hex, the ToolTip display is already delayed by definition. My vision for online play currently is not a split in remote clients and a centralized server, but rather have each player a client/server combination locally (similar to what we have now) and merely pass around the actions between the server instances. Each client than still gets update from the local server instance, thus keeping network traffic at a minimum. My current idea is to use the XMPP(rotocol), better known as Jabber, which allows to pass around serialized objects or xml/json messages with existing Java libraries (e.g. Smack). This would strongly leverage on existing infrastructure. Again a rather long text for such a simple fix ;-) Stefan On Wednesday, August 18, 2010 11:06:49 pm Erik Vos wrote: > * The toolTip on hexes was not updated correctly after undo/redos (still > showing the tile information from the previous state), as the update was > controlled only by the tile/token lay UI classes and not the game backend. > I shortly considered a ToolTipModel approach, but I realized that is much > easier to update the toolTip at the time it is requested by the user. > I would still like to move the code to create the toolTip string from the > UI > > GUIHex class to the game MapHex class to reduce the amount of processing > and > > calls to the game classes from the UI class. > Or is there a reason to avoid that, Erik? > > [EV] Let me restate the long-term architectural goal (which surely is no > news to you): that one day Rails should support client-server operation, > where one client per player communicates real-time with a central server > over the Internet. Although we are not very close to reaching this goal, I > always use it as a background for any architectural decisions. I want to > work towards it, not away from it. > > In this concept, the client (UI) can obtain any info it needs for display > in three different ways: > > (1) All static info can be obtained from the objects after these have been > initialised as is done currently. This occurs independently in both client > and server. > (IIRC Brett once made a case to push all static info from server to client > as well as the dynamic info mentioned below. I would that cosnsider that a > more extreme vision than mine, and certainly possible, but it'll probably > be a further development). > > Any dynamic (state) info is not directly accessible to the client. As far > as the client needs it for display, it can get such info in two ways: > > (2) By having dynamic info be pushed from the server to the client (by > sending that info to connected clients, or queueing it for disconnected > clients). This should happen with all information that must be displayed by > all clients alike: tiles, tokens, money, shares, messages etc. Basically > this amounts to all dynamic info that the GUI needs. This server push has > already been implemented for a large part of that info, but certainly not > yet for all of it. > > (3) By having dynamic info be pulled by the client from the server. > Currently this is done in many cases by direct server method calls, as > Rails originally did for all such info. I think we should continue to get > away from that. Network latency and the need to keep all clients on the > same footing are just two reasons why I find this unattractive. We might > encounter exceptional cases that where this approach would be a good > solution, but I don't think there will be many such cases. > > -- > > What does this mean for the tooltips? > > Once the UI knows which tiles and tokens are laid in what locations and > positions, almost all tooltip info is static and can be composed from > locally available data as in approach (1). I think the only missing bit is > the current phase (for the offboard revenue values). > > Getting to know about tiles and tokens is a bit tricky. Tile info is > already pushed via approach (2) (see GUIHex.update()). This is not the > case for tokens yet, for which the server is pulled (3) when a tile is > (re-)drawn (see, for instance, GUIHex.paintStationTokens()). The latter > process obviously needs to be replaced by a server-push driven one (2). > > The current phase is currently also pulled (3), but, as all clients need > it, it will also have to be server-pushed (2). We probably need a phase > model. > > My conclusion is, that in the end it will be possible to compose the > tooltips in the UI only (1), and that there is no real need to involve the > server. But to get the tooltips right now, I concur with your proposal that > tooltips can best be created when requested by the user. For now it will be > acceptable to call the server, if possible via a common interface that is > also used by the drawing code. As said, later on all info will be locally > available after being pushed by the server. > > Other approaches are feasible. In (2) the tooltips would be composed in the > server, and pushed by MapHex on any change. The catch is, that we should be > careful not to oversee cases when the text must change: all such cases > should trigger all relevant MapHex models to update their views. That's > added complexity I'd rather avoid. > > In this particular case, even method (3) might be an option, because > tooltips only need to be displayed on request. However, I fear that the > slower tooltip appearance (because of latency) could be a bit annoying. I > don't think we should go this way. > > My opinion therefore is, that we should leave tooltip composition in the UI > (but fix it as discussed). ---------------------------------------------------------------------------- -- This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ Rails-devel mailing list Rai...@li... https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Stefan F. <ste...@we...> - 2010-08-25 21:42:55
|
Erik: other implementation details follow here as they arose from to the topic in the subject: I have added two new state classes: ArrayListState and HashMapState, that create ModelObjects, which use the already defined Move classes for changes of ArrayLists and HashMaps. It basically wraps the ModelObject/State around standard ArrayLists and HashMaps and uses the standard method names to manipulate them. In principle it would be possible to fully implement the Map/List interfaces, but I was too lazy to write all required methods for that. My reason for adding those is that at least for the approach above protects against accidentally using the non-move methods on list or maps, which are in fact stateful and thus require the moves instead. And I still prefer using the standard syntax stateList.add(object) instead of new AddToList("NameOfList", stateList, object). And it allows to create more complicated operations using the atomic moves (for example addAll or initFromMap). It is possible to retrieve the wrapped list/map as an unmodifiable view. This allowed fixing the opertingCompanies bug in 1856 and the tilesPerColour problem in 18EU. Currently they do not inherit from neither ModelObject/State as the current usage has not required them to do so. But it is possible to do so, but I would prefer to inherit from ModelObject directly. If you do not mind I would like to add an according HashSetState class and replace BooleanState, IntegerState and StringState with more specialized versions that inherit from ModelObject instead of State and have according simple Moves (BooleanChange, IntegerChange, StringChange) and it would allow to introduce an easier syntax, for example for boolean: booleanVar.set(true) or booleanVar.set(false) and booleanVar.is() or booleanVar.isNot() This would also allow to deprecate (and remove later) the State class,as there is already a replacement available with GenericState. All those changes make the StateI interface unnecessary. It could still be used as a mere marker interface or have the getName() function at most. Stefan On Monday, August 16, 2010 10:48:07 pm Erik Vos wrote: > Stefan, > > I'll come back to your remarks later this week. I do have thoughts on these > matters, but no time right now. > > Erik. > > -----Original Message----- > From: Stefan Frey [mailto:ste...@we...] > Sent: Monday 16 August 2010 21:46 > To: 'Development list for Rails: an 18xx game' > Subject: [Rails-devel] Some (multi-)undo related bugs > > A rather longish discussion of implementation details to follow. Mainly > information for Erik. > Stefan > > A side-effect of the new game history is that it allows to jump around > between > very different game states, switching round types and phases on the fly. > This acts as a advanced test on the undo mechanism and overall it works > very > > well. However there are still some bugs to discover, which might also act > as > > examples to avoid confusing the undo/redo mechanism: > > * The toolTip on hexes was not updated correctly after undo/redos (still > showing the tile information from the previous state), as the update was > controlled only by the tile/token lay UI classes and not the game backend. > I shortly considered a ToolTipModel approach, but I realized that is much > easier to update the toolTip at the time it is requested by the user. > I would still like to move the code to create the toolTip string from the > UI > > GUIHex class to the game MapHex class to reduce the amount of processing > and > > calls to the game classes from the UI class. > Or is there a reason to avoid that, Erik? > It seems to me that now all UI elements update correctly after undo (I > recently added a PresidentModel to update the president column). > > * A more subtle problem arose from a 18EU test: After going back from a > major > turns to a minor ones during the green phase, the minor was suddenly > allowed > > to lay a green tile. > This occured as the tileLayPerColour state change triggers a call to the > operatingCompany variable inside the OperatingRound instance. This > variable > > itself however is not a state variable itself, but gets only initialized > from > the state variable operatingCompanyObject at the begin of the companies' > action generation. Thus during the undo Rails assume that the > tileLayPerColour > request is still for the major company, as the operatingRound is not > updated. > > I admit that I have introduced the operatingCompanyObject myself and did > not > > think about this problem at that time: The lesson to learn here is to > strongly > avoid working with non-state variables, which simply contain a reference to > a > state variable. This is an wide open door for bugs & troubles a long time > later. > Either use the state variable directly or encapsulate it to a method call, > if > the state mechanism seems to unwieldy. > > --------------------------------------------------------------------------- > - -- > This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel > > > --------------------------------------------------------------------------- > --- This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Erik V. <eri...@xs...> - 2010-08-26 20:37:33
|
Stefan, Since you created GenericState<>, I realized that State is redundant. My thought was (and is) that we should try to merge State and GenericState<> into State<>. That would make IntegerState etc. basically redundant, as it could be replaced by State<Integer> etc. Alternatively, if we would need the extra methods, we can also have subclasses like class IntegerState extends State<Integer> {...} where we can for instance add an add() method, and still reuse the set() and get() methods with automatic casting. No more need for intValue(). On first sight, such an approach would more appeal to me than yours, but I must admit that I have not worked it out beyond testing that the above subclassing approach works (to my surprise, I must confess). In any case, as State already extends ModelObject, we get that superclass for free. On IntegerChange etc., I don't see the added value of these new moves, if we already have ObjectChange, but perhaps I'm dumb... Here is the full code of my test classes: package rails.game.state; public class IntegerState2 extends GenericState<Integer> { public IntegerState2 (String name, int i) { super (name, i); } public IntegerState2 (String name) { super (name, 0); } public void add (int i) { set (get()+i); } } package test; import rails.game.state.IntegerState2; public class Test { public static void main(String[] args) { IntegerState2 i = new IntegerState2 ("I", 1); System.out.println(i.get()); i.set(3); System.out.println(i.get()); i.add(2); System.out.println(i.get()); } } which prints 1 3 5 Looks pretty lean to me... I'm not sure if my idea could be extended to ArrayListState<E> extends State<List<E>>, but perhaps it's worth a try... Erik. -----Original Message----- From: Stefan Frey [mailto:ste...@we...] Sent: Wednesday 25 August 2010 23:43 To: Development list for Rails: an 18xx game Subject: Re: [Rails-devel] Some (multi-)undo related bugs Erik: other implementation details follow here as they arose from to the topic in the subject: I have added two new state classes: ArrayListState and HashMapState, that create ModelObjects, which use the already defined Move classes for changes of ArrayLists and HashMaps. It basically wraps the ModelObject/State around standard ArrayLists and HashMaps and uses the standard method names to manipulate them. In principle it would be possible to fully implement the Map/List interfaces, but I was too lazy to write all required methods for that. My reason for adding those is that at least for the approach above protects against accidentally using the non-move methods on list or maps, which are in fact stateful and thus require the moves instead. And I still prefer using the standard syntax stateList.add(object) instead of new AddToList("NameOfList", stateList, object). And it allows to create more complicated operations using the atomic moves (for example addAll or initFromMap). It is possible to retrieve the wrapped list/map as an unmodifiable view. This allowed fixing the opertingCompanies bug in 1856 and the tilesPerColour problem in 18EU. Currently they do not inherit from neither ModelObject/State as the current usage has not required them to do so. But it is possible to do so, but I would prefer to inherit from ModelObject directly. If you do not mind I would like to add an according HashSetState class and replace BooleanState, IntegerState and StringState with more specialized versions that inherit from ModelObject instead of State and have according simple Moves (BooleanChange, IntegerChange, StringChange) and it would allow to introduce an easier syntax, for example for boolean: booleanVar.set(true) or booleanVar.set(false) and booleanVar.is() or booleanVar.isNot() This would also allow to deprecate (and remove later) the State class,as there is already a replacement available with GenericState. All those changes make the StateI interface unnecessary. It could still be used as a mere marker interface or have the getName() function at most. Stefan |
From: Stefan F. <ste...@we...> - 2010-08-31 22:41:59
|
Erik, I think you convinced me that there is no need to have any state classes, which do not subclass ModelObject. The increased complexity of a parallel structure clearly outweighs any performance gain. I would even go one step further: The supposed difference between state and model classes is unnecessary and I would rename all state classes to model classes: Thus instead of IntegerState we would have IntegerModel and so on. If we still have different packages, I would separate GenericModels (as e.g. IntegerModel) from RailsModels (as BaseTokensModel). I only differ in the implementation details: I would prefer to derive the specific models (as ArrayListState/Model IntegerState/Model) directly from ModelObject, as the GenericState/Model mechanism creates a new object for each change (move) of the model. My approach would reuse the existing object and the move would contain only the delta. (or for the IntegerModel: it allows to use int fields instead of Integer ones for the move and model objects). Stefan PS: In addition you convinced me that any trigger approach should work on the model/state objects directly: It should allow to build conditions in the xml files on defined state changes. (Hypothetical) Example for 1835 BA certificates: <Certificates> <Available> <Trigger="BY_fullysold" value="yes"> <Trigger="SX_fullysold" value="yes" operator="and"> </Available> </Certificates> On Thursday, August 26, 2010 10:37:20 pm Erik Vos wrote: > Stefan, > > Since you created GenericState<>, I realized that State is redundant. My > thought was (and is) that we should try to merge State and GenericState<> > into State<>. > > That would make IntegerState etc. basically redundant, as it could be > replaced by State<Integer> etc. > Alternatively, if we would need the extra methods, we can also have > subclasses like > class IntegerState extends State<Integer> {...} > where we can for instance add an add() method, and still reuse the set() > and get() methods with automatic casting. No more need for intValue(). > > On first sight, such an approach would more appeal to me than yours, but I > must admit that I have not worked it out beyond testing that the above > subclassing approach works (to my surprise, I must confess). > > In any case, as State already extends ModelObject, we get that superclass > for free. > On IntegerChange etc., I don't see the added value of these new moves, if > we already have ObjectChange, but perhaps I'm dumb... > > Here is the full code of my test classes: > > package rails.game.state; > public class IntegerState2 extends GenericState<Integer> { > public IntegerState2 (String name, int i) { > super (name, i); > } > public IntegerState2 (String name) { > super (name, 0); > } > public void add (int i) { > set (get()+i); > } > } > > package test; > import rails.game.state.IntegerState2; > public class Test { > public static void main(String[] args) { > IntegerState2 i = new IntegerState2 ("I", 1); > System.out.println(i.get()); > i.set(3); > System.out.println(i.get()); > i.add(2); > System.out.println(i.get()); > } > } > > which prints > 1 > 3 > 5 > > Looks pretty lean to me... > > I'm not sure if my idea could be extended to ArrayListState<E> extends > State<List<E>>, but perhaps it's worth a try... > > Erik. > > > -----Original Message----- > From: Stefan Frey [mailto:ste...@we...] > Sent: Wednesday 25 August 2010 23:43 > To: Development list for Rails: an 18xx game > Subject: Re: [Rails-devel] Some (multi-)undo related bugs > > Erik: > other implementation details follow here as they arose from to the topic > in > > the subject: > > I have added two new state classes: ArrayListState and HashMapState, that > create ModelObjects, which use the already defined Move classes for changes > of > ArrayLists and HashMaps. It basically wraps the ModelObject/State around > standard ArrayLists and HashMaps and uses the standard method names to > manipulate them. In principle it would be possible to fully implement the > Map/List interfaces, but I was too lazy to write all required methods for > that. > > My reason for adding those is that at least for the approach above protects > against accidentally using the non-move methods on list or maps, which are > in > fact stateful and thus require the moves instead. And I still prefer using > the > standard syntax stateList.add(object) instead of new > AddToList("NameOfList", > > stateList, object). And it allows to create more complicated operations > using > the atomic moves (for example addAll or initFromMap). It is possible to > retrieve the wrapped list/map as an unmodifiable view. > > This allowed fixing the opertingCompanies bug in 1856 and the > tilesPerColour > > problem in 18EU. > > Currently they do not inherit from neither ModelObject/State as the current > usage has not required them to do so. But it is possible to do so, but I > would > prefer to inherit from ModelObject directly. > > If you do not mind I would like to add an according HashSetState class and > replace BooleanState, IntegerState and StringState with more specialized > versions that inherit from ModelObject instead of State and have according > simple Moves (BooleanChange, IntegerChange, StringChange) and it would > allow > > to introduce an easier syntax, for example for boolean: > booleanVar.set(true) > > or booleanVar.set(false) and booleanVar.is() or booleanVar.isNot() > > This would also allow to deprecate (and remove later) the State class,as > there > is already a replacement available with GenericState. All those changes > make the StateI interface unnecessary. It could still be used as a mere > marker interface or have the getName() function at most. > Stefan > > > > --------------------------------------------------------------------------- > --- Sell apps to millions through the Intel(R) Atom(Tm) Developer Program > Be part of this innovative community and reach millions of netbook users > worldwide. Take advantage of special opportunities to increase revenue and > speed time-to-market. Join now, and jumpstart your future. > http://p.sf.net/sfu/intel-atom-d2d > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: Erik V. <eri...@xs...> - 2010-09-01 18:56:39
|
Stefan, Some comments: >I would even go one step further: The supposed difference between state and model classes is unnecessary and I would rename all state classes to model classes: Thus instead of IntegerState we would have IntegerModel and so on. If we still have different packages, I would separate GenericModels (as e.g. IntegerModel) from RailsModels (as BaseTokensModel). [EV] I think you forget that we have quite some ModelObjects that are not State objects, but only serve as Observables for the UI. Whether or not it is a good thing that these are not State objects is another matter - perhaps that needs to be reconsidered. But as long as this is the case, I would keep ModelObject and State separate, as these serve different (if often combined) purposes. (BTW It might be interesting to sort this out in more detail. For instance, I wonder why I ever have created both CashModel and MoneyModel, of which only the latter is a state object. All I remember is that I once thought to have very good reason for this difference, but it has slipped out of my mind.... Perhaps some further digging will reveal it). >I only differ in the implementation details: I would prefer to derive the specific models (as ArrayListState/Model IntegerState/Model) directly from ModelObject, as the GenericState/Model mechanism creates a new object for each change (move) of the model. [EV] That would be the case if always the superclass set() method is used, but that is of course not necessary. Subclasses can add delta methods (such as IntegerState.add() or ArrayListState.add()). We might even make subclasses smart enough to override set() to use delta actions (for instance, BooleanState would only create a new object if it is null). However, your point is well taken in that I now understand that we should not use State<Integer> to create state objects, but always use subclasses like IntegerState (extends State<Integer>). Even then I think we would still save code: (1) State and GenericState<> have merged, (2) less need for casting (e.g. no more booleanValue() etc. needed). But of course, if State<> would end up empty, or all its methods would be overridden anyway, there would be no need for it indeed. However, I would prefer to have that being the final outcome of a rationalization process rather than a starting point. I hope you understand that I'm not trying to force anything - this is just my view. If you want to go ahead with this your way - fine with me. In any case, later refactoring in either direction shouldn't be difficult. Erik. |
From: brett l. <bre...@gm...> - 2010-09-01 19:58:32
|
On Wed, Sep 1, 2010 at 11:56 AM, Erik Vos <eri...@xs...> wrote: > Stefan, > > Some comments: > >>I would even go one step further: The supposed difference between state and > > model classes is unnecessary and I would rename all state classes to model > classes: Thus instead of IntegerState we would have IntegerModel and so on. > If we still have different packages, I would separate GenericModels (as e.g. > > IntegerModel) from RailsModels (as BaseTokensModel). > > [EV] I think you forget that we have quite some ModelObjects that are not > State objects, but only serve as Observables for the UI. > Whether or not it is a good thing that these are not State objects is > another matter - perhaps that needs to be reconsidered. > But as long as this is the case, I would keep ModelObject and State > separate, as these serve different (if often combined) purposes. > Post-merge, perhaps it makes sense to have certain Model objects have an Observable property? e.g. bool isObservable = True Or, maybe it doesn't matter, and the UI simply uses the Model objects that make sense, and doesn't use the ones it doesn't need and there's really no difference between them at all. :-) > (BTW It might be interesting to sort this out in more detail. For instance, > I wonder why I ever have created both CashModel and MoneyModel, of which > only the latter is a state object. All I remember is that I once thought to > have very good reason for this difference, but it has slipped out of my > mind.... Perhaps some further digging will reveal it). > >>I only differ in the implementation details: > I would prefer to derive the specific models (as ArrayListState/Model > IntegerState/Model) directly from ModelObject, as the GenericState/Model > mechanism creates a new object for each change (move) of the model. > > [EV] That would be the case if always the superclass set() method is used, > but that is of course not necessary. Subclasses can add delta methods (such > as IntegerState.add() or ArrayListState.add()). We might even make > subclasses smart enough to override set() to use delta actions (for > instance, BooleanState would only create a new object if it is null). > > However, your point is well taken in that I now understand that we should > not use State<Integer> to create state objects, but always use subclasses > like IntegerState (extends State<Integer>). > Even then I think we would still save code: (1) State and GenericState<> > have merged, (2) less need for casting (e.g. no more booleanValue() etc. > needed). > > But of course, if State<> would end up empty, or all its methods would be > overridden anyway, there would be no need for it indeed. However, I would > prefer to have that being the final outcome of a rationalization process > rather than a starting point. > > I hope you understand that I'm not trying to force anything - this is just > my view. If you want to go ahead with this your way - fine with me. In any > case, later refactoring in either direction shouldn't be difficult. > If you want to do this before gaining complete consensus, create a branch and develop your changes in the branch. That'll make comparison easier and may help achieve consensus. :-) > Erik. > > ---Brett |
From: Stefan F. <ste...@we...> - 2010-09-01 21:41:54
|
Brett & Erik: thanks for your feedback. Some more comments below. I do not think that an (extra) branch is required for those changes now. As long as there is no agreement here, I will work on other issues first, and even if there would be a consensus, it is not that high on my priority list now. Stefan > > > > [EV] I think you forget that we have quite some ModelObjects that are not > > State objects, but only serve as Observables for the UI. > > Whether or not it is a good thing that these are not State objects is > > another matter - perhaps that needs to be reconsidered. > > But as long as this is the case, I would keep ModelObject and State > > separate, as these serve different (if often combined) purposes. > > Post-merge, perhaps it makes sense to have certain Model objects have > an Observable property? > > e.g. bool isObservable = True > > > Or, maybe it doesn't matter, and the UI simply uses the Model objects > that make sense, and doesn't use the ones it doesn't need and there's > really no difference between them at all. :-) I agree with Brett's last sentence: From my understanding (now) is that there is no inherent difference between Model and State objects, other than naming. All of them are changed (directly or indirectly via other states) by moves and have the ability to update observables. The latter usually UI elements, but also other states. I do not see any own property or behavior that is specific to the State classes. > If you want to do this before gaining complete consensus, create a > branch and develop your changes in the branch. That'll make comparison > easier and may help achieve consensus. :-) > |
From: Erik V. <eri...@xs...> - 2010-09-01 22:04:07
|
Post-merge, perhaps it makes sense to have certain Model objects have an Observable property? e.g. bool isObservable = True [EV] ModelObject extends Observable - being observable is integral to, and the sole reason for the existence of ModelObjects. State extends ModelObject - that's a bonus for State objects: that they can be observed. But not all are. So not all ModelObjects are in fact observed. Or, maybe it doesn't matter, and the UI simply uses the Model objects that make sense, and doesn't use the ones it doesn't need and there's really no difference between them at all. :-) [EV] So that's in fact already the case. But the point was, that not all ModelObjects have state, and the question is: should that change? Erik. |
From: brett l. <bre...@gm...> - 2010-09-01 22:51:12
|
On Wed, Sep 1, 2010 at 3:04 PM, Erik Vos <eri...@xs...> wrote: > Post-merge, perhaps it makes sense to have certain Model objects have > an Observable property? > > e.g. bool isObservable = True > > [EV] > ModelObject extends Observable - being observable is integral to, and the > sole reason for the existence of ModelObjects. > State extends ModelObject - that's a bonus for State objects: that they can > be observed. But not all are. So not all ModelObjects are in fact observed. > > Or, maybe it doesn't matter, and the UI simply uses the Model objects > that make sense, and doesn't use the ones it doesn't need and there's > really no difference between them at all. :-) > > [EV] So that's in fact already the case. But the point was, that not all > ModelObjects have state, and the question is: should that change? > Turn-based boardgames are effectively state machines. I'm not sure I can think of a model object that should be stateless. Certain parts of the view (in an MVC world) can and should be stateless, but the model *is* the state of the application (read: game). > Erik. > ---Brett |
From: Erik V. <eri...@xs...> - 2010-09-02 18:46:25
|
Turn-based boardgames are effectively state machines. I'm not sure I can think of a model object that should be stateless. Certain parts of the view (in an MVC world) can and should be stateless, but the model *is* the state of the application (read: game). [EV] Of course there is always some form of state behind a model, but often it is not a single state. For instance, the views that give you a list of available trains, or the player worth, or a share percentage, have models that depend on some calculated value, which is not an independent state itself. Erik. |
From: brett l. <bre...@gm...> - 2010-09-02 20:20:03
|
On Thu, Sep 2, 2010 at 11:46 AM, Erik Vos <eri...@xs...> wrote: > Turn-based boardgames are effectively state machines. I'm not sure I > can think of a model object that should be stateless. > > Certain parts of the view (in an MVC world) can and should be > stateless, but the model *is* the state of the application (read: > game). > > [EV] Of course there is always some form of state behind a model, but often > it is not a single state. For instance, the views that give you a list of > available trains, or the player worth, or a share percentage, have models > that depend on some calculated value, which is not an independent state > itself. Correct. This is where MVC tends to be an improvement to just an MV design. Typically, the controller possesses the "business rules" that derives those calculated values from the model. Originally, we started with a Model-View design. It's probably time to work on cleaning up the distinction between Model and Controller, and making that distinction to help clarify which is which. > > Erik. > ---Brett. |
From: Stefan F. <ste...@we...> - 2010-09-02 21:12:23
|
Brett & Erik: Depending on the interpretation of model and state (general idea, pattern context, Rails context) I can agree/disagree with all your statements below. Example: If model is simply the whole set of data/structure of an 18xx game, and if state is defined as something that change its structure /behavior /properties at runtime, then I disagree (think definition of tracks on tiles). If we define model as all classes that inherit ModelObject and state as above, than I easily agree. So I try to clearly identify my interpretation my take simply is: Parts of the (game) model, which change their state (as defined above) directly/indirectly, extend ModelObject. There is no substantial difference, if the UI subscribe to the object or if only other part of the (game) model. Thus I suggest do derive all three cases below from ModelObject: A) First-class model objects (have state of its own, update UI directly) B) Derived model objects (derive their state from A) or C) type objects, but update UI directly) C) State objects (have state of its own, but do not update UI directly) From my point of view the difference between A and C is irrelevant on the model (MVC context here) level, as the model should not care which elements the UI/view subscribes. The difference between B and C might be somehow more relevant, especially if the only composite information for specific UI elements. Then it would make sense to move those into a controller layer, but they could still follow the ModelObject observer pattern. Another suggestion is those objects that have a state of their owns (type A and C thus get changed by Moves) implement a Moveable interface to identify those. Stefan On Thursday, September 02, 2010 10:19:35 pm brett lentz wrote: > On Thu, Sep 2, 2010 at 11:46 AM, Erik Vos <eri...@xs...> wrote: > > Turn-based boardgames are effectively state machines. I'm not sure I > > can think of a model object that should be stateless. > > > > Certain parts of the view (in an MVC world) can and should be > > stateless, but the model *is* the state of the application (read: > > game). > > > > [EV] Of course there is always some form of state behind a model, but > > often it is not a single state. For instance, the views that give you a > > list of available trains, or the player worth, or a share percentage, > > have models that depend on some calculated value, which is not an > > independent state itself. > > Correct. This is where MVC tends to be an improvement to just an MV > design. Typically, the controller possesses the "business rules" that > derives those calculated values from the model. > > Originally, we started with a Model-View design. It's probably time to > work on cleaning up the distinction between Model and Controller, and > making that distinction to help clarify which is which. > > > Erik. > > ---Brett. > > --------------------------------------------------------------------------- > --- This SF.net Dev2Dev email is sponsored by: > > Show off your parallel programming skills. > Enter the Intel(R) Threading Challenge 2010. > http://p.sf.net/sfu/intel-thread-sfd > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel |
From: brett l. <bre...@gm...> - 2010-09-02 21:42:32
|
Stefan - I see what you're driving at, and it sounds a lot like MVC to me. ;-) So... I feel I should caveat this with the usual disclaimer: the guy writing the code, ultimately, will get to make most of these decisions. As I haven't had time to directly touch the code, I feel that yours and Erik's opinions should weigh a bit more than mine at this point. :-) That said... I think your view and mine align pretty closely. Most of my suggestion really comes down to clarifying the distinction between model and controller, and reflecting that distinction in the code's organization. To be honest, I've spent the last week at $dayjob coding a TurboGears app, which is heavily MVC structured, so this is probably influencing my perspective. Basically, the 'model' should be the current state of the game. It's stored in some sort of data structure that could translate to a database, or a segment of RAM, or a set of flat files. How it's stored isn't relevant so much as _that_ it's stored as *data*. To me, this is stuff like Company A's share price is $100, Company B has 2 5-Trains, and Company C just played Tile #7 into MapHex A5. The Controller layer receives requests from the user through the View's UI, and operates on the Model. It's the "glue" between UI and Data. Much of our game engine code could be considered "controllers". It takes the instructions from the UI, interprets the request through the game's ruleset, then applies the relevant changes to the data store to update the state of the game to reflect those changes. The View is what the user sees. It may access Model objects for read-only display purposes, but it should *not* change model objects. All changes to the model's data should route through the various Controllers because all of the logic on _how_ to update the game state should be in the controller. So... in our case, it is likely that we could further specify layers in terms of function or based on how they interconnect, but the basic design should look something like this: Game State Data -> Data storage interface -> Game Engine and other App-specific logic -> Public API -> UI. I have a feeling that it may be time to do some housekeeping and more clearly define the boundaries of each domain so that if we want to swap out the Swing UI for Web-based, or swap our current in-memory data store for a database, we can without needing to touch the other parts of the code. ---Brett. On Thu, Sep 2, 2010 at 2:12 PM, Stefan Frey <ste...@we...> wrote: > Brett & Erik: > Depending on the interpretation of model and state (general idea, pattern > context, Rails context) I can agree/disagree with all your statements below. > > Example: If model is simply the whole set of data/structure of an 18xx game, > and if state is defined as something that change its structure /behavior > /properties at runtime, then I disagree (think definition of tracks on tiles). > If we define model as all classes that inherit ModelObject and state as above, > than I easily agree. > > So I try to clearly identify my interpretation my take simply is: Parts of the > (game) model, which change their state (as defined above) directly/indirectly, > extend ModelObject. There is no substantial difference, if the UI subscribe to > the object or if only other part of the (game) model. > > Thus I suggest do derive all three cases below from ModelObject: > A) First-class model objects (have state of its own, update UI directly) > B) Derived model objects (derive their state from A) or C) type objects, but > update UI directly) > C) State objects (have state of its own, but do not update UI directly) > > >From my point of view the difference between A and C is irrelevant on the > model (MVC context here) level, as the model should not care which elements > the UI/view subscribes. > > The difference between B and C might be somehow more > relevant, especially if the only composite information for specific UI > elements. Then it would make sense to move those into a controller layer, but > they could still follow the ModelObject observer pattern. > > Another suggestion is those objects that have a state of their owns (type A > and C thus get changed by Moves) implement a Moveable interface to identify > those. > > Stefan > > On Thursday, September 02, 2010 10:19:35 pm brett lentz wrote: >> On Thu, Sep 2, 2010 at 11:46 AM, Erik Vos <eri...@xs...> wrote: >> > Turn-based boardgames are effectively state machines. I'm not sure I >> > can think of a model object that should be stateless. >> > >> > Certain parts of the view (in an MVC world) can and should be >> > stateless, but the model *is* the state of the application (read: >> > game). >> > >> > [EV] Of course there is always some form of state behind a model, but >> > often it is not a single state. For instance, the views that give you a >> > list of available trains, or the player worth, or a share percentage, >> > have models that depend on some calculated value, which is not an >> > independent state itself. >> >> Correct. This is where MVC tends to be an improvement to just an MV >> design. Typically, the controller possesses the "business rules" that >> derives those calculated values from the model. >> >> Originally, we started with a Model-View design. It's probably time to >> work on cleaning up the distinction between Model and Controller, and >> making that distinction to help clarify which is which. >> >> > Erik. >> >> ---Brett. |
From: Erik V. <eri...@xs...> - 2010-09-02 22:35:55
|
-----Original Message----- From: Stefan Frey [mailto:ste...@we...] Sent: Thursday 02 September 2010 23:12 To: Development list for Rails: an 18xx game Subject: Re: [Rails-devel] Some (multi-)undo related bugs Brett & Erik: Depending on the interpretation of model and state (general idea, pattern context, Rails context) I can agree/disagree with all your statements below. Example: If model is simply the whole set of data/structure of an 18xx game, and if state is defined as something that change its structure /behavior /properties at runtime, then I disagree (think definition of tracks on tiles). If we define model as all classes that inherit ModelObject and state as above, than I easily agree. So I try to clearly identify my interpretation my take simply is: Parts of the (game) model, which change their state (as defined above) directly/indirectly, extend ModelObject. There is no substantial difference, if the UI subscribe to the object or if only other part of the (game) model. Thus I suggest do derive all three cases below from ModelObject: A) First-class model objects (have state of its own, update UI directly) B) Derived model objects (derive their state from A) or C) type objects, but update UI directly) C) State objects (have state of its own, but do not update UI directly) [EV] The current ModelObject was basically intended to provide for case B). 'Model' is used here in the very limited sense of a Rails-style Observable. I conclude that you want to give it a more fundamental meaning - fine with me if that clarifies matters. The fact that State extends ModelObject is merely caused by Java's main defect: the lack of multiple inheritance. I consider State and Model-in-the-sense-of-Observable as independent types, but the problem was that some objects need to be both. [EV] I'm not sure if using the term Model in this limited sense does any right to its meaning in the MV(C) pattern sense. Perhaps ModelObject is just a bad name. I'm not well versed in MVC theory, to me it's all a matter of practical solutions to actual needs. [EV] What this all means for which way to go (if any), I don't know. If you know ways to give these concepts a better foundation, please go ahead, as long as it simplifies, not complicates the structure (for the sake of some theory). I have seen to much unwieldy Java code to believe that following preconceived frameworks tend to yield good results. >From my point of view the difference between A and C is irrelevant on the model (MVC context here) level, as the model should not care which elements the UI/view subscribes. The difference between B and C might be somehow more relevant, especially if the only composite information for specific UI elements. Then it would make sense to move those into a controller layer, but they could still follow the ModelObject observer pattern. Another suggestion is those objects that have a state of their owns (type A and C thus get changed by Moves) implement a Moveable interface to identify those. Stefan On Thursday, September 02, 2010 10:19:35 pm brett lentz wrote: > On Thu, Sep 2, 2010 at 11:46 AM, Erik Vos <eri...@xs...> wrote: > > Turn-based boardgames are effectively state machines. I'm not sure I > > can think of a model object that should be stateless. > > > > Certain parts of the view (in an MVC world) can and should be > > stateless, but the model *is* the state of the application (read: > > game). > > > > [EV] Of course there is always some form of state behind a model, but > > often it is not a single state. For instance, the views that give you a > > list of available trains, or the player worth, or a share percentage, > > have models that depend on some calculated value, which is not an > > independent state itself. > > Correct. This is where MVC tends to be an improvement to just an MV > design. Typically, the controller possesses the "business rules" that > derives those calculated values from the model. > > Originally, we started with a Model-View design. It's probably time to > work on cleaning up the distinction between Model and Controller, and > making that distinction to help clarify which is which. > > > Erik. > > ---Brett. > > --------------------------------------------------------------------------- > --- This SF.net Dev2Dev email is sponsored by: > > Show off your parallel programming skills. > Enter the Intel(R) Threading Challenge 2010. > http://p.sf.net/sfu/intel-thread-sfd > _______________________________________________ > Rails-devel mailing list > Rai...@li... > https://lists.sourceforge.net/lists/listinfo/rails-devel ---------------------------------------------------------------------------- -- This SF.net Dev2Dev email is sponsored by: Show off your parallel programming skills. Enter the Intel(R) Threading Challenge 2010. http://p.sf.net/sfu/intel-thread-sfd _______________________________________________ Rails-devel mailing list Rai...@li... https://lists.sourceforge.net/lists/listinfo/rails-devel |