From lechner@cs.uml.edu Thu Dec 7 01:42:13 2006 Received: from venus.cs.uml.edu (venus.cs.uml.edu [129.63.8.51]) by earth.cs.uml.edu (8.12.11.20060308/8.11.6) with ESMTP id kB76gC1C015735; Thu, 7 Dec 2006 01:42:12 -0500 Received: from venus.cs.uml.edu (localhost [127.0.0.1]) by venus.cs.uml.edu (8.12.9/8.12.9) with ESMTP id kB76gCfB408713; Thu, 7 Dec 2006 01:42:12 -0500 (EST) Received: (from lechner@localhost) by venus.cs.uml.edu (8.12.9/8.12.9/Submit) id kB76gCGK408714; Thu, 7 Dec 2006 01:42:12 -0500 (EST) From: Bob Lechner Message-Id: <200612070642.kB76gCGK408714@venus.cs.uml.edu> Subject: $PH/06f522/setgame06fRJLCommentsOnEmail061206.txt To: alison_lea@yahoo.com, kbagley@us.ibm.com, cguffey@gmail.com, agabriel@cs.uml.edu, nitin.sonawane@verizon.net, nsonawan@cs.uml.edu (Nitin Sonawane), nitin.sonawane@gmail.com, lechner@cs.uml.edu (Bob Lechner) Date: Thu, 7 Dec 2006 01:42:11 -0500 (EST) X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Status: RO RJLRef: $PH/06f522/setgame06fRJLCommentsOnEmail061206.txt Here are some more comments on email Tues and Wed, which I concatenated non-redundantly into $PH/06f522/setgame06fEmails061206.txt (in ascending time order - which I find easier to trace) My comments are first about quotes from these emails, then about new concepts for separating concerns (event distribution vs. State Models) in LCP. -------------------------------------- Message 29/1540 From Chris Guffey Dec 06, 06 01:13:49 PM -0500 ------------------------------------------- $CASE/06f522/cguffey/final_project/rev9 directory. This revisions adds functionality to check the number of sets on the board [RJL> Why is this useful? It just seems to put a gratuitous constraint on the layout. It's possible to deplete the deck then the layout so both are empty. Why are there "other places where we deal cards"? Since maxLayoutSize is fixed at #define SOMEINT 12, why doesn't deal [enough] cards accept (or figure out) the current card count and just add more until (layout_is_filled or deck_as_empty)? Propagating card locations is optional, I think someone said, since the card (and its content) is known by the same unique immutable id# in [0..80] regardless of its location at each client. BTWay isnt it a premature generalization to make some deployment constants (# of decks, deck size, layout size?) dynamically reconfigurable over different games? Unless the game-rule-set is also dynamically configurable metadata, all the code must be recompiled anyway? I heartily agree. The MVC 'pattern' keeps model AND controller stuff out of the GUI (local 'front end' UI). In fact, MVC separates all three: model. view, controller. GUI reports events via callbacks to Controller. 'Backend' DBMS (e.g. bde/pr_util) does persistent I/O so noone else knows how it's implemented. I also believe 'networking' (front end to remote users) should also be separated from Controller which is in charge of all of them. That's right. (I append a few pages of notes on this below.) Chris - Why do you say "the GUI code would tell the engine what needs to be done?" I think the GameController is (subordinate to?) the Server, and the GUI is subordinate to (part of) the Client, not the Server. The GUI code may send to the client an event message or callback with mouse position arguments or it may convert mouse position into a layout cell# parameter value before sending a more abstract higher-level Event input to the Client. I believe the game-playing server-interaction responsibiliies of the client can be subclassed independently of the GUI rendering and callback responsibilities of the GUI. We only need to implement one version of each. (A text-based alternate would be another UI version; a local shared-memory player would be another networking version..) >> Some further Food for thought: Separation of Concerns within LCP: ---------------------------------- Paraphrasing FPBrooks in MMM Ch. 5 The Second-system effect: (1) Your first system is often conservative in design: lean and mean but inadequate for the job. (2) The second system is the most dangerous one - the general tendency is to over-design it with too many frills. (3) The third and further ones should reach a cost-effective compromise. ---------------------------------- Is comm. channel surrogate services part of View since it talks to (or from) remote clients who have their own GUIs? I think not. Is it part of Backend DBMS? Certainly not. Is it part of Controller? Again I think not, because it should be a separate (2-way message distribution) concern between Server and each Client, hidden from (transparent to) the GameController. I would try to hide networking under one of two distinct subclasses of Client: the current remote ones that need networking, and another subclass of local shared-memory or light-weight thread that do NOT need networking at all. The only methods that should care about whether a Client is in the local or remote subclass of player are the ones that handle registration of Clients as Observers; these diffs can be hidden under subclass override methods of the Client class.. The controller can also pass its (broadcast) messages to invoke generic methods that are also over-ridden inside each client subclass. Clients on a single LAN can use the shared memory version (not yet implemented). Lucky for me that you-all and Lalo/Herrick implemented the more complex distributed process version:-) So the ideal (to me) architecture separates 4 concerns: Model(DB), View, Controller and Distribution (networking). For example, I think LCP modeling concepts would make this mmore evident: Using LCP, I would have modeled two AC classes at the Server site: one AC for the Server=GameController and one AC for the channel interface SurrogateClient subclass of Client. There would be one AI instance of the controller AC, and N AI instances for N players, representing them as SurrogateClients. At the Server site all of these N AI instances would be from the networking surrogate subclass of Client with responsibilty for transparently forwarding messages to and from that Client. I would also have modeled one Client AC and one AI for the ONE client at each remote Client site, and one AC for the Server's networking surrogate at eacn remote client site (2 AC's, each with a single AI.) I don't know if networking is so symmetric that the surrogate for Server at site of Client, and the surrogatwe for CLient at site of Server can be the SAME class, or if they must also become subclasses, one for Server and one for Client. My ideal would be to minnimize the differences between them. This would simplify evolving peer-to-peer network games from the current one with a Server hub and radial links to client-sites. An interesting question is whether a LocalClient AC needs any surrogates at all? Can the Server/Controller AC/AI send its messages directly to the local Clients with no networking surrogaes involved? I believe this should be possible. This is another criterion for what class should be assigned what responsibilities: LCP now manages a single event queue (EI table). This can support the Server AI and all locel Client AIs with a FIFO queue discipline. LCP merely works down this queue and dispatches any messages there. Messages to the local clients are processed by that Client's methods (he same ones that remote Clients execute). Messages to a remote client are processed by the surrogate for that Client, which merely sends them over the channel to that Client's EI queue (for processing by its local LCP if implemented that way). Messages from a remote client are sent out by the Server's surrogate AI from the client site (hiding the remoteness of the Server). When they arrive at the Server site, they are merely placed in the EI table (addressed to the Server/GameController) where he LCP dispatcher proceses them (ProcessOneEvent). If local clients also generate events, they put them on the same EI queue, that is shared with the Server. Note that inserting a generated EI object into the EI table is an atomic transaction if it is inside a single State Action (without priority levels). Another thing to note: I believe it is possible to use LCP without any State Models - i.e. with each AI having a one-state or stateless model. In this case, all 5 classes I identified: RemoteClient, SurrogateServer, or SurrogateClient, LocalClient and Server/Controller are modeled like bde classes: they case-switch on flags representing their implicit 'control' state ST and then on message type representing their implicit EventType ET and cal the appropriate method in each case. [Caveat: Guard Conditions are also involved. One glance at bde/src/*ops.cc which uses this method reveals the complexity of guarded control flow, mainly because bde's methods must detect various object selection conditions from mouse x,y coordinates; modern GUI builders may provide more built-in services for this.] [But be aware that dynamic diagram editing is NOT the same as writing callbacks to non-GUI commands from a menu tree of buttons pre-compiled into a GUI. It is much more like using a window layout editor/manager whose end product is a file that generates a widget tree instead of a bde diagram.] My Conclusion: LCP could be used without [non-trivial]StateModels: (i.e. all its AC's have trivial one-state SMs). As such, LCP is simply an APPLICATION-INDEPENDENT framework for managing Event Types and Instances with support from the genlog API. EIcurr becomes the hcg_ptr argument to each such call. EIcurr points to the text-encoded arguments supplied by the msg source and ETid implies the method to be called at the destination. Later, StateModels could be added (e.g. to setgame or to bde) by splitting out States and their Actions. The current AI==>EI network paths can trace the history of a game, since logging can spill out a runtime event trace history (each EI is a graph edge among CLient and Server instances (the EI's source and destination AIid#s). Constraints on this network would be easy to model as another class of AI to AI edges. This models the administrative database[View]. (E.g., create one AI per Client that joins the game. Until it quits the game, allow it to communicate to/from the Server AI but to no other client AI.) These edges represent setup [meta?]data that can evolve by and is runtime-checkable by the Controller. This would involve extending the LCP dispatcher's application-independent ProcessOneEvent function. Then it applies not only to any Game, but to any distributed application. PS: If you have read this far, you may have gleaned some clues to Exam2's take-home problem.:-) I hope Exam2 Problem 1 gave you some insight into LCP's generic applications. I hope we can discuss this further next Tues. Bob Lechner