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 2 3 [4] 5 6 ... 10
Print
Author Topic: StateMachine - A PureMVC / AS3 Utility  (Read 108714 times)
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #45 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. :)
Logged
Darshan Sawardekar
Sr. Member
****
Posts: 85


View Profile Email
« Reply #46 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
Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #47 on: January 08, 2009, 07:20:22 »

hey, thats really cool Darshan! :~)

Logged
GroundZero
Newbie
*
Posts: 7


Bling Bling

 - g888z  - Actionscriptdude
View Profile Email
« Reply #48 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!

Logged
cambiata
Newbie
*
Posts: 6


View Profile Email
« Reply #49 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
Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #50 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:~)
Logged
cambiata
Newbie
*
Posts: 6


View Profile Email
« Reply #51 on: January 08, 2009, 12:07:31 »

Aha!
Thank you, Neil!
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #52 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>
Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #53 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
Logged
gjastrab
Jr. Member
**
Posts: 18



View Profile WWW Email
« Reply #54 on: January 12, 2009, 09:35:37 »

Awesome work Darshan, that's slick and elegant!
Logged
gjastrab
Jr. Member
**
Posts: 18



View Profile WWW Email
« Reply #55 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)
}
Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #56 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
Logged
gjastrab
Jr. Member
**
Posts: 18



View Profile WWW Email
« Reply #57 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.
Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #58 on: January 15, 2009, 02:31:48 »

well, since the body is not being used I can see no reason not to
Cliff?

Logged
Neil Manuell
Courseware Beta
Sr. Member
***
Posts: 109


View Profile Email
« Reply #59 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?
Logged
Pages: 1 2 3 [4] 5 6 ... 10
Print