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

Show Posts

* | |

  Show Posts
Pages: 1 [2]
16  Announcements and General Discussion / Getting Started / Re: AsyncCommand and remote proxies on: March 04, 2009, 06:48:45
GUARD isn't necessary. If you want to cancel a transition do it from a command triggered by the exiting note, by sending a StateMachine.CANCEL note.

Yes, I understand (I think) your view of it.

Your view, as I understand it, is that to separate the notion of a test before the transition and the notification on exiting a transition is redundant, and I want to clutter your beautifully simple and elegant model with more baggage that achieves little.

In my view of the world, the fact that entry and exit seem symmetrical means they should be symmetrical in the way they work. Otherwise they contain a buried surprise. So my inclination is to separate the guard condition 'is this transition allowed to happen?' from the always-happen action 'we are now exiting the state'. I feel to mix or combine these two things is 'smelly'.

About right? :-)

FWIW I haven't implemented guards in my fork of the state machine code... (Cliff's voice: Aha!) but nor have I allowed transition aborts in the exit note handler. So far I have kept my conditional code inside the code that will fire the transition.

However, I do think I will need guards at some point.

StateMachine.CHANGED is broadcast at the end of every single state change and allows you to monitor the machine's behavior without signing up for every state-specific 'changed' note. Trust me you need both.

Honestly I don't need it, except, perhaps, for a debug monitor to show me what state the machine is in.

I write code that never queries the current state. The whole behaviour of the state machine is held inside the model, as described in XML. None of my mediators or commands 'know' what the current state is, nor tests it. Nothing. I regard this is a tenet of the way it is written. What happens when a trigger causes a transition is specified uniquely by that transition's action - in the XML. This is the only place where it is specified.

If I alter behaviour in the model, I know that I am not fighting any logic buried in the code in the mediators. I have achieved a clean separation between the structure of the app at top (state machine) level and the next level down (individual commands and mediators interacting with each other). Specific actions may be fired on state exit, entry and specific transition, but the code in the actions is unaware of the transition in which it is taking part. I feel this is in line with the coarse-grained, as-much-mutual-unawareness-as-possible philosophy that underlies PureMCV.

I think we may have drastically incompatible mental models of the way this is done. I am sure I am missing benefits and neat things permitted by your approach.

Never mind. People who agree about everything probably don't understand the issues ;-)

Will
17  Announcements and General Discussion / Getting Started / Re: AsyncCommand and remote proxies on: March 03, 2009, 08:59:14
(Sorry for slow reply - I thought I was following this board, but wasn't.)

@Will, you were absolutely right.

TVM. The nicest thing one programmer can say to another ;-)

I'll have a look at your implementation. From what you say, it sounds much more to my taste.

I think there is still is slight mismatch between the way we think about it. I absolutely don't insist on my point of view, but I thought I'd write it out, so you are aware.

The way I have ended up thinking about it, is as follows:

The Exit note is good for things that must always happen on the way out of a state, no matter where you are going. Entry is similarly good for stuff on the way in. Whereas what I call the ACTION and (I think) you call the 'state-specific changed' note, the extra one that I wanted, allows one to carry out things associated with that specific transition.

For example, in my database editor there is an 'Editing' state.

  • On entry to this state (which can be by making a new record or editing an existing one - I don't care) the Entry action enables the Apply and Cancel buttons.
  • On exit from this state to anywhere (which can be by Applying or Cancelling the edit, or by doing something wild like hitting the logout button) I always want to disable the Apply and Cancel buttons, so this is handled in my Exit note.
  • On the Cancel button's ACTION/'transition-specific changed' note, and only on this particular Cancel transition, I want to call something that restores the record to how it was before. No other transition out of the 'editing' state will call this function.

One thing where we differ: I don't allow a cancel in the Exiting note. I feel by the time you start hitting Entry/Exit/Change notes, you are committed, and the state should change whatever happens.

Instead I want to handle the possibility of cancelling the transition in yet another, optional feature. This would be a GUARD, and it would be called before the Exit note. In effect it is a predicate: 'Do you want to do this state transition?'

So the sequence I envisage on a transition is

GUARD - fires tests that may abort the transition without leaving the old state
EXIT - stuff that always happens when you leave this old state
'Transition-specific note' [your jargon] / 'ACTION' [my jargon] - do specific stuff for this transition
ENTRY - welcome to the new state, wherever you have come from
CHANGED - (Cough) I don't see what this is for... How does it differ from ENTRY? Why two?

Will
18  Announcements and General Discussion / General Discussion / Re: Using the FSM on: February 23, 2009, 07:43:39
So don't worry, I'm not dismissing your ideas out of hand, I just don't see the need yet myself for making major changes. As I implement, I'll refer back to this post if I find myself scratching my head about how to proceed.

Fair enough. I'll leave you alone to have a go.

Will
19  Announcements and General Discussion / General Discussion / Re: Using the FSM on: February 23, 2009, 02:17:49
Wow, this was a really long post.

I apologise for making it such a long post. This was an error on my part. I felt the need to 'dump' the various discoveries I have made.

I'm on a phone and can't see the uml,

That's a disappointment. Does the url not resolve?

http://www.willwatts.pwp.blueyonder.co.uk/images/StateChart.png

I'll happily e it if you would be interested. It's 25KB or so.

but I will say this: the state machine scope is very much narrower than I believe you'd like. This is by design. If you want to see what can happen when you really go down thr rabbit hole with this, just have a look at the SCXML schema (after which our xml was loosely based):

http://www.w3.org/TR/scxml/

The point is that's awesome, but way more scope than we needed to start and than most would be willing to swallow just to try out an FSM in their app.

I appreciate this point. Really I do. I admire the philosphy of spareness. I understand that you do not wish to add features for their own sake, and guard fiercely against glib requests for extra baubles. I agree with this principle very much.

I started off, at your suggestion, trying to use the State Machine Library to solve my problems, which I have shared with you in the earlier thread, and you have been most helpful about.

I had (and have) no ambitions to extend your State Machine library as a sort of 'look what else you can do with state machines' thing. I was very reluctant to touch the code as supplied.

I found that I couldn't make it do what I needed it to do, however hard I tried. It was very frustrating, because I could almost do it.

However, by making a very few simple alterations, and adding one VO class for transition, I found I could. I have added maybe a dozen lines of code.

These alterations feel like genuine design tweaks, and not frigs to dig me out of my own particular holes. They were, after all, implementing basic FSM features.

It felt like I was slightly battle-hardening a design that supported the canonical stopwatch fine, but maybe had not yet been much used in real life applications.

I appreciate it feels like I am being cheeky and stomping about over this. I apologise. I got excited by the difference in utility between the library as presented, and the library with a very little functionality added. I found that it solved my problem, and opened up many more possibilities, and addressed some other worries I had about organisation of my app.

I wanted to share, but I dare say I have put you and everybody else off with what comes over as a very high handed message. I can only ask you to excuse my excitement.

And 'events' were renamed actions because event would be confusing with flash events, which they're not, while triggers and transitions are also used in Flex States and would also be confusing.

I appreciate this, but 'action' is a term already in use in the FSM domain, and it is 'action' in this sense that I found I needed to implement.

Obviously suggesting a change in terminology was a poor way to start any proposal of change as it immediately raises the hackles of the original designers. I apologise, but I couldn't see any sensible way forward. It is just too confusing having 'action' standing as a synonym for 'event', especially when one also needs a word for the action performed as a result of a transition.

But I stand by wanting to know what state I'm heading into on the exiting note, though the entering note should carry the state being exited.

I suggest this is perhaps the case if you must put all your code into entry and exit actions.

But if you have the action mechanism available too, you find you don't need to test the destination. You refactor your code so that only stuff that always needs to run goes into entry actions and exit actions; material that is specific to a transition goes into the transition action. So you move a little bit of high level logic out of the code of an action, and into the XML of the state machine, improving your separation of concerns.

I know, I'm putting you off again. I am sorry. I will shut up now.

Will
20  Announcements and General Discussion / General Discussion / Using the FSM on: February 21, 2009, 07:46:00
(A continuation of the issues discussed in http://forums.puremvc.org/index.php?topic=1002.0 - I flatter myself it is beyond 'Getting Started')

After Cliff's suggestions, I went away and modelled the database app I am trying to write as a state machine. It has four states: an initial login screen, a main screen where you browse records in a grid, an editing mode where you can edit the current record, and a 'Do you want to save your edits?' modal dialog, which comes up when the user tries to do something destructive - eg log out - when there is an edited record.

Here is the model as rather grotty UML. My explanations will refer to it.



The current FSM library is very neat, and I admire in particular its XML-description feature. However, with all respect to Neil Manuell and Cliff, implementing the model above using the current FSM library is very difficult, and perhaps not possible.

However, with just a few changes it can be done. The following is my attempt to justify and champion them.

1. I realise that there are many alternative vocabularies for this sort of thing, but I claim that the current library makes rather unusual use of the term 'action'.

When a state machine performs a transition, the transition is (usually) initiated by a triggering event, and it it performs various actions as part of the transition.

The current library wrongly uses the term 'action' to describe the notifcation that initiates the transition, for example:

The transition from one state to the next is triggered by any actor sending a StateMachine.ACTION Notification - http://trac.puremvc.org/Utility_AS3_StateMachine/wiki/ReleaseNotes.

As supplied, this clash does not matter, because the library does not allow you to define actions that are associated with a transition - only the exit and entry actions. However, I say it does become necessary to be clear, and to make the distinction.

Therefore I propose the following change in terminology:

  • The notification event that triggers a transition is renamed from 'Action' to 'Trigger'. ('Event' would perhaps be more standard terminology, but is confusing because of AS3's use of the term. 'Trigger' clashes with database use of the word, but I doubt this will cause any trouble.)
  • The term 'action' is reclaimed for its more usual use in state transitions - ie something that is performed as part of a transition.

In the diagram above, triggers are shown in caps, the actions in camelcase, with a slash separating them. So going from the browsing to editing state by way of clicking the new record button is shown as NEW/createNewEntry meaning that the trigger NEW causes the action createNewEntry.

This is the terminology I will apply for the rest of this post.

In the library code I have changed StateMachine.ACTION to StateMachine.TRIG, plus various supporting changes.

2. In the current library, transition actions are not implemented. However as a designer one does miss them very much.

Consider the UML diagram above. If the user is editing a record (ie in the editing state), and performs a CANCEL, the grid display restores itself to how it was before. If the user presses APPLY, the grid reflects the edited record. Both transitions move between the same two states, but the actions taken are different.

Therefore it is not possible - or it is at least not easy - to perform the correct action by using entry and exit actions on the two transitions. (In my implementation, I perform a restoreAfterCancel on the CANCEL transition; obviously other designs are possible.)

You could get around this be introducing extra states, or adding tests in the exit and entry action (this seems to me to be particularly unsatisfactory approach, as you are moving logic out of the XML description of the FSM and into code).

After playing around with this and similar problems, I decided to add an optional action, associated with the transition. The action is performed after the exit from the original state and before the entry to the new. Part of the XML definition:
:
<state name="STATE_EDITING"
    entering="ENABLE_APPLY_CANCEL"
    exiting="DISABLE_APPLY_CANCEL">

    <transition
        trigger="TRIG_CANCEL"
        target="STATE_BROWSING"
        action="RESTORE_AFTER_CANCEL"
    />

    <transition
        trigger="TRIG_APPLY"
        target="STATE_BROWSING"
    />
...
</state>
To implement this I had to create a Transition class to store the action as well as the destination state.

3. Currently the Entry and Exit notifications pass the destination state in their Type field. I have not found this to be useful. You generally don't want to vary the behaviour of the code based on the destination state - this logic lives in the state machine itself.

Instead, I suggest that the Type field contains the trigger name. This enables me to handle the situation where the user clicks 'Log out' while editing a record. This causes the state machine to transition from editing to save_edit_screen in the diagram above. If the user clicks 'Yes - save the record' or 'No - scrap my edits', the state machine must then go on to do the logout. To do this, it needs to know the original trigger - which can be retrieved from Type.

I have also found it useful to pass the Body of the original trigger notification to the entry, exit, action and change notifications. This enables parametrised events. For example, the 'NEW' trigger allows the user to create different kinds of records (there are in fact half a dozen different New buttons).

4. The current implementation doesn't allow loopback transitions. (To be fair, without proper actions, there is no point, as the entry and exit actions should not fire.) I have found these useful, and have added them.

5. Using the FSM, I find the Application proxy is not needed. I originally took code from one of the PureMVC AS3 examples to implement a login. It used the application proxy to store in an int member variable whether the application was 'logged in' or not. This always struck me as a bit odd, because I would say that this is part of the business/application logic, rather than the domain logic - and therefore had no business [sorry] being in a proxy.

Using the FSM, I have been able to remove the Application proxy class. The FSM itself is a type of mediator, so can legitimately act as the seat of app logic.

In fact, as a general principle, I would say that using the FSM has given me a way to structure the 'business logic' of the whole application. I was finding that I was ending up with a sort of spaghetti notification app, with lots of parts responding to different notifications. I was losing my grip on the structure of the application as a whole. There was nowhere where one could view its high level structure.

I think the FSM supplies this missing feature, and allows me to keep an overview of things as I add features.

6. I am making extensive use of AsyncCommands. I use them to call all services on proxies, using Cliff's suggested AsyncToken mechanism from an earlier thread.

One consequence: I no longer need Proxies to send notifications, and in fact I have as a design choice outlawed the practice.

My reasoning is this: if one allows a proxy to send a notification, it needs to define the notification as a static constant in its own class (in order to avoid dependency on ApplicationFacade, or wherever you have defined you app's notification strings). But this means that you cannot have a single place where you can view all your global notifications - you have to go hunting through the domain proxies. This practice forces them all into one place.

I also use AsyncCommands to run modal dialogs - for example the one in the save_edit_screen state. When the user supplies the Yes/No/Cancel answer, the control is returned to the showSaveEditsDialog command that first displayed it. This command holds a little state, namely the transition that brought the machine to this state. It is able to use this to perform the next action. I couldn't see any other way of doing this without having (yuck!) some sort of global state.

I think this is a very handy and tidy little idiom - although it seems to be at odds with the FAQ: http://puremvc.org/content/view/80/188/

7. The action of a transition is generally to fire a single command. Where a notification causes more than one effect on mediators, I tend to make a new command that performs a sequence of notifications.

For example, when you log out, the app clears the login name from the top of the screen, clears the current record in the grid and displays the login dialog. These changes are performed jointly by three or four mediators on their respective components. Rather than have them all react to the 'global' notification 'LOGOUT', I have set up individual notifications for each one (CLEAR_LOGIN_NAME, CLEAR_CURRENT_RECORD, SHOW_LOGIN_SCREEN) which express the action in 'local' terms of the mediator concerned, rather than 'global' terms.

So the actions in the FSM tend to refer to 'global' change notifications, which map to commands. The commands then issue notifications enacted by mediators, where the notification constants are specific to mediators.

This got me thinking further. There are now a lot of constants declared in ApplicationFacade. Many of them refer to notifications only handled by one mediator. I was considering moving them out of ApplicationFacade, and into the mediator that deals with them. I would declare them using the
:
public static const SOME_NOTE:String = NAME+"someNote" ;
trick to make sure they couldn't clash.

This would reduce the pollution in my 'global' ApplicationFacade namespace... but it would require the command classes to depend on the mediator concerned. The notification constants left in ApplicationFacade would refer only to commands, and to transition states.

Not sure about this...



Sorry, the above has been a somewhat muddled and rambling brain dump of my experiences using PureMVC with FSM. I do think I have some reasonable ideas, and have extended the library usefully. There are still things I think are missing:

  • Guards. It would be handy to execute a guard before performing a transition. The guard could cancel the transition by sending a StateMachine.CANCEL notification. This would replace the present (in my view unsatisfactory) facility to cancel a transition from an exit action.
  • Multiple actions. The ability to specify lists of actions to be executed. Like macro commands, but without the need to create an extra class.
Natch I am happy to share the code that I have made, if it is of interest. I can't really share the app, because it is large and messy and has too many dependencies. However, I think the features I have discussed could fairly easily be added to one of the example apps, if that were thought useful.

Will

PS: There is an excellent tool on SourceForge called the State Machine Compiler which generates state machines in a dozen or so languages, including C++, C#, PHP... but not AS3. Anyway, my ideas have been strongly influenced by the facilities it offers, and excellent documentation... nearly as good as Cliff's :-) Check it out here: http://smc.sourceforge.net/

PS#2: Oops: in the diagram the EDIT transition from editing to save_edit_screen is in the wrong place. It should be from browsing to editing. It is the transition that occurs when a user edits an existing record.
21  Announcements and General Discussion / Getting Started / Re: How to implement 'Save record? (Yes/No/Cancel)' on: February 15, 2009, 11:11:39
The problem is that the asyncCommand if triggered on the exiting note and used to popup the dialog will not be able to hold off the thread of execution from completing the StateMachine transition while the popup is awaiting your input.

Ok, I see that now you say it. But I still have the problem of not wanting to let the popup dialog's mediator query the StateMachine's state.

I feel that the popping up of the dialog must fall out of the design of the state machine.

How about this for a variation? The situation of having a popped-up dialog is really a state. To fix my design, I need to admit this and put it in the model:

From the 'edit' state, clicking something (apart from 'Apply' or 'Cancel' buttons) takes you to the 'abandon dialog' state.

Entering the 'abandon dialog' triggers an async command which
1) Stores the action that caused this transition in its instance
2) Fires off the popup mediator to get the Y/N/Cancel answer from the user - supplying a completion function that gets called when the dialog is dismissed.

The dialog completes, so now we are back in the async command... with the answer. Now I can mung in your previous design with mine:

  • if the answer is 'yes, save my edits' then fire off an AsyncMacroCommand comprising  1) save the record 2) fire the StateMachine.ACTION to go to wherever the original click wanted to go. We know what this action is, because we stored it in the 'Show Dialog' AsyncCommand's instance data above
  • if the answer is 'no, ditch my edits' then just fire off the StateMachine.ACTION to go and do the original action
  • if the answer is cancel, fire off the StateMachine.ACTION to go to the 'edit' state

That works, doesn't it? I have pushed the logic back into the FSM's definition. I think.

Mostly I am worried that I won't be able to find out the Action that brought me here when I fire up the AsyncCommand to show the dialog.

I am also worried about what happens if the first command in the Save AsyncMacroCommand fails (ie the remote save process comes back with an error). Can I abort the rest of the command and do something else?

I am prepared to put off detailed worrying until tomorrow.

Will
22  Announcements and General Discussion / Getting Started / Re: How to implement 'Save record? (Yes/No/Cancel)' on: February 15, 2009, 05:03:04
Hi,

Thanks for the explanation. However, I am still puzzled. (Fx: Transatlantic groan.)

Let's say you're in the 'edit' state and you click something that will take you to the 'list' state.
That click should lead to a notification that causes a PopUpMediator hears and shows its Popup asking if you want to save.

Suppose, for the sake of argument, the action is clicking on another record in the grid. The grid mediator generates a SELECT_RECORD notification.

My PopUpMediator (you seem to be saying) consumes this. But it needs to know if I am in the edit state. If I am, it pops up and does its thing as you describe. If I am in the list state, it creates an action to change the state back to list state, and somehow forwards the notification so that the mediator that owns the 'Display this record' component loads up the new record.

So now my PopUpMediator has to know what the FSM state is, and test it. Doesn't it? Is that ok? Surely its behaviour should fall out of the transitions that take place, rather than by explicitly querying state? We seem to have moved the logic of the state transitions out of the XML definition of the FSM, and into the code inside the PopUpMediator.

I was thinking of a design something like this:

The SELECT_RECORD notification, issued when the user clicks on a different record in the grid,  is changed into a StateMachine.ACTION called SELECT_RECORD that causes the state machine to try to exit the 'edit' state. This is defined in the FSM.

I set up an AsyncCommand that detects attempts to exit 'edit' state and runs the popup, gathering the result in its callback. When the popup dialog returns, and we are still trying to exit the state, and the following logic gets executed:

- if the user has clicked 'Yes, save my edited record' then the callback triggers a notification for AsyncMacroCommand comprising two parts: 1) save the record, 2) select the clicked-on record. If the 'save the record' part fails, by the way, I most likely issue a StateMachine.CANCEL notification.

- if the user has clicked 'No, ditch my edited record' then just perform the 'select the clicked-on record' part as described above.

- if the user has clicked 'cancel, let's keep on editing' then the callback in the async command generates a StateMachine.CANCEL notification - aborting the state transition

But this design contradicts the very first sentence in your answer, viz:

With the StateMachine, you need to be sure that its safe to change states BEFORE sending the StateMachine.ACTION notification that kicks off the transition.

because I want to be able to abort an ongoing transition. What is CANCEL for if not to abort a transition?

Sorry to be thick, and thanks for your ongoing patience.

Will
23  Announcements and General Discussion / Getting Started / Re: How to implement 'Save record? (Yes/No/Cancel)' on: February 14, 2009, 10:19:07
Thanks Cliff, that's reassuring. I thought I might be barking completely up the wrong tree.

I am not against state machines. Indeed, I am very tempted. I now have a state chart sketch to prove it.

From what you said before, do you recommend using an AsyncCommand to run a modal dialog in PureMVC? Is that a better idiom than broadcasting the result from the popup's mediator? The mediator is self contained, and perhaps reusable; the AsyncCommand captures the post-dialog logic?

Please excuse my questions. I am an elderly C++ programmer finding myself on strange and unfamiliar ground. I have yet to reach a comfort level with this framework. I will shut up in a minute, I promise.

Will
24  Announcements and General Discussion / Getting Started / How to implement 'Save record? (Yes/No/Cancel)' on: February 13, 2009, 01:37:50
Once again I seem to be stuck on what should be a simple thing.

I have a database editor, which allows one to select and edit a record from a grid, or create a new record. I have created suitable commands, mediators etc, so that the various parts of the app live in blissful ignorance.

However, now I would like to handle the following situation. The user has edited a record. Now he does something else - say select another record in the grid (or logs out, or changes the selection set of records - something that is potentially destructive to his current record. Any one of a number of things, where this number will increase as time goes on).

I want to put up a 'Save this record? Yes/No/Cancel' dialog, and then save the record (with the async round trip to the database that implies), sling the record or cancel the action and continue editing. In the first two cases, I wish to carry out the original request afterwards. I would like to do it in a generic way, so that it handles new ways of interrupting the editing process that may occur as the app expands.

If I were doing this in a sinful, tightly-coupled application, I would supply a general routine to test if the record were edited, call my dialog, harvest the answer and take action as appropriate. The logic would be clear, and in one place.

As it is, I am a bit baffled. The logic seems to spread itself over lots of notifications and commands (which I have to create to prevent my mediators from mating), and/or I have to make a state machine which grows states like topsy, and has special pockets where you keep the command you want to execute in the notification handler that is next but one.

I am sure I am being very dense about this, but I really would much appreciate pointers as to how to approach it.
25  Announcements and General Discussion / General Discussion / Re: Document-Based Application: is PureMVC the way to go? on: February 12, 2009, 07:49:37
Yes, that's neater, and presumably you would store the VO in the same way, as part of the AsyncToken.

Do you need to handle the failure case in the Mediator/Component? (That's where my schemes tend to get sticky.) But perhaps an empty VO is good enough, and use a general failure reporter.

Will
26  Announcements and General Discussion / General Discussion / Re: Document-Based Application: is PureMVC the way to go? on: February 12, 2009, 05:59:55
> Secondly, say the component lazily loads a list of comments from the server when it has focus: it's Mediator calls a method on a Proxy, and the Proxy sends a Notification when it's retrieved the list of comments. All Mediators of this type then receive that Notification and we have to come up with another mechanism for filtering the response - only one of them was actually interested in that particular list of comments. It's not the sort of thing that anyone else really needs to know about - the application model hasn't changed. <

How about: the Mediator passes in 'this' to the call on the Proxy (natch untyped, as an Object reference, so the Proxy remains ignorant of the Mediator). The Proxy stores it in its AsyncToken, as described in Cliff's answer to me here http://forums.puremvc.org/index.php?topic=991.0 (but you store an object ref instead of a callback).

When it handles the result from the service, the Proxy includes the object reference in the Notification that it creates. Mediators look for the reference, and then only process them if they match 'this'.

Will
27  Announcements and General Discussion / Getting Started / Re: AsyncCommand and remote proxies on: February 06, 2009, 11:00:09
> Have the Proxy set this as a dynamic property such as 'callback' on the AsyncToken

Brilliant! Didn't know about the AsyncToken. That is at least 19 times as clever as anything I had thought of. Possibly even 23 :-) And I can have the FaultEvent handler in the proxy do the same thing, and then my command always gets completed.

> Investigate the StateMachine utility.

I am sorely tempted. I would love to refactor the app as a state machine. State charts are my favourite kind of computer diagram - I find the act of drawing them clarifies my thoughts.

However, I need to progress the app in a quicker and dirtier way, and I am concerned by the prospect of needing to assimilate another tool, and redesigning what I have done to use it. I absolutely accept it would be much lovelier for the effort and a benefit in the long run. But.

I'll leave it alone for the weekend and see how I feel.

Thanks once again for your swift, detailed and most helpful answer.

Will
28  Announcements and General Discussion / Getting Started / AsyncCommand and remote proxies on: February 05, 2009, 10:40:02
I would like to execute an action on a remote proxy and get the result within the aegis of an AsyncCommand, so as to preserve context - 'This failure occurred while trying to execute a page up command' - without having extra bits of state lying around.

However, I am struggling. Don't see how to get the result of a remote call back to the command instance. Is it ok to use event listeners to communicate between proxy and command? Feels wrong.

Is this kind of thing an intended use of AsyncCommand? Have I got the wrong end of the stick?

Will


(PS: A tardy thanks to Cliff for his help with my previous Getting Started question.)
29  Announcements and General Discussion / Getting Started / Re: Two questions about Slacker on: January 09, 2009, 04:11:30
Thanks for that.

In the demo app, the components were created just the once and never destroyed. I suppose the code could be intended to demonstrate a more general case.

To argue against myself in the case of passing the class: I depend on the presence of the NAME static constant, and that the constructors of the classes all have the same signature. In practice I think they all do, but (scarily to a busking C++ programmer who is slightly alarmed by all this absence of static type checks) there is no way to check this until the code runs.

Will
30  Announcements and General Discussion / Getting Started / Two questions about Slacker on: January 07, 2009, 09:25:21
First: PureMVC (as everyone else correctly says) is indeed an excellent and wonderful thing, and I am most grateful for it. But I am very new to it, so please excuse a couple of silly questions.

I have quickly arrived at the deferred instantiation problem in my app, and have found the Slacker example. It seems to work fine, but I don't understand the reasoning behind the following code extracted from MainDisplayMediator.as.

The onXXXCreated() functions below are called from the creationComplete events of the respective components. It is the handling and checkForMediator() implementation that puzzles me:


    public class MainDisplayMediator extends Mediator
    {
    //...
        protected function onEditorCreated( event:Event ):void
        {
            checkForMediator( MainDisplay.EDITOR, mainDisplay.activeView );
        }

        protected function onGalleryCreated( event:Event ):void
        {
            checkForMediator( MainDisplay.GALLERY, mainDisplay.activeView );
        }
 
        protected function onProfileCreated( event:Event ):void
        {
            checkForMediator( MainDisplay.PROFILE, mainDisplay.activeView );
        }


        protected function checkForMediator( childSelector:Number, child:Object ):void
        {
            switch (childSelector)
            {
                 case MainDisplay.PROFILE:
                      if ( ! facade.hasMediator( ProfileViewMediator.NAME ) )
                         facade.registerMediator(new ProfileViewMediator( child ));
                      break;
                 case MainDisplay.GALLERY:
                      if ( ! facade.hasMediator( GalleryViewMediator.NAME ) )
                         facade.registerMediator(new GalleryViewMediator( child ));
                      break;
                 case MainDisplay.EDITOR:
                      if ( ! facade.hasMediator( EditorViewMediator.NAME ) )
                         facade.registerMediator(new EditorViewMediator( child ));
                      break;
              }       
        }



My two questions are:
1) Is this a case of the switch statement being deliberately used to emphasise simplicity? I don't like the way that integer manifest constants like MainDisplay.PROFILE must be translated into a class ProfileViewMediator, which seems fiddly and hard to maintain. I want to write

        protected function onProfileCreated( event:Event ):void
        {
         checkForMediator( ProfileViewMediator, mainDisplay.activeView );
        }

//... etc for each tab

        protected function checkForMediator( mediatorClass:Class, child:Object ):void
        {
          if ( ! facade.hasMediator( mediatorClass.NAME ) )
            facade.registerMediator(new mediatorClass( child ));           
        }
and simplify the code. Is this 'bad style' in PureMVC terms?

2) Why do we need the check to see if the mediators have already been created anyway? We are in the CreateComplete event for the component, which surely only gets called once for the lifetime of the component. The code is specific to the handler. So one could safely write

        protected function onEditorCreated( event:Event ):void
        {
           facade.registerMediator(new EditorViewMediator( mainDisplay.activeView ));
        }

Am I missing something?

Best regards

Will
Pages: 1 [2]