tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/345-fsm-async-statesRobotlegs: Discussion 2018-10-18T16:35:19Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/37261142010-11-10T12:50:39Z2011-02-13T15:22:11ZFSM & async states...<div><p>I like to decouple app state from service / model events. It's
as simple as mediating your contextView and doing:</p>
<pre>
<code>onRegister():void
{
eventMap.mapListener(SomeServiceEvent.DATA_LOADED, relayAsStateEventAction, SomeServiceEvent);
}
private function relayAsStateEventAction(e:SomeServiceEvent):void
{
dispatch( new StateEvent(StateEvent.ACTION));
}</code>
</pre>
<p>Effectively I treat my context mediator - or each module
mediator - as a layer that decouples the application from the
framework.</p>
<p>It's SRP really - your class (service or model) should only have
one reason to change - because the description of its own job
changes. If you import the StateEvent then you'll also have to
change your service if you decide to use a different state machine
implementation.</p>
<p>So - no, my models / services only dispatch situation-agnostic
events that are about themselves. They don't know or care whether
there is a state machine / context etc. That stuff is for mediators
to hook up - and they do it rather well!</p>
<p>A bonus of this approach is that your contextView mediator ends
up giving a very neat, contained description of how the application
hooks together, which, read in combination with the context
mappings, almost entirely describes your application logic, and
makes it pretty easy to do high-level changes on that logic.</p>
<p>Win!</p>
<p>(But nothing will break if you fire your StateEvents from your
models / services).</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/37261142010-11-10T13:29:49Z2010-11-10T13:29:54ZFSM & async states...<div><p>Thanks for the lightning fast reply Stray!</p>
<p>Your response is exactly what I was looking for; I clean way to get the<br />
</p>
<pre><code>dispatch(new StateEvent(StateEvent.ACTION, BootstrapFSMConstants.SOME_SUCCESS_ACTION));</code></pre>
<p>stuff out of my model. I had that icky feeling that I was doing some funk, but wan't clear on how to get rid of it. I think I'll have a crack at the implementation you've described and see how it feels. Thanks again mate!</p>
<p>best,</p>
<p>jc<br />
</p></div>jcetag:robotlegs.tenderapp.com,2009-10-18:Comment/37261142010-11-10T13:39:11Z2010-11-10T13:39:11ZFSM & async states...<div><p>No worries - glad it made sense to you. :)</p></div>Straytag:robotlegs.tenderapp.com,2009-10-18:Comment/37261142010-11-11T17:36:11Z2010-11-11T17:36:13ZFSM & async states...<div><p>I've been working a bit more on this implementation, and for the most part really liking it.<br />
However there is one bit I'm confused on and hopefully someone can clarify. I had assumed (perhaps incorrectly) that one of the benefits of using a FSM is that you have these defined states and the transitions/actions that are allowed in each state so that the machine can check that . My thought was that if my FSM gets an action that is "invalid" I would get an error thrown or some other sort of notice at runtime. Right now it just stops dead in its tracks.</p>
<p>For example if part of my FSM looks like:<br />
</p>
<pre><code><!-- LOAD CONFIG FILE, THIS COMES FROM NativeApp.APPDirectory -->
<state name={LOADING_CONFIG} changed={LOAD_CONFIG}>
<transition action={LOADING_CONFIG_SUCCESS} target={DETECTING_INTERNET_CONNECTION}/>
<transition action={LOADING_CONFIG_FAILED} target={BOOTSTRAP_FAILED}/>
</state>
<state name={DETECTING_INTERNET_CONNECTION} changed={DETECT_INTERNET_CONNECTION}>
<transition action={DETECT_INTERNET_CONNECTION_SUCCESS} target={PREPPING_MODEL} />
<transition action={DETECT_INTERNET_CONNECTION_FAILED} target={BOOTSTRAP_FAILED} />
<!--<transition action={INITIAL_CONNECTION_ON} target={DO_SOMETHING_IF_ON} />
<transition action={INITIAL_CONNECTION_OFF} target={DO_SOMETHING_IF_OFF} />-->
</state>
<!-- PREP MODEL -->
<state name={PREPPING_MODEL} changed={PREPARE_MODEL}>
<transition action={PREPPING_MODEL_SUCCESS} target={BOOTSTRAP_COMPLETE}/>
<transition action={PREPPING_MODEL_FAILED} target={BOOTSTRAP_FAILED}/>
</state></code></pre>
<p>when my app is in LOADING_CONFIG state, I would expect some sort of error thrown/notice if the FSM gets a PREPPING_MODEL_SUCCESS action sent to it. Was I assuming too much?</p>
<p>cheers,</p>
<p>jc</p></div>jcetag:robotlegs.tenderapp.com,2009-10-18:Comment/37261142010-11-30T23:56:19Z2010-11-30T23:56:19ZFSM & async states...<div><p>Hey jce,</p>
<p>I've only read the docs on the FSM but if I recall if it gets an
incorrect state request it'll just ignore it right? I don't think
it'll throw an error though you could probably crack it open and
figure out a way to make it do that :D</p></div>rob