Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Need help with architecture planning of kind of complex state machine.  (Read 8017 times)
fanselm
Newbie
*
Posts: 2


View Profile Email
« on: February 07, 2012, 09:17:06 »

Hello out there and thanks for reading.

Sorry for the bad title btw but my problem is not easy to describe in one line. So here comes the looong story:
I'm developing a small game which should work as a kind of virtual chemistry laboratory. The laboratory has different kinds of equipment, bottles, test tubes, heaters and so on. One can then take chemicals with eg. a pipette (which one drags with the mouse) from different bottles and add them together in a test tube, which can then be taken (clicked and dragged) to other equipment for instance the heater. Hopefully in the end you will end up with some new chemical.
To begin with the user selects a certain task (like "Produce fertilizer") which determines which equipment is available in the lab and gives the user a recipe of what to do in which order. When the user has performed a step in the recipe it gets checked on a list so that the user can follow the progress.

The problem is simply: How do I lay out the MVC structure to best incorporate this functionality?

Here are some of my own thoughts about it:
 - The tasks that the user can select are represented by a TaskVO which defines which equipment should be available and what steps it should allow (and check on the list) and which actions that should not be allowed (we might want to show a warning if the user tries to do something which is not in the recipe)
 - The chosen TaskVO is stored in the TaskProxy.
 - The different chemicals could be represented by some kind of SimpleContentVO which just has an ID property
 - A mixed or somehow treated chemical could be represented by a ContentVO which contains a history of what has been added and how the content has been treated (eg. heated, stirred).
 - When performing an action on the content one adds to its history an ActionVO which has a type ("add", "heat"...) and some info (if type == "add", info is the ContentVO added, if type == "heat" ifo might be the temperature)
 - The lab and its equipment is represented by view components, which could have a content property of type ContentVO if they can hold chemicals.
 - If one takes some chemical with the pipette and adds it to a test tube the mediator could send out a "PERFORM_ACTION" notification with type "testTube" and body being an ActionVO with type="add" and info being the ContentVO in the pipette.

So here comes the trouble: The TaskProxy will be asked (through performActionCommand) if the requested action is permissible based on what we try to put in the test tube and what is already in there - but so far only the test tube component knows what is already in it. One can then solve this is two ways: 1) Send both the content to be added and the content already in there 2) Throw all info about what content is in which equipment in some new proxy - but still the look (eg. color) of the test tube perhaps depends on what is in it, so the view should still be updated (I've thought of using an ActionRequest to send a callback to the mediator)

Do you have any suggestions of how to do this? It should allow for easy extension of the lab with more tasks and equipment.

Any help is much appreciated!

/Filip
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: February 07, 2012, 11:05:49 »

You could actually build a state machine using the StateMachine Utility. That would mean that your actions would lead you to various states such that you don't have to evaluate everything all the time, instead you rely upon being in the right state at all times because you define a Finite State Machine (FSM) that says what states there are and what states you can transition to from a given state, etc. You can write guard code that keeps you from exiting a given state unless you're ready (e.g., you've put something valid into a test tube), or from entering a given state unless you're allowed (e.g., you've got two test tubes with valid stuff in them so that you can mix them. You have Mediators and Commands send notifications about actions that change the state, or respond to notifications from the StateMachine saying the state is about to change or has changed, etc.

The difference in the StateMachine approach and the approach you describe is that you are constantly trying to evaluate the state of the application in various places. With an FSM driving things, you don't care. You just listen for the changes and trigger them when appropriate. Having an FSM at the core of your app is a fog-lifter.

Here is a recent post with a real-world FSM from a product of mine. It's a licensing program, not a game, but you can see what the process of declaring an FSM is and how looking at it gives you a conceptual map of your application's discrete states and how it moves between them. http://forums.puremvc.org/index.php?topic=1991.msg8905#msg8905

State Machine Overview Presentation
http://puremvc.tv/#P003/

AS3 StateMachine Utility
http://trac.puremvc.org/Utility_AS3_StateMachine

-=Cliff>
Logged
fanselm
Newbie
*
Posts: 2


View Profile Email
« Reply #2 on: February 07, 2012, 01:38:46 »

Thanks for your quick reply, Cliff.

I've already looked into the FSM utility, but I found it hard to make it fit in this situation. The problem is that we are in fact not talking about a finite but an infinite state machine: A test tube can be heated over and over again changing its state - however, heating it twice may in most recipes be an illegal action and thus only two of the states can be visited, but still one cannot exclude that a future recipe will require us to heat it two or more times. Actually it isn't discreet either as one could heat it to different temperatures. The FSM Utility requires us to manually label all of the possible states which is impossible in this case. Instead we need to find some good identifier of the state (which I attempted to do with the action history) and check that a transition to another state is valid.

One could however use the FSM to keep track of the allowed steps in the task since they can easily be individually labelled (perhaps this was actually what you proposed?). One can then make a task FSM definition that looks like the following (here in a baking example):
:
<fsm initial="empty">
    <state name="empty">
        <transition action="add-water" target="water"/>
        <transition action="add-yeast" target="yeast"/>
    </state>
    <state name="water">
        <transition action="add-yeast" target="water+yeast-added"/>
    </state>
    <state name="yeast">
        <transition action="add-water" target="water+yeast"/>
    </state>
    <state name="water+yeast">
        <transition action="stir" target="water+yeast-stirred"/>
    </state>

    ...

</fsm>

However the FSM Utility has to be modified to allow for dynamical properties on the transitions for use by the guard code and then it all starts to look a bit like my initial proposal (except for the fact that we are now rid of the probably cumbersome history validation). Building on the baking example I need something like the following:
:
<fsm initial="empty">
    <state name="empty">
        <transition action="add" type="water(0.5L)" target="water"/>
        <transition action="add" type="yeast(50g)" target="yeast"/>
    </state>
    <state name="water">
        <transition action="add" type="yeast(50g)" target="water+yeast-added"/>
    </state>
    <state name="yeast">
        <transition action="add" type="water(0.5L)" target="water+yeast"/>
    </state>
    <state name="water+yeast">
        <transition action="stir" target="water+yeast-stirred"/>
    </state>

    ...

</fsm>
As you see I've added parameters to the transitions. This XML structure might not be the best, perhaps one could keep the original FSM Utility structure and just define transitions in another XML ot just in AS.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: February 07, 2012, 05:00:02 »

Well, you have infinite states, if you account for the invalid ones, right?  Those are the places you take stock of the situation in guard code.

Say you've put water and water into the tube, for instance. Presumably, you couldn't do anything interesting with that. So when you've put water and water into the tube and tried to go to the stir state, you'd listen for the exiting guard announcement, run some code that looks at the things you've put in your tube, and determine you couldn't go forward to the stir state, cancelling the state transition.

-=Cliff>
Logged
Pages: [1]
Print