PureMVC Architects Lounge

PureMVC Manifold => Demos and Utils => Topic started by: puremvc on November 29, 2008, 08:45:01



Title: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on November 29, 2008, 08:45:01
This utility provides a simple yet effective Finite State Machine implementation, which allows the definition of discrete states, and the valid transitions to other states available from any given state, and the actions which trigger the transitions.

A mechanism is provided for defining the entire state machine in XML and having a fully populated StateMachine injected into the PureMVC app.

Standard and MultiCore versions are included.

The utility has historically been located here: http://trac.puremvc.org/Utility_AS3_StateMachine
The project has been moved here: https://github.com/PureMVC/puremvc-as3-util-statemachine/wiki

Standard and MultiCore versions are included.

The authors are Neil Manuell and Cliff Hall.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 01, 2008, 02:46:19
If you happened to download this utility within the last 24 hours, you probably found that the /bin folder with the compiled SWC files was missing. Sorry about that. Download again and you should be set, though you may need to clear your browser's cache.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Hyakugei on December 08, 2008, 07:48:14
Just a quick note to say - wow, nice work! I'm really looking forward to my next project where i can spend some time with this utility.

Wonderful work. Thank you, to all the authors.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 09, 2008, 02:57:38
cool, let us know of any problems / solutions / additions that may pop up


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on December 24, 2008, 10:38:19
In the release notes under the State Representation section one of the points is:

The entering notification for a State carries a reference in the body to the state we are entering as well, in case you've sub-classed State to pass data.

Do you have an example of how this would be done?  How would you get your new state class to be registered, by overriding FSMInjector::createState to instantiate your class instead of StateMachine's State class?

This would be my top feature request: an elegant way to specify subclasses for individual states w/o needing to override createState (maybe a user doesn't want all of the states to be represented by the extended State class, only certain ones).  Perhaps something could be cleverly done w/ XML namespaces to specify the class to use...

(abbreviated fsm example)
:
<fsm xmlns:sub="com.my.namespace.to.state.class.ExtendedStateClass">
  <state name="Normal State">...</state>
  <sub:state name="Extended State 1">...</sub:state>
  <sub:state name="Extended State 2">...</sub:state>
</fsm>

This way you wouldn't have to type out the entire state class multiple times:
More Verbose Way
:
<fsm>
  <state name="Normal State">...</state>
  <state name="Extended State 1" stateClass="com.my.namespace.to.state.class.ExtendedStateClass">...</state>
  <state name="Extended State 2" stateClass="com.my.namespace.to.state.class.ExtendedStateClass">...</state>
</fsm>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 24, 2008, 11:49:00
Yes, currently you'd need to subclass FSMInjector as you described.

I like your suggestion, though.

I think the latter version of your suggested examples is the right way to go. Overloading the xml namespace identifier will (IMHO) be confusing to most, harder to parse, and more prone to error. And we have E4X for parsing. Imagine doing it to java and having to use some horrible xml parser there to programmatically rip it apart. (BTW, if you happen to be doing just that in java now, go look up XOM, its the best).

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on December 24, 2008, 12:11:43
Hm, wasn't thinking about having to port when suggesting that, but would it really be that difficult?  I was just concerned w/ having to re-enter the potentially long namespace for the subclassed State multiple times.  I much prefer the first method, and parsing it is easy!

Using the following XML:
:
var fsm:XML = <fsm xmlns:sub1="com.SubState1" xmlns:sub2="com.SubState2">
  <state name="Normal State" />
  <sub1:state name="Sub Classed 1" />
  <sub2:state name="Sub Classed 2" />
</fsm>

Parsing:
:
var namespaces:Array = fsm.namespaceDeclarations();
for each(var ns:Namespace in namespaces) {
  // get class reference for ns.uri
  // store it in a hash under key ns.prefix
  trace("Prefix '" + ns.prefix + "' is for class => " + ns.uri);
}

for each( var state:XML in fsm.children() ) {
  var stateNS:Namespace = state.namespace();
  if(stateNS == null) { /* USE regular State class */ }
  else {
    trace("Need to use class w/ NS: " + stateNS.prefix);
    // something like
    var stateClass:Class = stateRefs[stateNS.prefix];
    state = new stateClass();
  }
}


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 24, 2008, 01:52:44
I agree with cliff that the namespace option is, lets say a little specialised, for general use... I think it may scare off quite a few people.  The verbose declaration is simple and obvious, though not as elegant, though I may have a play with this idea.




Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 24, 2008, 02:31:44
by the way, how would you ensure that the state classes get compiled?
if you are typing to interfaces and defining class paths as strings, there is no guaranteeing that they will.

I usually wrap my getDefinitionByName method in a factory that explicitly declares all the classes to be compiled for that factory, then pass the factory where it is needed.

However, this is just another class, another piece of tramp data, and another complication...

oh, and merry xmas


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 24, 2008, 07:00:20
As soon as I walked away from that last post, this was the next thing that came to mind. I think your closing thought is key, it is another complication. Whether is worth that complication to implement is questionable.



-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 25, 2008, 02:25:15
i think that its definitely worth documenting as a way of extending the utility... that gives the user a choice


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 25, 2008, 07:53:03
Sure. Perhaps a demo that overrides FSM and injects custom state classes. But I'm not entirely sure just yet that State should have subclasses. That means any actor handling the State object needs to know that custom State subclass. I have reservations about that coupling.

Before recommending that I'd like to think through the problem a bit more.

If anyone would like to throw out example scenarios here that use subclasses and arguments for it, please do.

In the meantime, some more research of other statemachine implementations might be in order to inform us further. There are a lot of takes on this problem out there and what is here is extremely simple and usable. I'd hate to make it more complicated than it is if we don't have to.

-=Cliff> 


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on December 26, 2008, 01:30:19
I don't have a particular need to subclass state, but was just exploring how this would be done in response to the bullet in the release notes I originally quoted.

If there was a body Object on the State that would allow me to pass data into the notification that is initiating an ACTION to another State, then the problem of having to send the StateMachine.ACTION notification, and then respond later after an ENTERING or CHANGED notification to send data would be solved.  That is the primary feature request I have right now for this utility.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on December 26, 2008, 01:31:25
oh, and merry xmas

And merry xmas to everyone as well.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on December 29, 2008, 03:27:38
Hi!

Is the State Machine solution suitable for handling asset/media loading? (mp3 files, images...) If so, should the loading be regarded as a state or as an action between two states?

Regards!  / Jonas


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 29, 2008, 04:31:40
mmmm this is quite a pertinent question, as it involves an asynch element.

The fact that the StateMachine Util is itself synchronous, must be taken into account. The important thing is not to fire an async command from the exiting notification of a State (and I see no reason why this should be needed, these should merely provide 'clean up' functionality).  It is likely that this will mean that the enter Notification of the next state is fired before the asynch process of the exiting State has finished.  The Synchronous nature of the StateMachine can be worked with by encapsulating asynch processes into separate states.

These are two methods that I have employed myself:

             MainState
              |        ^
   (loadAssets) (loadComplete)
              V        |
             LoadState

or

             MainState
               |      ^
   (loadAssets) (loadError)
               V      |
            LoadState
                 |
         (loadComplete)
                 V
           DisplayState

This also allows restriction of user activity within the loading state, and ensures that a view can be bound to it (ie a prog bar).

hope that helps :~)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 29, 2008, 07:02:58
Note that though the StateMachine is synchronous, you can use the AsynchCommand utility in conjunction with it to cause asynch processes to complete before the state transition completes.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 29, 2008, 07:12:57
Hey cliff,

surely if you use the AsynchMacroCommand, on an exit Notification, as soon as the executing code hits an AsynchCommand (and added a handler), it will continue back down the call stack, to the StateMachine, and send the enter notification for the next state, then run any code registered for it, and only when the entire thread has completed, will it be able to execute the handler for the exiting AsynchCommand, allowing the AsynchMacroCommand to continue.

I'm by no means an expert on the execution order of AS3 code, but the above was my understanding of it.  I also have to admit that I haven't actually tried it, as I didn't think it would work :~/



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 29, 2008, 05:59:39
Fleecie,

You may be right. I haven't tried it yet either, but thought it would work because the thread of execution shouldn't return to the StateMachine until the AsyncMacroCommand completes its execute method, which cannot happen until all its subcommands have completed.

We have seen in the Sequential demo that asynch timer processes can effectively hold the thread of execution inside an AsynchMacroCommand's execute method until its children, async or not, complete. This shold be no different for asynch service calls.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 30, 2008, 01:29:06
that would be cool :)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on January 02, 2009, 06:18:57
Hi Cliff and Fleecie!

The asset/media loading stuff is a common "real life problem", and so are service calls. To me it sounds very reasonable to combine these with the state machine paradigm.

A demo combining the state machine and async loading and/or service calls would be of great help for a PureMvc newbee like me!

Regards / Jonas


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on January 02, 2009, 01:34:27
It's definitely on the list of needed stuff. Fortunately they each have separate demos and are learnable. The combination will be powerful to be sure.  I'm fully tied up trying to get video training going at the moment. In the meantime if you (or any other kind soul reading this thread)  manage to get one going let me know.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 02, 2009, 01:39:11
well, I'm working on some thing similar at the mo, and at some point I'll try and rip the guts out to make a simple demo... don't hold your breath tho...:~/


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on January 03, 2009, 12:31:46
Hurry up, Fleecie! My face is already blue!  :) / Jonas


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: muqtadir on January 03, 2009, 02:08:30
Is there is a concept of interceptor.
How State will work with Pipes Modular approach. -MA



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 03, 2009, 02:16:21
I presume you are talking about the Interceptor Pattern
Do you have any resources?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on January 03, 2009, 02:43:43
Each core can have its own StateMachine. Within a core, you can respond to any incoming message or interface call by changing the state of the core, which could in turn trigger outgoing messages (or call return value) that cause other modules to change state.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: muqtadir on January 03, 2009, 03:01:19
Make sense. I have model which is shared by different core. Will try your option to see how it behaves. - MA
Each core can have its own StateMachine. Within a core, you can respond to any incoming message or interface call by changing the state of the core, which could in turn trigger outgoing messages (or call return value) that cause other modules to change state.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 04, 2009, 02:25:44
hey, cambiata,
have whipped up a quick demo here you go.
http://revisual.co.uk/?p=388 (http://revisual.co.uk/?p=388)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on January 05, 2009, 06:00:44
Thanx a lot, Fleecie!
I've delve into it as soon as my brain has got some oxygene!  :)

Jonas



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on January 05, 2009, 02:42:05
A nice demo for sure, but I thought we were looking for a demo of StateMachine in conjunction with AsyncCommand?

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 05, 2009, 03:22:25
LOL, yes, that's next on my list.... I wanted to show two ways, encapsulating the asynchronisity in its own state, and an asynchronous state transition.

Its just that the project I ripped the demo code out of handles it the former way.

I will try to do it by the end of the week.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 06, 2009, 03:59:03
well here it is:

http://revisual.co.uk/?p=409 (http://revisual.co.uk/?p=409)

The AsynchMacroCommand doesn't seem the keep the thread, and so the DISPLAY state is entered before the load is completed ( check out the enabling of the button states ). This is ok in the demo, as the progress window is modal, so restricts interaction. So using this method requires more care.

Have a look and see if I've done something wrong...

cheers



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: GroundZero on January 07, 2009, 10:20:32
This is a very nice edition so let me start by saying thanks to those involved with getting this put together. :D

In the last 6 months I have become very attached to the Fabrication code base that can be used to eliminate much of the need to write "glue" code in the mediators etcetera.  The State Machine is not exactly playing nice with this stuff and I really do not want to have to make a decision as to using one or the other (pureMVC+Statemachine as opposed to PureMVC+Fabrication).  Yes, I know, I want to have my cake and eat it too..then ride a rollercoaster and maybe go for a nice skateboard ride :P

The issue arises when you are trying to write your notification handlers in the mediator for your application.    With Fabrication, you don't need to use listNotificationInterests....you jsut write the handler out prefixed with "respondTo".

So a note called "userModelChanged" could be easily picked up in the mediator by writing up a function named "respondToUserModelChanged" and BAM you are off to the races.

Unfortunately the State Machine "changed" note name contains forward slashes and prevents us from using Fabrication.  I thought for a moment maybe I could just handle the state changed using "pure" pureMVC listNotificationInterests methods.   But Fabrication sees this and will not respond to other "respondTo" methods.

I REALLY wanted to continue usage of Fabrication along with this State Machine so I dug in and altered the Static constant for the "changed" name to be "stateChanged" instead of "StateMachine/states/changed".

This seemed to have no impact on the way the state machine operates and allowed me to write my "respondToStateChanged" and my originally needed "respondToUserProxy" handlers so Fabrication can do its awesome magic.

Of course I am now forced to use the uncompiled source, but hey!  It works!

 I have converted the StopWatch example to use Fabrication on top of pureMVC and the State Machine.
For some reason I also had to register the commands for them to execute. Could someone explain how the slash notation in the currentState.name is really meant to be used? I see other constants in the example using this notation and just wanted to be more clear about the impact of my own changes.

Thanks again!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 07, 2009, 11:26:27
Wouldn't this be an issue to take up w/ the Fabrication utility and not StateMachine?  What if someone uses the convention of putting slashes in their constants out of preference (I have begun doing this for all of my Facade constants).

I haven't used Fabrication yet, so I'm not sure how that works, but it seem that Fabrication should perhaps detect and trim out bad characters, replacing them with empty space, or underscores or something when trying to call respondTo*...


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: GroundZero on January 07, 2009, 11:32:56
Yes I have had these thoughts too.  Underscores were my first choice.  I am going to talk to Darshan about it to see what he thinks. Until then I will work on the Fabrication sources as well to see what I can come up with.

Please understand that I was not taking issue with anything or saying it is a bad choice made, but merely pointing it out for the folks on these forums that are using Fabrication and may be running into issues.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 07, 2009, 11:38:23
Of course, I wasn't criticizing your post, but just suggesting that the problem should be addressed at the root cause in order to prevent the same thing from occurring elsewhere (people using slashes in their constants), rather than changing the way state machine names its constants.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 07, 2009, 11:46:11
hi GroundZero,

you have brought to a point a question that I have been asking my self.  There is a lot of really great stuff  coming out around the pureMVC frame work: fabrication, pureMVC Studio, and I'm not sure whether they will be compatible with each other. I'm working on my own little project, and don't want to create something that can't be used seemlessly alongside the like.  

In this case though, I have to agree with gjastrab, I think using package conventions on note names is a really useful way to avoid pollution, and they are simply Strings, and should be able to contain anything. I think you are right about talking to Darshan about this, as the fact that they can't work together needs to be ironed out. I'd be interested to hear Cliffs views on this.  I'm sure he has a master plan that he hasn't divulged to us yet.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: GroundZero on January 07, 2009, 11:53:46
Yes, I agree some "regex" magic is needed to remedy this in the Fabrication package.  I want to use the state machine in a project I am doing now (that has a 30 day deadline) so went the route of a "quick fix" by just removing slashes in the event name. I see the point about pollution of notes/events.  I guess this is similar to the "addressing" of modules in a pipes application (I have done 2 now and will never go back to the single instance packages!).  I am going to go post on code drunks so both parties are aware.

Thanks for such prompt replies!



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Jason MacDonald on January 07, 2009, 01:23:40
Fabrication already uses a slash syntax for note names behind the scenes because module instances share the same note names. Both ModuleA_Instance1 and ModuleA_Instance2 have the same notification interests because they are both instances of ModuleA . Routing needs a way to send a route to moduleInstance1, and not moduleInstance2 of the same module (this is the entire point of Fabrication, simplifying communication between modules and allowing finite communications.) It accomplishes this by changing the noteName internally to a path like "module/instance/noteName" rather than just "noteName", and then stripps away the path from the note name when it's time to call the actual function held under that path. If you were to name a note with slashes, it would end up looking like "module/instance/note/name/too/many/slashes" and would fail to properly trigger the associated method when the module/instance part was strip off.  It would try calling respondToNote/name/too/many/slashes() which is note a valid function name.

Asking a developer with a huge code base, who's project has existed much longer than this one, to change his entire logic of routing to work with a very small utility seems a poor choice of fixes to me. I for one would much rather roll my own StateMachine without slashes than try to rewrite all that Fabrication does. Not using slashes in  note names is a small trade-off for the power fabrication gives me.

Just my two cents, but I hope Darshan does not change his routing logic.

EDIT: Changed first paragraph to better explain routing paths and why they are used as note names.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 07, 2009, 01:30:21
Hm, that does complicate things if it relies on interpreting meaning from slashes in a notification name in Fabrication.

I think fleecie's right and now that the PureMVC community/tools are growing it's going to be interesting and important to see how to better tie things together to ensure they play nicely.

+1 on being interested to see if Cliff has anything cooking in this area yet...


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 07, 2009, 01:41:02
sure, jasonmac, I bow to your knowledge of Fabrication, I haven't had a chance to look at it yet.
If it's entire notification system relies on slashes, then:

Asking a developer with a huge code base, who's project has existed much longer than this one, to change his entire logic of routing to work with a very small utility seems a poor choice of fixes to me

seems a sensible attitude :~)

The slash notifications in the State Machine were added by Cliff, so I await his judgement.

as I said previously, I think this is going to happen more and more, and not just for simple utilities like this one. 


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: GroundZero on January 07, 2009, 02:31:23
I dug around a bit and saw this as well Jason. Thanks so much for your post  :) . It made me feel a bit better about my quick fix. Maybe it IS the best thing to do for now...I like the routing when using pipes/fab the way it is as well.  I was afraid however that for some reason unknown to myself, that removing the slashes would break something in its core functionality. This is not the case, WHEW! I am so glad these forums exist.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 07, 2009, 03:19:08
btw, i always used to use . delimitation with my note names which, of course, would not clash with the Fabrication /
just a thought
:~)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Jason MacDonald on January 07, 2009, 06:10:43
I can almost 100% guarantee the reason Cliff added the path was because note names like "change" are far to generic and likely to be used by other people in their own apps. By using the static name of stateMachine, along with the "path", he guarantees there won't be a clash of names at run-time. However the same can be accomplished using "stateMachineChange", "stateMachineNotesChange" or even "stateMachine_notes_change" instead of "StateMachine/notes/change".

The "/" in this case serves no real purpose other than to provide a unique name. There's no demand, in the case of a "pure" puremvc app, for there to be a path in the note name.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 08, 2009, 12:42:01
of course it was,
I'm only saying that it is good to get some standards so that such a simple thing doesn't bring down the house. :)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Darshan Sawardekar on January 08, 2009, 07:15:00
Hi All,

Regarding the issue with StateMachine and the respondTo syntax. This is easily solved using a new feature that I implemented a few days ago, Interceptors. Interceptors are like filters for PureMVC notifications. You can drop notification, alter them enroute, etc before they reach the PureMVC actors, Mediators and Commands. The idea is adapted from the Parsley application event interceptors feature[1]. Interceptors are very similar to commands and you can do everything PureMVC commands can do.

To implement Interceptors you need to extend the AbstractInterceptor class and implement the intercept method. The interceptor object is registered like commands with the registerInterceptor in commands or fabFacade.registerInterceptor method. Inside the intercept method you can,

  • Alter the body/type of the notification
  • Drop the notification
  • Proceed with a different notification in its place
  • Send N notifications before/after the notification

The StateMachine looks pretty useful. Good work Neil and Cliff. I have put up a demo of using the StateMachine with Fabrication[2]. The key class in the demo is the StateMachineInterceptor[3]. I have registered this interceptor with the StateMachine notification names. The intercept method checks for the presence of the StateMachine slash syntax, extracts the last part from the name and converts it to the form state<Changed|Action|Cancel>.

I checked the StateMachine source. It is listening to 2 of these notifications. So instead of altering the notification I am sending the modified notification for use with the respondTo syntax.

To clarify regarding the slash syntax, Fabrication uses the slash as a separator for routing notification across modules. The notification name is not altered at any point before, during or after transport. The slash in the to argument indicates the destination address of the target module of the notification not the notification name.

With Fabrication I have tried to keep things as compatible to PureMVC(Multicore) as possible. But If you have some specific feature/utility that does not work as expected, I will try to fix anything from Fabrication's pov as long as it makes sense. ;-)

Note, Interceptors are only present on SVN at the moment. I will be adding a release swc soon.

peace,
darshan

[1] : http://www.spicefactory.org/parsley/docs/current/manual/mvc.php#config_interceptors
[2] : http://code.google.com/p/fabrication/source/browse/#svn/examples/simple_fsm/src
[3] : http://code.google.com/p/fabrication/source/browse/examples/simple_fsm/src/interceptor/StateMachineInterceptor.as


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 08, 2009, 07:20:22
hey, thats really cool Darshan! :~)



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: GroundZero on January 08, 2009, 09:18:20
Seriously, that rocks  8) . 
Thanks for the email Darshan. I will update my demo and pass it along to you as promised.  Thanks everyone on this thread for their time!



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on January 08, 2009, 09:53:13
Hi all!

When entering a FSM state, is it possible to fire more than one ApplicationFacade command?
Something equivalent to the following would be practical:
<state name={Main.STATE_1} entering={AppFacade.INIT_UI, AppFacade.RESET_VALUES, ...}>
Or would this break some good design practice?

Regards / Jonas


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 08, 2009, 09:59:36
this shouldn't be needed,

If you need more than one command to be triggered by this event, simply register a macro command (synch or asynch ) with the Notification, and add all the sub commands within the initializeMacroCommand method.

also, don't forget that mediators can also have interests in notifications.

cheers:~)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: cambiata on January 08, 2009, 12:07:31
Aha!
Thank you, Neil!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on January 10, 2009, 09:17:44
Sorry I didn't see this thread brewing folks.

I've been using this as the message naming style in Pipes for awhile and it seemed reasonable that the notification namespace of utilities should be managed in this way as well.

BTW, it's not so much an as yet undivulged 'master plan' on these utility note names, so much as a recognition with the last few utils I've worked on that I need to do this, to ensure that the casual choice of notification naming within my utility I'm not in fact declaring reserved words without people knowing it. As someone mentioned here I could declare a note named MyUtil.CHANGE as 'change' and the string 'change' would be completely unusable by any other utility or the application itself. And furthermore you wouldn't know this until you started having all sorts of weird problems where the wrong actors are notified.

I could go and change the utilities that use this (DeploymentConfig and StateMachine I know for sure), but I'd rather not be forced to unless it's unresolvable otherwise. Unfortunately there is a monster pile of repository work set to chew up the rest of my weekend and then I'm back into a fulltime gig for the next few months, which will definitely slow things down again.

For the record, I personally haven't used Fabrication, so I wasn't aware that there would be any conflict there. If there still exists a problem that can't be worked around, can someone summarize it here in just a few words to someone who hasn't used Fabrication?

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 10, 2009, 10:02:51
been thinking about this quite a bit...

and surely a Notification's name is defined as a string.  It doesn't enforce any content structure.  To do so now would only create huge backward compatibility issues. I personal think you should be able to define notification names as the first line of Shakespeare's sonnets (poetic and obviscating) if you so desire. 

darshan seems to have been one step ahead of this any way.

changing the note names on the utils is not a problem, but it should be part of a considered plan, not just a quick fix

cheers


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 12, 2009, 09:35:37
Awesome work Darshan, that's slick and elegant!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 14, 2009, 01:27:17
Before recommending that I'd like to think through the problem a bit more.  (Sorry for not attaching code yet, I will if it makes it easier, but hopefully talking through it will be enough first)

If anyone would like to throw out example scenarios here that use subclasses and arguments for it, please do.
Here is a simple usage example for a case that, in the current version of the utility, is difficultannoying to implement:

I want to pair StateMachine w/ AsyncCommand that will attempt to login to a service.  The login form will be changed when the login request is outstanding, and either change back if failed or faded and the main view is to be displayed if login was successful.

This uses my practice of making the Command an IResponder - which I know has been discussed to be bad practice in PureMVC.  However, I think the usefulness of doing this (especially with an AsyncMacroCommand) outweighs the "bad practice" argument.  I'm willing to be swayed, but this has been my practice since using PureMVC which is why I'm still going with it.  In this example, we're not using an AsyncMacroCommand, but I'll make the DoLoginCommand extend AsyncCommand anyway, for argument's sake.

So, my FSM:

LOGIN -> TRY_LOGIN
TRY_LOGIN -> LOGIN (transition to occur on a failed login)
TRY_LOGIN -> MAIN (transition to occur on a successful login)

If we dispatch an event from the Login form that will get picked up by a mediator, which will send a notification with the username/password information.  However, we don't want the login service to be called until we are actually in the TRY_LOGIN state.

This currently requires us to send a LOGIN notification w/ the username/password.  A command will extract this information from the notification and store it on a LoginProxy.  It will then
:
sendNotification(StateMachine.ACTION, null, TRY_LOGIN)
Now in the mediator on ENTER_TRY_LOGIN we can disable the Login button and the input fields and display a message "Logging in...".  However, cannot execute the service until the state machine has changed into TRY_LOGIN.  So we have to listen on a mediator for StateMachine.CHANGED, and:
:
if(note.getBody().name == TRY_LOGIN) { // (body of note is a State)
  // now run login service
  sendNotification(DO_LOGIN); // (registered to DoLoginCommand)
}

DoLoginCommand
:
public class DoLoginCommand extends AsyncCommand implements IResponder {
  override public function execute(note:INotification):void {
    var loginProxy:LoginProxy = facade.retrieveProxy(LoginProxy.NAME) as LoginProxy;
    loginProxy.login(this); // LoginProxy will execute an HTTPService call and add this command as a responder to the token
  }

  public function fault(info:Object):void {
    sendNotification(StateMachine.ACTION, null, AppFacade.LOGIN) // go back to login
  }

  public function result(data:Object):void {
    /* pseudo code here */
    if( data.result) { // (login successful)
      sendNotification(StateMachine.ACTION, null, AppFacade.MAIN); // go to main
    }
    else { // (invalid credentials)
      fault(null);
    }
  }
}

I love using StateMachine to enforce what state your application is in, but the shortcoming for me right now is not being able to trigger a state change from the login event and pass that event object to the notification that will initiate the state change, but have that be accessible in the ENTER notification for the target state.  Thus, the current need to wait for CHANGED on a mediator before doing the actual login.

To be clear, I would like to be able to:
:
var evt:LoginEvent = ... // this has been retrieved from the mediator, and has username & password properties
sendNotification(StateMachine.ACTION, evt, AppFacade.TRY_LOGIN);

ENTER_TRY_LOGIN will be registered w/ the DoLoginCommand.
Ideal DoLoginCommand:
:
...
override public function execute(note:INotification) {
  var state:State = note.getBody();
  state.body // (the LoginEvent sent as the body of the TRY_LOGIN action notification)
}


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 15, 2009, 01:42:09
gjastrab, can I confirm that you are requesting that if you send a body with an StateMachine.ACTION notification, then it gets passed to the subsequent notifications sent by the StateMachine (ENTER_STATE, EXIT_STATE and CHANGE)?

this seems like quite a good idea.... will ponder


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 15, 2009, 02:27:48
Precisely, if you could pass a body w/ a StateMachine.ACTION that would be available in the notifications that StateMachine sends out, that would save me from a bunch of code that doesn't belong in certain places (if I want to send a body into an event in response to a CHANGED notification, I currently have to throw that onto a Mediator somewhere.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 15, 2009, 02:31:48
well, since the body is not being used I can see no reason not to
Cliff?



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 15, 2009, 02:56:12
except that the body of the notifications sent by the StateMachine is the State which is being moved to... isn't that pretty important information?

how would you get round that?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on January 15, 2009, 03:00:35
I can see a big value in being able to pass the notification body on to the entering notification, and I can also see that instead of passing the State in the body, we could pass the state name in the notification type...

I'm not totally convinced though


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on January 15, 2009, 03:08:25
Yea, I don't really seen any value in passing the State in the body, but that may just be because I haven't found the need to use it yet.

Why don't you introduce a new class:

StateMachineNotificationBody or something like that?
:
public class StateMachineNotificationBody {

  public var body:Object;

  public var state:State;

}


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on January 18, 2009, 06:48:08
I agree.

We have to ensure uniqueness on the part of our utilities' notification namespaces.

I think the approach we have is correct, though we could go with a different separator. But we shouldn't have to. It should be able to be anything as long as its unique.

Darshan is trying to imbue more meaning in the notification name than he should.

This is why I wrote Pipes and IPipeMessage. the notification namespace of a module cannot be guaranteed not to overlap with that of other modules, making it impossible to share notifications reliably between cores written by others. Only if you control the entire notification namespace of all modules can that work. Which means nuts to outsourcing big chunks of your app without handholding or opening a platform where others can write modules that plug into your app.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: undersound on February 10, 2009, 05:50:23
Hey.

following this thread, I just want to give my vote on this!!

It would be really great to pass/receive the notification body the one way or the other. I am facing the problem to either define millions of slightly different states or to put some data somewhere more global accessible, both smells bad.

thanks for this library though i really like it a lot!!!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: jon.opus on February 10, 2009, 12:44:37
Flex apps I have seen define states in the main stage mxml file. If I am in a pure as3 app rather than a flex app where should I define my application states?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on February 10, 2009, 01:18:29
Re passing state, if memory serves, the state you are entering should be in the type param of the exiting note. The state you are exiting should be in the type param of the entering note.

@As for flex states, they are not ther same as application states provided by the StateMachine utility. Flex states are view states, different configurations of view components and their properties which will be used to compose a custom component (not just the main application).

The StateMachine utility provides an application-wide concept of state. It is not mutually exclusive of Flex view states, for instance when the statemachine sends the exiting/entering notifications that make up a transition, mediators for the view could respond by setting the state property of their view components to an appropriate setting for the new application state (not necessarily a 1-to-1 mapping).

But Flex states aren't necessary for use of the StateMachine utility .

To define your application's states, you create an xml description of your FSM (finite state machine. Then from your XML, the FSMInjector creates and injects a fully configured StateMachine into your app.

For more info, check out the article 'Get your FSM On!" In the puremvc.org news section. That will lead you to the utility and the StopWatch demo that defines and implements a simple FSM.
 
-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on February 10, 2009, 01:20:11
The state in flex is specifically a visual state.  The StateMachine utility, manages application wide states.

take a look here  http://puremvc.org/pages/demos/AS3/Demo_AS3_Flex_StopWatch/srcview/ (http://puremvc.org/pages/demos/AS3/Demo_AS3_Flex_StopWatch/srcview/) to see the Stop watch demo, study the InjectFSMCommand.as (org.puremvc.as3.multicore.demos.flex.stopwatch.controller).  The states are defined in xml, then injected via the FSMInjector into the StateMachine.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on February 10, 2009, 01:29:44
on passing states

@Cliff: the argument here, I think, is not to pass the state in the StateMachine's outgoing notifications, but to be able to pass the body of an incoming ACTION notification onto the outgoing ones, instead of the state.

@undersound: I've come across this problem myself, and my solution was to change the model, then change the state.  I don't necessarily think that data should be passed from one state to another, surely states need have no knowledge of each other.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: jon.opus on February 10, 2009, 02:41:24
Cliff, I think I understand. I noticed in the Stop Watch Demo that the state names are references to the something like StopWatch.STATE_FOO.

Are you indicating that If I'm not using flex that I should define the state names in the xml? It seams that I would want to be able to Reference them elsewhere in the app. So should I Define those constants in the facade or in a component or the mediator or the Main???


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on February 10, 2009, 08:20:01
You can define the constants in your main application class if you'd like, or wherever makes sense to you.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on February 27, 2009, 10:24:02
A new version (1.1) of the StateMachine utility has been released for AS3 Standard & MultiCore.

Please read the release notes for details:
http://trac.puremvc.org/Utility_AS3_StateMachine/wiki/ReleaseNotes

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on February 27, 2009, 10:35:50
cool :)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Tekool on February 27, 2009, 12:07:15
Excellent I'm just starting to use the FSM utility. The changelog makes me feel impatient to be on monday.

Waiting for the 'real-world' demo.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on February 27, 2009, 07:20:40
Don't hold your breath on the demo. I'm steaming on a project that you'll all hear much more about very soon. I will be working on something, but spare time is low right now.

For now, read with care the note above and the changes in 1.1 description on the release notes page.

Examine the stopwatch demo for a basic understanding of how to create your FSM and inject it.

In the real world the big difference was I mostly use the 'changed' note for the states instead of the entering and exiting.

I hesitated to put the new version up till I could work out a more realistic demo, but I knew at least on frustrated person recently sunk a lot of cycles into making it do something useful, so I thought I'd be remiss not to post the changes I know for sure work.

Fear not, it is simple but powerful and there'll definitely be more demos and stuff on how to use it forthcoming.

Cheers,
-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on March 03, 2009, 03:43:12
hey, cliff

I like the changes, simple and yet obvious.

Interested to see how this will change the way I use it.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 03, 2009, 06:53:18
I think you'll like it. I'm loving it!

When I dived into my cuurent project, I was determined to use it since I hadn't had a chance to really apply it beyond the Stopwatch demo.

I was somewhat crestfallen to find that the big hole in that demo was the fact that all the state changes are initiated by the user's button presses. No code is ever executed that programmatically initiates a state change.

The reason that's a problem is that the Stopwatch instantly falls into a basin of stability when the new state is reached and so will always be ready for the next action to carry it to another state.

However in the real world, you want to do automated things like check for net connectivity, then check for a license, branch off and collect the license frome the user if not present, then return to checking its validity, then load stuff, then display the main user interface.

For my current app I had lots of that business going on and I felt the StateMachine would be perfect for keeping track of where we were in the process.

But as soon as I started implementing I found that firing off code to do something that would lead to another change of state would fail if triggered by the entering or exiting notes, because, by definition, the new state hasn't been reached, and so when the code you triggered ends up sending an ACTION, the machine ignores it because it was still preparing to enter the state you now wanted to leave.

I was quite pleased to find that adding the per-state changed note was enough to fix the problem.

Then being able to tunnel data through to the next state really helped to not make it so hard for the next state to know what's going on. For instance, when the license info isn't present, and I go collect it with a little data entry panel, then the mediator for the panel stuffs the info collected into the body of the ACTION note which the command kicked off when the state is changed to the license saving state simply plucks out the data from the note, stores it in the AIR ELS and then fires the ACTION for verifying the stored license. If that license is bad, your ping ponged back to the license entry state and do it all again until you get it right, then you move on through to the next state. When the app comes up again, the good data is stored and you never pass through the license entry and saving states.

It really is like a well-oiled machine now. I love it!

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on March 03, 2009, 07:04:26
Yes, I've found myself making hacky workarounds
am about to start a new project and will def be using it in that



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on March 03, 2009, 08:35:01
Thank you Neil for the utility.
Thank you  Cliff for the changes.

from http://trac.puremvc.org/Utility_AS3_StateMachine/wiki/ReleaseNotes:

Passing data between States. When sending a StateMachine.ACTION notification, you may include any Object as the body of the notification and it will be included in the state-specific 'exiting', 'entering', and 'changed' notifications. This allows, for instance, the data collected from a UI form in the 'DATA_ENTRY' state to be passed to the 'DATA_SAVING' state when the form's 'Save' button is pressed, for instance.

This is really very useful!!

A more 'real-world' demo will be forthcoming.

I know, I know. You are very busy:)
But I can't stop myself from asking: when?
Can you give us an approximate time frame? 1 week, more weeks, 1 month?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 04, 2009, 06:01:53
Hi Ondina,

I was actually thinking about this as I was waking this morning. Its an important thing to get out there and will happen.

However, I'm full-on busy at the moment, I just can't say, though I wish I could. If it weren't for the pesky business of having to actually do other stuff for a living I'd get way more done here. :(

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Jason MacDonald on March 04, 2009, 07:11:19
However, I'm full-on busy at the moment, I just can't say, though I wish I could. If it weren't for the pesky business of having to actually do other stuff for a living I'd get way more done here. :(

Try to spend a little time solving the problem of human cloning. Work that out and all your time problems will go away ;)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on March 04, 2009, 07:41:28
Hey Cliff


After I wrote the previous post I found Neil's example:

http://revisual.co.uk/?tag=statemachine (http://revisual.co.uk/?tag=statemachine)

which is cool also because it combines StateMachine with the AsynchCommand ,  but it's the old version of StateMachine and I still don't know how to apply it to CRUD operations.


I was actually thinking about this as I was waking this morning. Its an important thing to get out there and will happen.

That's because people like me who want this cool utility  so badly, think intensively  about it while you are sleeping.;-)


However, I'm full-on busy at the moment, I just can't say, though I wish I could. If it weren't for the pesky business of having to actually do other stuff for a living I'd get way more done here.
I  know what you are talking about.
And how short a day is when you want to have lots of things done by the end of the day.

Actually I kind of feel bad right now.  I'm trying to use your framework and those utilities for my current project  (that I'm working on for a living) while you guys support us ( the community) for free in your spare time. There should be  a “Donate” section on the web-site. It wouldn't make you rich, but maybe it would help you cover the costs for the website?


Oh  I just saw the better solution that Jason suggested.
I also say YES to Cliff's cloning
( 1564-1 = 1563 clones needed?)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on March 04, 2009, 09:27:55
I'll see if I can update those demos for the latest build...

though, they might not be more useful than they are at the present


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on March 04, 2009, 09:43:57
Thank you Neil.

In the meantime I'll look at periplum, that reminds me of Cirque du Soleil:)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: gjastrab on March 05, 2009, 02:18:38
Don't hold your breath on the demo. I'm steaming on a project that you'll all hear much more about very soon. I will be working on something, but spare time is low right now.

Hey everyone, I just pushed up a demo utilizing these new changes in StateMachine to github.  Please check it out there until Cliff moves it into a demo page here (if he thinks its worthy)  ;)

http://github.com/gjastrab/puremvc-statemachine-1.1-login-demo/tree/master


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on March 06, 2009, 01:57:03
Hey Greg,

I've downloaded your example. Yes, it is useful, at least for newbies like me!!

I'm going to play around with it and see how I can use this “changed” state with notifications for other states.

If you already know how to use the new features of the StateMachine why don't  you try to modify the EmployeeAdmin  or CafeTownsend example as a next level of complexity regarding the StateMachine?
I know it's too much to ask.

Anyway thank you very much for your example:)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Paul Bonneville on March 06, 2009, 09:49:03
Where is the most appropriate place to list the State/Action state machine constants for your application for a strictly AS3 implementation? I'm thinking is should be the main application facade.

The examples I have found are all Flex based and I've seen the constants placed in the main flex application file (StopWatch example) and then in the main application facade in the most recent LoginFSM example.

Also, being a newbie to AS3 and PureMVC, the LoginFSM has a nearly one-to-one correlation between notification constants, states and actions. In a typical PureMVC implementation this would not necessarily be the case since there are only a finite number of application states to move between but a vast amount of application notifications between all the Mediators, Controllers and Proxies depending on your application's complexity. Not all the application notifications are going to affect the state. I am looking more for an affirmation of what I just stated as opposed to trying to make a statement. Do I have it right?

It gets a little tricky jumping between Flex and Flash PureMVC examples since we are dealing with either the main Stage (AS3 project) or the main Application (Flex project).

Also, what is behind the convention of appending notification names with "actions/", "states/" etc. Again, it seems to imply a direct correlation between notifications and state changes and I'm pretty sure that is not going to be the case in the real world. It looks like any application notifications that also trigger state changes would be best served by this "appending" naming convention.

I understand the simplicity of the LoginFSM demo, but as someone who is "green" to PureMVC, I want to be sure that I am interpreting things correctly.

Ultimately I am asking if I am interpreting things correctly.

Any input would be appreciated, even if it's just "You're on the right path."

(If I get the hang of PureMVC over the next few weeks I will probably put together a bit more comprehensive AS3-only demo)

Thanks!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 07, 2009, 08:00:35
I keep thinking of that movie Multiplicity and how it would probably end up like that. :)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on March 07, 2009, 08:17:15
Hey Doug

How is Doug doing?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: guyinthechair on March 20, 2009, 08:22:25
My advice is Flex only, so take from it what you can.

Where is the most appropriate place to list the State/Action state machine constants for your application for a strictly AS3 implementation? I'm thinking is should be the main application facade.
This is up to you, but I like to define my constants in my concrete "State" view classes. For example, if I use a ViewStack at the Application level to separate the states, each child of my ViewStack would be considered a State class. I wrote an AbstractState (extends Canvas) that my concrete State view classes extend, these states have enter/exit actions by default defined in AbtractState, then I have a mediator to listen for StateMachine notifications and coordinate the application state changes. But I digress.

The examples I have found are all Flex based and I've seen the constants placed in the main flex application file (StopWatch example) and then in the main application facade in the most recent LoginFSM example.
The StopWatch demo defines State Machine constants similarly to what I described above.

Also, being a newbie to AS3 and PureMVC, the LoginFSM has a nearly one-to-one correlation between notification constants, states and actions. In a typical PureMVC implementation this would not necessarily be the case since there are only a finite number of application states to move between but a vast amount of application notifications between all the Mediators, Controllers and Proxies depending on your application's complexity. Not all the application notifications are going to affect the state. I am looking more for an affirmation of what I just stated as opposed to trying to make a statement. Do I have it right?
Sort of. It's true that you can send any string as the name for a notification. So you could potentially mix up some of your application notifications with notifications sent by a PureMVC utility like the StateMachine. But this is why they try to conform to unique notification names (like "StateMachine/notes/action").
Here's how I generally will define the constants in my concrete State view classes:
:
public class MainState extends AbstractState{
public static const NAME:String = "MainState";
public static const ENTER:String = "Enter" + NAME;
public static const EXIT:String = "Exit" + NAME;
public static const CHANGED:String = "Changed" + NAME;
public static const GOTO:String = "Goto" + NAME;
}

Also, what is behind the convention of appending notification names with "actions/", "states/" etc. Again, it seems to imply a direct correlation between notifications and state changes and I'm pretty sure that is not going to be the case in the real world. It looks like any application notifications that also trigger state changes would be best served by this "appending" naming convention.
Yes, and... yes. I think we're on the same page here...

I understand the simplicity of the LoginFSM demo, but as someone who is "green" to PureMVC, I want to be sure that I am interpreting things correctly.

Ultimately I am asking if I am interpreting things correctly.

Any input would be appreciated, even if it's just "You're on the right path."

(If I get the hang of PureMVC over the next few weeks I will probably put together a bit more comprehensive AS3-only demo)

Thanks!
You're on the right path as far as I can tell. Notifications are generic messages that can be listened for an interpreted by anybody. The convention of naming notifications a certain way is only to avoid conflict between Utility code and your custom code. Happy coding!


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: deltajam on March 23, 2009, 05:52:57
From my reading, it looks like this utility is more for application states ... than view states.  Is there a proper way to handle view states with the State class?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 24, 2009, 04:58:02
Personally, I handle view states using Flex.

If you're not using Flex, and need to implement view states, you probably. Want to pick up a copy of the 'Gang of Four' book Design Patterns. (For ISBN, check the PureMVC Best Practices doc, its mentioned at end of the TOC). Or of course, just google 'State Pattern'.

View states are different from application state as   managed by a Finite State Machine. I won't try to explain it all here; for a fine evenings read, contrast the two by checking out the wikipedia articles on State Pattern and on Finite State Machines.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on March 25, 2009, 02:50:29
this seems to be a question that is asked a lot...
is it possible to pin your last answer up somewhere?? a FAQ page??


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 25, 2009, 01:47:01
True that. I'll try to remember to take care of this tonight.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: deltajam on March 26, 2009, 12:20:16
Cliff, thanks for your reply.

So something like a fullscreen state, would it fall under a view or application state?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 26, 2009, 04:16:25
That depends. Is there any different functionality available in your fullscreen state?
 
-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: deltajam on March 27, 2009, 11:01:25
Hmmm.  Well there are different types of fullscreen states in my app.  The one I was mentioning was when on a landing page and transitioning form the normal screen to fullscreen, it adds and removes components.  When say a video component is viewed, it has small, normal, and fullscreen states.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on March 27, 2009, 01:34:34
Then you're probably looking to implement view states.

You don't see it much, but the nice thing about Flex and RIA's in general (as opposed to HTML) is that you can easily switch your application to a different configuration of functionality and components depending on the turf available to you.

A common case would be an MP3 player which might have a 'tiny' state that has minimal controls to show you the track name, pause/play, and a button to go to 'normal' state, where you might have a grid with all your tracks, a full transport, and perhaps links to buy the track, etc. The 'fullscreen' mode for a MP3 player is typically a visualization mode where you drop the funky 'spectral analysis' science.

So in the MP3 player those three states are all quite different, and more appropriately handled as application states with the state machine. And of course there may be different view states for the components common to different application states.

-=Cliff>


Title: Re: StateMachine - A PureMVC AS3 Utility
Post by: devorb on April 11, 2009, 12:13:49
Hi Guys,
I was trying to connect the state machine with some unit testing (Fluint and FUnit) and came to the following problem: whenever i want to see if a given state was 'changed' I allways see the previous state. Here is my code:
:
<state name={STATE_REGISTERING} changed={REGISTER_TRY}>
    <transition action={ACTION_REGISTER_OK} target={STATE_REGISTERED}/>
</state>

So I make a listener for REGISTER_TRY and in that function I want to check the state if it's STATE_REGISTERED. But it's not, and the reason is that in StateMachine class:

:
// Send the notification configured to be sent when this specific state becomes current
if ( nextState.changed ) sendNotification( currentState.changed, data );

// Notify the app generally that the state changed and what the new state is
sendNotification( CHANGED, currentState, currentState.name );

In my code the CHANGED notification upadtes the status variable(I listen for this in a Mediator)
So you see, the notification with my data is coming sooner, and the notification of the state changed is coming later, so my status variable is changing later, so I allways see the previous state first.
So what I did, I replaced the 2 lines with each other, and now my state changes first, then comes my notification where I can check the state...

:
// Notify the app generally that the state changed and what the new state is
sendNotification( CHANGED, currentState, currentState.name );

// Send the notification configured to be sent when this specific state becomes current
if ( nextState.changed ) sendNotification( currentState.changed, data );

Is it an error or am I doing something the wrong way?


Title: Re: StateMachine - A PureMVC AS3 Utility
Post by: puremvc on April 11, 2009, 05:23:53
:
<state name={STATE_REGISTERING} changed={REGISTER_TRY}>
    <transition action={ACTION_REGISTER_OK} target={STATE_REGISTERED}/>
</state>
So I make a listener for REGISTER_TRY and in that function I want to check the state if it's STATE_REGISTERED. But it's not

You're just interpreting your FSM incorrectly.

In this case, when the StateMachine sends REGISTER_TRY, its current state will be STATE_REGISTERING. Your definition says that REGISTER_TRY is the note to send when the state has fully been changed to STATE_REGISTERING. Further, it says that whenever the action ACTION_REGISTER_OK is sent while in the state STATE_REGISTERING, that we should begin a transition to the state STATE_REGISTERED.

The state specific changed note is sent first by design. It is the last user definable step in the transition, executed once the machine has reached the state in question (the currentState property within the machine has just been updated to the new state at this point) and has with it any data you were tunnelling from the previous state. This is where you should kick off any actions that work with that data or are only executed for this transition.

The more generic StateMachine.CHANGED note is informing you that all user defined notes in the transition (exiting, entering, changed) have been sent and the machine will now become quiescent until a new StateMachine.ACTION is received.

On the StateMachine.CHANGED note, you can, with all certainty, be sure that there is nothing else to be done. If it were switched around as you suggest, then there may or may not be something left to do depending on whether there's a state-specific changed note defined.

I am using both notes successfully throughout my apps at the moment with no odd behavior.

-=Cliff> 



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 21, 2009, 05:15:49
re: state layout "middle-ware" application
just to say I have finally got round to looking at the flare framework, and it seems pretty straightforward to use (once I got my head around it).
so I might start throwing up some tests (when I find the time).

unfortunate turn of phrase... maybe "throwing out" would have been better.




Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 24, 2009, 07:03:25
just a thought...

If the StateMachine is queried reguarding the current state during an entering notification, it will return the previous state.

I was wondering if there should be a neutral StateTransitionState, so the transitionTo method would read
something like.

I'm not sure if this would make any major practicle difference but it would be slightly more "truthful".

:

{
            // Going nowhere?
            if ( nextState == null ) return;
           
            // Clear the cancel flag
            canceled = false;
               
            // Exit the current State
            if ( currentState && currentState.exiting ) sendNotification( currentState.exiting, data, nextState.name );
           
            // Check to see whether the transition has been canceled
            if ( canceled ) {
                canceled = false;
                return;
            }

            // makes currentState into a neutral State
            currentState  = new StateTransitionState();

            // Enter the next State
            if ( nextState.entering ) sendNotification( nextState.entering, data );
            currentState = nextState;
           
            // Send the notification configured to be sent when this specific state becomes current
            if ( nextState.changed ) sendNotification( currentState.changed, data );

            // Notify the app generally that the state changed and what the new state is
            sendNotification( CHANGED, currentState, currentState.name );
       
        }



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on April 24, 2009, 12:50:17
Actually, after some recent talks with Simon Bailey, I'v been thinking of adding another cancel check after sending the entering note for the next state, but before setting current state to next state. That would give that note some teeth in terms of acting as a given state's entry guard. Why should the exit state be the only side of the transition with a guard.

An exit guard let's you keep users from leaving a state without saving or abandoning edits, for instance.

An entry guard is good for keeping unauthorized persons from accessing certain functionality.

So when that entry guard rejects entry to a state, we wnt to simply abort the transition, remaining in the existing state.

-=Cliff>   


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 25, 2009, 03:08:20
yes, that sounds good.
I have stopped using the entering notification for a state in favour of the entered one in 1.1, simply because it has no more value, and actually "lies" about the current state.

Cancelling a transition in the entering state would give it its power back, because I think that its job is a very different one than the entered.

so if you cancel an entry note, the state will revert back to the previous state, and trigger its entering state again (as its state's exiting note will have been sent. )

And if no cancellation is made, there will still be that little lie about the current state. What do you think of a neutral state (that holds previous and next state) to cover the small period between exiting the old state and before entering the new?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 25, 2009, 10:03:05
like this?
:
protected function transitionTo( nextState:State, data:Object=null ):void
        {
            // Going nowhere?
            if ( nextState == null ) return;
           
            // Clear the cancel flag
            canceled = false;
               
            // Exit the current State
            if ( currentState && currentState.exiting ) sendNotification( currentState.exiting, data, nextState.name );
           
            // Check to see whether the transition has been cancelled in the exiting state
            if ( canceled ) {
                canceled = false;
                return;
            }
           
            // Enter the next State
            if ( nextState.entering ) sendNotification( nextState.entering, data );

           // Check to see whether the transition has been cancelled in the entering state
            if ( canceled ) {
                canceled = false;
                 if ( currentState.entering ) sendNotification( currentState.entering, data );
            }else{
                 currentState = nextState;
            }
       
            // Send the notification configured to be sent when this specific state becomes current
            if ( currentState.changed ) sendNotification( currentState.changed, data );

            // Notify the app generally that the state changed and what the new state is
            sendNotification( CHANGED, currentState, currentState.name );
       
        }


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on April 25, 2009, 10:48:53
The thing is when we are entering a state, we're not *really* in that state. If you are 'entering' your office, you're really still in the hallway or the doorway until you're fully in the room, right? At which point it is valid to say that your state has 'changed' from being in the hallway to being in the office' at any time before, you might still bail out and go down the hall to get coffee. And I'm not sure there's any value ti isolating the point in that transition when you're 'in the doorway'; no longer in the hall but not yet in the room. Its like purgatory, what is there to do there, really?

By not changing the current state untill we've triggered the previous state's exiting guard and the next state's entering guard, we can cancel at either point and nothing more need be done. There won't be a re-transition to the previous state because you never left it. If you want to do anything that rearranges the view do it on the 'changed' note for the destination state. That's the first point at which you can be sure you're in the new state.

-=Cliff> 


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 25, 2009, 11:04:38
well, I guess it depends how you define these things.

I would say that if you are going from the hallway into the office you leave the hallway, and enter the office by passing through the doorway. And the doorway is neither in the hallway, nor is it in the room, it is the place that connects them (though I agree that in a synchronous system this transition phase has much less value than in an asynchronous one).

The way I have seen the entering phase is as a preparation phase. You use it to prepare the correct environment for that state, and while its being prepared, you arn't in that state, because its not fully prepared. The entered note indicates this. The exiting state is the same but in reverse. As soon as you start de-preping that state it is no longer in that state, but in a dismantling phase.

As you go through the doorway, you switch the light off in the hallway, then you switch on the light in the office, and walk in (ok, maybe not always in that order but lets stick with it).

It seems that the only use for the entering and exit notes in your suggestion are as a hooks  to allow cancellation of the transition. You can no longer, for example use the entering phase to say, disable interaction, and turn it back on on the exiting, because if the next state's entering phase cancels the transition, the user interaction is not switched off again, breaking state's environmental safety, which is surely the whole point of having a FSM.

Looking again at this, I see that it is the entering phase that can be used only as a cancellation hook. The preparation of the state can be done in the changed note. So you can check whether the conditions are right on entering, when you hit the changed note, disable user interaction, and do what is to de done in that state, then on exiting enable interaction again.  If the next state cancels the transition, the preparation is done on the entered, so the states environment is not compromised.  

OK

So thats alright then.

(though I think that
a) the names of the states are no longer quite as descriptive and
b) it would need good documentation of the phases and the consequences of cancelling in the wrong places.)



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 26, 2009, 03:53:29
no, thats not right, because with your description, on cancellation of a transition, the entered phase will NOT be reinvoked.  OK, I go with the non reinvoking of the entering phase, but if a state's exiting phase has been invoked, its entered phase must be reinvoked if cancelled. Otherwise you can't maintain the state's proper environment

am i making sense?




Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on April 26, 2009, 03:22:14
Your considering the exiting and entering notes as being part of the state during which you might do some activity related to that state that you'd have to undo.

What I'm saying is that you use those notes as exiting or entering GUARDs, not 'phases'.

Guards keep you from leaving or entering a state. If you are stopped by the guard, that's it. So don't assume you'll get past the exit guard, and therefore do any teardown on the exiting note only check to see if they can leave.

Nor should you assume you'll get past the entry guard for the next state until you try. Again you may be stopped, and that's it.

If either guard stops you the state doesn't change, period.

Therefore, only on the new state's 'changed' note are you in the new state, and only then do you perform any activities related to being in that state.

This keeps the transition process simple and predictable. No need to re-enter a state you never left from a state you never made it to.

-=Cliff> 


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 26, 2009, 03:44:03
OK, cool...
lets say I've navigated the exit guard of a state successfully, and done my teardown.  However the next state's entry guard has forbidden entry. So I am still in the previous state, but I have already torn it down...
how do I overcome this?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on April 26, 2009, 05:16:59
By holding off on the teardown intil the state has changed.

For instance let's assume you have a view stack with children like product chooser view and shopping cart view.

Let's say that on the change of state from product chooser view to shopping cart view, you change the index of the view stack to the corresponding view. This happens as either as a result of the state specific-'changed' note or from the StateMachine.CHANGED note.

So in the hideEffect handler for the product browser, ii do any visual outties I want to, and from the hide handler, I kick off any commands that need to run to do logic.

Likewise in the shopping cart view's showEffect handler, I take care of any visual intro, and in the show handler I kick off any logic for getting the data for the new view.

So again there are two bardos that must be crossed before a transition is complete; the exiting and entering guards. Don't count your chickens before they're hatched by doing any teardown or(build up) in anticipation of a state change that may not happen.

Restrict exiting and entering code only contain guard logic (go/no go) logic.

Also, remember that the code that sends the StateMachine.ACTION to initiate a state transition can asume the burdon of doing async user interactions like 'Are you sure you want to exit this state without saving?' And waiting for your cancel or ok before proceeding. This is easy to do while in the stability of a state but not while doing a transition, where a sequence of code is executing

You can always have whatever code would have sent the StateMachine.ACTION instead check if you want to save and handle it before sending the ACTION that kicks of the StateMachine's transition. Then the exiting guard can check a confirmation proxy for the flag that tells it it can go. No async required at that step.

So part of it is not getting too fancy with the guards; let it be as easy for them do decide go/no as it is for the bouncer to decide who to let into the club. Let the guard rely on braun not brains. 'You're not on the list, beat it' or 'I'm sorry I can't let you leave the room, the detective gave strict orders'.

The list maker and the detective have already done their work, the guys guarding the doors are just following orders.

In practical terms, be go don't kick off the state change until your reasonably sure it will go through) and allowing the machine to maintain an atomicity in the transition. Nothing happens unless everything happens. No partial state change undo's to manage.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 27, 2009, 01:51:09
so a change of conception in my head, not necessarily in the code. :)

will need to think about this.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 28, 2009, 02:09:45
Just starting a new project, so I'm going to try these potential changes out, see what comes out.
will let you know.

is this what you were thinking:

:
protected function transitionTo( nextState:State, data:Object=null ):void
{
// Going nowhere?
if ( nextState == null ) return;

// Clear the cancel flag
canceled = false;

// send exiting notification for the current State
if ( currentState && currentState.exiting ) sendNotification( currentState.exiting, data, nextState.name );

// Check to see whether the exiting guard has been canceled
if ( canceled ) {
canceled = false;
return;
}

// send entering notification for the next State
if ( nextState.entering ) sendNotification( nextState.entering, data );

// Check to see whether the entering guard has been canceled
if ( canceled ) {
canceled = false;
return;
}

// only change state nownow
currentState = nextState;

// Send the notification configured to be sent when this specific state becomes current
if ( nextState.changed ) sendNotification( currentState.changed, data );

// Notify the app generally that the state changed and what the new state is
sendNotification( CHANGED, currentState, currentState.name );

}




Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on April 28, 2009, 09:29:58
Yes, this looks correct. The following was the only code change (inserted), right?

:
// Check to see whether the entering guard has been canceled
if ( canceled ) {
canceled = false;
return;
}

If so, you can check in the change and I'll build and rev the project. I'm positive about the 1.1 state of affairs and the usage of exiting being a guard and of entering being essentially useless. As a guard, both notes have an unambiguous reason for being.

Right now, I barely use either of them, relying entirely on StateMachine.ACTION, per-state-'changed' and StateMachine.CHANGED notes to drive the application and it is squeeky clean. I do use the exiting in one place to cancel a transition away from a state, and it works fine. Now, If entering could keep me from transitioning to prohibited states (even if I was ok to leave my previous state), then it would rock.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on April 28, 2009, 09:32:44
yep, thats right


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on May 06, 2009, 01:41:51
have stuck a demo visualisation of the FSM Markup Utiliy I have been working on here:http://revisual.co.uk/?p=501 (http://revisual.co.uk/?p=501).



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: newtriks on May 06, 2009, 06:50:20
Cheers guys, I really like this utility and the new logic you have implemented was exactly what I was looking for in a demo I was putting together.  So I have integrated the new code as detailed above in the following post:

Combining the PureMVC StateMachine Utility with Slacker http://cli.gs/pSUVae (http://cli.gs/pSUVae)

Cheers,

Simon

[ Twitter ] @newtriks
[ Blog ] http://www.nutrixinteractive.com/blog/ (http://www.nutrixinteractive.com/blog/) 


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on May 06, 2009, 07:19:58
@cliff, I have added the entering guard code in to the svn


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on May 06, 2009, 07:51:39
@Neil, Re the FSM visualizer - I LOVE IT! If those lines could be annotated (perhaps in italics?) with the actions that trigger the transitions being shown, that would be over the top awesome. Probably be nutty hard to do though if their library doesn't expressly provide for line names. :)

@Simon, heh, any chance you could rename that demo to 'Slack Against the Machine' ? :)

-=Cliff>



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Ondina on May 07, 2009, 05:13:51
@Cliff

Hmm... you know what? Your demo is not good at all. It distracted me from my goal (learning more about StateMachine). It made me listen to the cool sound tracks and after a while my mind entered in a state of not caring anymore about FSM&Co  :)

O.K.  Back to the earthy state... Thank you for the much awaited demo! I'll come back with questions after trying it.

One little observation, not related to puremvc:
I have an external sound card, that was off by the time I started your demo and that made the app throw an error when I was  trying to select an item. Maybe you should catch this(sound off) somewhere in your code.


@Simon

I'll post my questions regarding your demo in here instead of your blog.

Here the FSM:
var fsm:XML =
<fsm initial={StateConstants.LOAD}>
<state name={StateConstants.LOAD}>
<transition action={ActionConstants.ACTION_LOAD} target={StateConstants.LOGIN}/>
</state>
<state name={StateConstants.LOGIN} exiting={ ApplicationFacade.CHECK_LOGGED_IN }>
<transition action={ActionConstants.ACTION_USER} target={StateConstants.STATE_2}/>
<transition action={ActionConstants.ACTION_ADMIN} target={StateConstants.STATE_3}/>
</state>
<state name={StateConstants.STATE_2} changed={ ApplicationFacade.CHECK_LOGGED_IN }>
<transition action={ActionConstants.ACTION_LOGIN} target={StateConstants.LOGIN}/>
<transition action={ActionConstants.ACTION_THREE} target={StateConstants.STATE_3}/>
</state>
<state name={StateConstants.STATE_3} changed={ ApplicationFacade.CHECK_LOGGED_IN } entering={ ApplicationFacade.CHECK_ADMIN }>
<transition action={ActionConstants.ACTION_LOGIN} target={StateConstants.LOGIN}/>
<transition action={ActionConstants.ACTION_TWO} target={StateConstants.STATE_2}/>
</state>
</fsm>;

1.Why do you need  changed={ ApplicationFacade.CHECK_LOGGED_IN }  in state 2 and 3? You  can be in those states only after a successfully login, right?
2.Then in the LOGIN state I expected it to do something in case the password/username was wrong, because in your CheckLoginStatusCommand you have this:
override public function execute(notification:INotification):void
{
      if( !lgnPrx.login_success ) sendNotification( StateMachine.ACTION, null, ActionConstants.ACTION_LOGIN );
}
I modified it to see what was going on:
if( !lgnPrx.login_success ){
   Alert.show("wrong pw");
   sendNotification( StateMachine.ACTION, null, ActionConstants.ACTION_LOGIN );
} else{
   Alert.show("Hi "+lgnPrx.username);
}
And if login_success==true  then it does say “Hi username”, after logging in.
It is actually normal, because it happens only  on exiting the LOGIN state.
So sendNotification( StateMachine.ACTION, null, ActionConstants.ACTION_LOGIN ); is not doing anything.
Was your intention to cancel the transition to the next state?


The cool thing is: entering={ ApplicationFacade.CHECK_ADMIN }, because I can do something like this:

CheckAdminStatusCommand
...
if( !lgnPrx.userAdmin ) {
sendNotification( StateMachine.CANCEL );
Alert.show("you are not admin");
}
...
when the user with restricted access clicks on the admin button.

Thank you  Cliff, Simon, Neil, gjstrab  for your demos and explanations/posts.

Ondina


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on May 09, 2009, 11:04:29
More functionality to the FSMVisualisation (we need a name, any suggestions?).
http://revisual.co.uk/?p=517 (http://revisual.co.uk/?p=517)

@Cliff Yes, nutty hard, haven't fond a way to label them actions, but surely there will be. Am thinking of a rollover info box that will show all the info.

functionality now includes adding/deleting states adding/deleting actions.  Very crude at the mo, will whip up something more appealing when I have done more functionality.




Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: nilsm on June 14, 2009, 05:49:02
Quick questions regarding the StateMachine:

Why is the 'currentState' getter on StateMachine protected, rather than public?

(Enjoying working with it, by the way, but this has thrown up some problems for me.)

Thanks - Nils.

[Edit: Question about multicore removed - found it in ZIP file]



Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on June 14, 2009, 06:01:26
You can get the current state trough the viewComponent property (but you will have to cast it)... mmm doesn't really seem intuitive.
The is no multi core, as there does n't need to be.  You can register a StateMachine in each core, and if necessary you can use the pipes util to communicate between them.

Though I guess a layer of abstraction above these two utils could make the whole easier to use.  Sounds like an interesting project ( I wonder if Fabrication has incorporate something of the like). I'm a bit busy with the FSMVisualiserat the mo - why don't you have a go ;~)

BTW, after my blog being hacked, and my head deep in bread and butter work, I've actually had a bit of time spare to work on the FSMVisualiser, so I might have something more solid to post next week.

cheers


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on June 14, 2009, 06:04:00
Ah, I took your question to mean why are the StateMachine utils exactly the same between standard and multicore (which they are).


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: nilsm on June 14, 2009, 06:20:12
Hi Neil,

thanks for the super-quick reply (esp on a Sunday).

I'll cast the viewComponent, that's easy enough. Don't know whether Fabrication uses FSM but communicating with pipes shouldn't be too hard. I'm also too busy to work on anything like that - but thanks for the suggestion ;)

Cheers - Nils.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: nilsm on June 14, 2009, 06:55:29
ENTERING / EXITING in addition to CHANGE notifications

I'm just in the middle of writing some code to manage a state history and it occurred to me that it would be useful to have generic ENTERING / EXITING notifications sent by StateMachine, which also contains the additional notification body that is sent when sending the state-specific 'entering', 'exiting' notifications.

At the moment, you can only retrieve the state instance itself by listening to the StateMachine.CHANGED notification - but you can't record what additional information was sent when entering the state.

My question is: Is there a trick for retrieving that information when the CHANGED notification is received?

Just in the middle of coding, sorry if the post doesn't make much sense ;)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on June 14, 2009, 08:48:45
What would you do with the data on these generic ENTERING and EXITING notes?

I see the state-specific entering, exiting and changed announcements as being very much internal to that transition. For instance, going between a COLLECTING and SAVING state, it's reasonable to expect that the COLLECTING state's exiting guard would know the data being sent and be able to make sure it's all there or cancel if not. It has specific knowledge of the COLLECTING state's purpose and output.

But a generic EXITING announcement would only be useful to some ungainly actor that knows about all the states and their outputs (specifically what to cast their note bodies to).

And to send a generic ENTERING and EXITING note is to tempt the developer to begin doing teardown/buildup of the interface and then wonder how to undo it if the transition is canceled.

-=Cliff>


Title: access to transition list in runtime
Post by: Djaffy on December 17, 2009, 11:36:29
Hi everyone,

Is there any possibility in runtime to get the list of all possible transitions from current state and the list of actions initiating these transitions as well? For instance I want to make a mediator that handles StateMachine.CHANGED notification and creates the button for every possible transition (onClick handler initiates sendNotification(StateMachine.ACTION, null, Actions.SOME_ACTION)). How can I do that?

thanks in advance


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 17, 2009, 12:55:16
from the top of my head, you can get the current state using getViewComponent() on the StateMachine mediator.

For accessing stuff from the State, you 'ld need to subclass it, and add a "get all actions" method.
However, you couldn't use the standard FSMInjector for creating that class, but you could subclass it, or roll you own.

that answer you?

cheers


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 18, 2009, 10:19:42
Is there any possibility in runtime to get the list of all possible transitions from current state and the list of actions initiating these transitions as well?

Without subclassing or breaking the encapsulation of the StateMachine, you could instead preserve the XML that the InjectFSMCommand uses to initialize the FSMInjector. While the InjectFSMCommand has the XML in hand, have it instantiate and register a Proxy to hold onto the FSM for later recall:

First cut InjectFSMCommand
:
override public function execute ( note:INotification ) : void
{
// Create the FSM definition
var fsm:XML =
<fsm initial={FSMConstants.INTERNET_CHECKING}>

<state name={FSMConstants.INTERNET_CHECKING}>
<transition action={FSMConstants.INTERNET_ONLINE} target={FSMConstants.UPDATE_CHECKING}/>
<transition action={FSMConstants.INTERNET_OFFLINE} target={FSMConstants.INACTIVE}/>
</state>

<state name={FSMConstants.INACTIVE}>
<transition action={FSMConstants.INTERNET_ONLINE} target={FSMConstants.UPDATE_CHECKING}/>
</state>

<state name={FSMConstants.UPDATE_CHECKING} changed={FSMConstants.CHECK_FOR_UPDATE}>
<transition action={FSMConstants.UPDATE_PENDING} target={FSMConstants.UPDATE_AVAILABLE}/>
<transition action={FSMConstants.NO_UPDATE_PENDING} target={FSMConstants.LICENSE_CHECKING}/>
</state>
.
.
.
</fsm>;

// Create and inject the StateMachine
var injector:FSMInjector = new FSMInjector( fsm );
injector.initializeNotifier(this.multitonKey); // if using MultiCore
injector.inject();

// Stash the FSM for later reference
facade.registerProxy( new Proxy( FSMConstants.ProxyName, fsm ) );
}

Notice you don't even have to create a new Proxy class (unless you want to give it some convenience methods for querying the XML structure. Otherwise you just retrieve the proxy and get its data, casting to XML.

Later in your Mediator, you could do something like this:

First cut MyMediator
:
override public function handleNotification( note:INotification ):void
{
switch ( note.getName() )
{
case StateMachine.CHANGED:
var state:State = note.getBody() as State;
var fsm:XML = facade.retrieveProxy(FSMConstants.ProxyName).getData() as XML;
var transitions:XMLList = fsm.state.(@name==state.name)..transition;
var actions:Array;
for each (var transition:XML in transitions);
{
actions.push (transition.@action.toString);
}
myViewComponent.addButtons(actions);
break;

.
.
.
}
}

That should come close to solving the problem, but it's the brute force implementation though. It puts too much domain logic in the Mediator. What if another Mediator needed to do something a similar? You'd soon find your Mediators doing lots of local XML manipulation, and likely repeating some of it.

So, we would probably want to refactor/move this domain logic out of the mediator and into a custom FSMProxy class.

Second cut FSMProxy
:

public class FSMProxy extends Proxy
{
public static const NAME:String = 'FSMProxy';

public function FSMProxy( fsm:XML )
{
super ( NAME, fsm );
}

// Return a list of valid actions for the given state as an array of strings
public function getActionsForState( state:State ):Array
{
var transitions:XMLList = fsm.state.(@name==state.name)..transition;
var actions:Array;
for each (var transition:XML in transitions);
{
actions.push (transition.@action.toString);
}
return actions;
}

private function get fsm():XML
{
return data as XML;
}
}


Second cut InjectFSMCommand
:
override public function execute ( note:INotification ) : void
{
.
.
.

// Stash the FSM for later reference
facade.registerProxy( new FSMProxy( fsm ) );

}

Now we can simplify the Mediator and remove the domain logic:

Second cut MyMediator
:
private var fsmProxy:FSMProxy;
override public function onRegister():void
{
    facade.retrieveProxy(FSMProxy.NAME);
}

override public function handleNotification( note:INotification ):void
{
switch ( note.getName() )
{
case StateMachine.CHANGED:
var state:State = note.getBody() as State;
var actions:Array = fsmProxy.getActionsForState(state);
myViewComponent.addButtons( actions );
break;

.
.
.
}
}

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 18, 2009, 11:01:15
Hey, nice thinking cliff :)


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Djaffy on December 18, 2009, 02:59:53
Cliff and Neil, thank you guys! ))


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: Neil Manuell on December 22, 2009, 05:16:43
Actually, Cliff, mind if I use this Idea for my Domino project... it's a nice solution for a similar problem I was pondering on...


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on December 27, 2009, 11:46:13
By all means, if it helps.
 :D
-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 07, 2010, 07:31:14
So I would like to be able to define sub-FSMs, for lack of a better term. Here is an example for why:

Say I have an application that has a menu with items/states A, B, and C. I select item B and I now am brought to a complex form with states X, Y, and Z. If the main menu is still accessible then I could be half way through the form and change to item C. I would want state B to be able to respond to this rather than having states X, Y, and Z be able to handle it. That would make things a lot simpler. Is this possible without having separate cores that have separate FSMs? Can I make a hierarchical FSM?

I'm new to using this utility and may be missing something.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on May 08, 2010, 12:48:48
Two answers here.

First is separating view state from application state. That form with states x,y and z is actually a view component in charge of maintaining its own states. Flex has a very nice facility for this but even without it, its not much of a problem for a component to properly encapsulate this behavior.

Second is with MultiCore you can have an FSM per core.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 10, 2010, 05:30:55
Thanks! I was confused as to what should be handled in the FSM and was trying to handle both the view and application states I think.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 10, 2010, 08:25:30
So I have two commands listening on most every FSM notification. One is basically a logging command that keeps FSM history and listens on all actions, changes, and cancels. The other is the one that does all the work. I ran into some unexpected behavior with this. Here is the scenario:

1. Mediator fires off an notification with FSM Action #1.
2. Logging Command picks it up and Action #1 and logs it.
3. Working Command picks up the corresponding CHANGED event (Changed #1) from the FSM and it does its work (not asynchronously).
4. The Working Command's work causes a state change and fires off Action #2.
5. Logging Command picks up Action #2 and logs it.
6. Logging Command picks up Change #2 and logs it.
7. Logging Command picks up Change #2 and logs it.

It looks like step 7 should be handling the changed event from step 1. I am assuming that since the state changed in the FSM again before the first CHANGED event finished propagating that it pulled the current state. But I thought that the original event would maintain the integrity of its type variable. Is that variable somehow still bound to the FSM's original current state variable?

If I comment out the code that does the work and in turn fires off the Action #2 this is what happens:
1. Mediator fires off an notification with FSM Action #1.
2. Logging Command picks it up and Action #1 and logs it.
3. Logging Command picks up Change #1 and logs it.

Also, I could probably get rid of this logging thing if I knew a way to get the current state at will rather than storing the state each time a CHANGED event is fired off. Is there a way to do this?

Currently this isn't an issue for me, it is just unexpected behavior.


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on May 10, 2010, 09:24:07
But I thought that the original event would maintain the integrity of its type variable. Is that variable somehow still bound to the FSM's original current state variable?
It is a reference to the FSM's current state variable.

I think the problem is that it had no async break, so the stack was not allowed to collapse between states. Try having the working command that fires of the action for state 2 do this asynchronously. That is replace your sendNotification call like this:

:
override public function execute(note:INotification):void
{
         // do your stuff
                     .
                     .
                     .
         // then, a brief async pause
               var timer:Timer = new Timer( 50, 1 );
               timer.addEventListener( TimerEvent.TIMER, onTimer, false, 0, true ); // use weak reference
       timer.start();
}

        private function onTimer( event:TimerEvent ) : void
        {   
               Timer(event.currentTarget).stop();
       sendNotification( StateMachine.ACTION, null, MyAppConstants.STATE_TWO );
}

Let me know if this straightens you out. If so, it might be worthwhile to amend the StateMachine with this as an internal behavior.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 10, 2010, 10:19:41
Couldn't get the timer to work, maybe because it is in a command. But I used an asynchronous DB call and it fixed the issue.

The original DB call wasn't asynchronous because I was just running it on the flex side and hacking things in the proxy. When I am done it will be asynchronous so I probably wont hit this issue.

Is the issue that the state change event type is being set by reference rather than by value?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 10, 2010, 11:50:41
This may just be that I am still a little confused of the difference in what is application and view states. I am trying to control a tabnavigator with the FSM. I don't know of a good way to do this besides catching the index change event, canceling it, and then if it successfully transitions to the next state I will set the tab navigator to the new index. Is there a better way to do this?

How would you define the difference between view state and application state? I have a simple user admin panel I decided to test the FSM utility out on. It has two tabs; one is for searching users and the other for creating new users. From the searching tab you can deactivate/activate/edit a user. If deactivating/activating you stay on the same page and are alerted to the outcome of the db call. If you edit you are sent to the create page and the form is pre-populated. Submitting changes to a user or creating a user will take you back to the search page.

The issue I'm running into is that a user can hit a tab in the tab navigator while the application is in the "STATE_DELETE" state or something and the view will progress but the fsm wont because it is waiting on a response from the server.

Here is my simplified FSM XML:
:
<fsm initial={INITIAL_STATE}>
<state name={STATE_SEARCH} changed={CHANGED_SEARCH}>
<transition action={ACTION_CREATE} target={STATE_CREATE} />
<transition action={ACTION_EDIT} target={STATE_EDIT} />
</state>
<state name={STATE_CREATE} changed={CHANGED_CREATE}>
<transition action={ACTION_CREATE_SAVE} target={STATE_CREATE_SAVE} />
<transition action={ACTION_GO_TO_SEARCH} target={STATE_SEARCH} />
</state>
<state name={STATE_CREATE_SAVE} changed={CHANGED_CREATE_SAVE}>
<transition action={ACTION_CREATE_SAVE_SUCCESSFUL} target={STATE_SEARCH} />
<transition action={ACTION_CREATE_SAVE_FAILED} target={STATE_CREATE_TRY_AGAIN} />
</state>
<state name={STATE_CREATE_TRY_AGAIN} changed={CHANGED_CREATE_TRY_AGAIN}>
<transition action={ACTION_CREATE_RETRY_YES} target={STATE_CREATE_SAVE} />
<transition action={ACTION_RETRY_NO} target={STATE_SEARCH} />
</state>
<state name={STATE_DELETE} changed={CHANGED_DELETE}>
<transition action={ACTION_DELETE_SUCCESSFUL} target={STATE_SEARCH} />
<transition action={ACTION_DELETE_FAILED} target={STATE_SEARCH} />
</state>
</fsm>

Is this a proper use of this utility or should the utility be used in a less granular way?


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: puremvc on May 10, 2010, 01:58:10
I am trying to control a tabnavigator with the FSM. I don't know of a good way to do this besides catching the index change event, canceling it, and then if it successfully transitions to the next state I will set the tab navigator to the new index. Is there a better way to do this? ... How would you define the difference between view state and application state?
It's a bit overly granular. While it's possible to do it just like you mention, you're not gaining a lot by running all the state change logic through the PureMVC apparatus. This is how I define the difference between view and app states.

If all the states you're tracking can be contained in a single view component (even a complex one with several forms), then you're better off calling those view states and implementing them in that component. If no other actors in the system really care about those specific states, then why expose knowledge of them throughout the app needlessly?

Now, if you have several view components that are concerned with a common state, for instance, a header that displays a different banner for each state, a menu bar that displays different items in each state, and a form control that presents a different form in each state, then you have a good reason to call that an 'application state' and implement an FSM to support it. In this way you coordinate the view states of disparate components based on shared updates about the application state.

-=Cliff>


Title: Re: StateMachine - A PureMVC / AS3 Utility
Post by: emurphy on May 11, 2010, 05:29:51
Thanks Cliff, that clears a lot up!