Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


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

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

Pages: 1 ... 8 9 [10]
Print
Author Topic: StateMachine - A PureMVC / AS3 Utility  (Read 166553 times)
emurphy
Jr. Member
**
Posts: 19


View Profile Email
« Reply #135 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.
Logged
emurphy
Jr. Member
**
Posts: 19


View Profile Email
« Reply #136 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.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #137 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>
Logged
emurphy
Jr. Member
**
Posts: 19


View Profile Email
« Reply #138 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?
Logged
emurphy
Jr. Member
**
Posts: 19


View Profile Email
« Reply #139 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?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #140 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>
Logged
emurphy
Jr. Member
**
Posts: 19


View Profile Email
« Reply #141 on: May 11, 2010, 05:29:51 »

Thanks Cliff, that clears a lot up!
Logged
Pages: 1 ... 8 9 [10]
Print