PureMVC Architects Lounge

PureMVC Manifold => Demos and Utils => Topic started by: puremvc on August 16, 2009, 07:25:13



Title: Loadup - A PureMVC AS3 Utility
Post by: puremvc on August 16, 2009, 07:25:13
The Loadup utility offers a solution to the problem of how to manage the asynchronous loading of Model resources at anytime during application runtime. It supports loading order dependencies, and is progress-aware.

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

The author is Philip Sexton.

NOTE: This project was formerly known as StartupManager, and was renamed Loadup, to dispel the notion that the utility it was only usable at startup time.

The previous thread is here: http://forums.puremvc.org/index.php?topic=259.0


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on August 18, 2009, 03:15:53
As regards features, the main enhancement in this release is the option to supply a proxy name to LoadupMonitorProxy, thus enabling independent instances to exist.  See the notes in version.txt.

To migrate to Loadup from StartupManager, see the instructions in the text file migrationToV2.txt.  In developing Loadup, the opportunity was taken to drop code that existed only for backward compatibility purposes.

The two demos have been migrated to Loadup, so we have Loadup as Ordered and Loadup for Assets.  The latter has been enhanced to illustrate the loading of intermittent single assets and a group of assets, as independent tasks.

----Philip


Title: Small Sequencing Issue
Post by: bestbuyernc on August 19, 2009, 06:53:25
Hello.  This is my first major flex/puremvc project.  I am still on the login/logout functionality but its helped me get started with what the players are supposed to do.  It has taken me long to get going but I think I am making good progress thanks to everyone here.

However, I am still confused about a few things like, THE STATE MACHINE, when I should use a command vs just calling the proxy method from the mediator, how to keep viewComponent code out of the mediator by sending notifications that invoke commands and what it means to 'put business logic in the commands'  when the only thing I typically see in commands in examples is the command getting data from the note and invoking a proxy method. I hoping to find a good complex command example.

Anyway, for this post my question is about a sequencing issue.
My login view has 4 states.  Login, Registration, Reset Password and Change Password.  When the user registers successfully I show an alert telling them that the registration was successful.  When the user clicks the alert 'OK' button, I want the following to happen:

1.  Enable the form.
2.  Clear the form.
3.  Go back to the Login state.
4.  Populate the userID with the userID from the registration VO.

To go back to the login state I am using an approach I found where the application proxy holds the view state property and sends a notification any time its changed and then the app mediator reacts by changing the view.  But the login form mediator is responsible for enabling the login form and clearing the form.  What is happening is that the form gets cleared and enabled but the app mediator doesn't get a chance to change the state.  Its a sequence issue because the app mediator gets the notification first and changes the state but I think calling the alert from the registration state makes it return.  Not sure.
I am wondering if this is where the State Machine or Macro Commands would come in handy.  The State Machine has been really intimidating to me but I knew at some point I would have to face it.  From what I understand Macro Commands are a way of chaining and sequencing events. My startup command is a macro command.  Is this what I should be doing in this scenario?  Or is this something the state machine would be good for.

Thanks.



Title: Re: Small Sequencing Issue
Post by: puremvc on August 20, 2009, 07:23:40
Don't keep state in a proxy. State is a View concept, not part of the Domain Model and thus not a responsibility belonging in the Model tier. Instead use the State Machine. Check out the overview presentation at http://puremvc.tv to get an idea of how it works.

As for a complex example that also uses State Machine, you can see the original Sea of Arrows code at http://seaofarrows.com/srcview. Check out the state machine in the shell. It executes a number of commands that do chunky business logic like plumbing the modules.

The long and short of when to fire a command instead of calling a proxy method from a mediator is, you can do either. If there's a lot of preparation involved, or if the same call will be triggered from multiple places in the UI, you might be better making the call from a command, so you'll only have one place to refactor if the method signature on the proxy changes. Otherwise, the View and Controller tiers are both allowed to update the Model.

-=Cliff>



Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 21, 2009, 11:16:07
Thank you for responding.  What about the states of one component vs. application state?  My login screen component has 4 different states. LOGIN, REGISTER, CHANGE PASSWORD and RESET PASSWORD.  Should all of these be managed by the state machine? Or is that for more application scope state, like moving from the Login page to the Main application page?  Should the view component state be handled only by the component's mediator? Since the first application state change would be once the user logged in successfully. Until that point everything is on one view. 


Also, I want to load a list of projects to a combo box prior to showing the login view.  I am attempting to do this by mapping an APPLICATION.STARTUP action to an APPLICATION.LOAD_PROJECTS.  I want my application mediator to respond to the notification and call the projectProxy to load the projects.  I have defined the FSM like this:

:
<fsm initial={ApplicationFacade.STARTING}>
<state name={ApplicationFacade.STARTING}><transition action={ApplicationFacade.ACTION_STARTUP} target={ApplicationFacade.LOAD_PROJECTS}/>
<transition action={ApplicationFacade.STARTUP_FAILED} target={ApplicationFacade.STARTUP_FAILED}/>
</state>
<state name={ApplicationFacade.LOAD_PROJECTS}><transition action={ApplicationFacade.LOAD_PROJECTS} target={ApplicationFacade.PROJECTS_LOADED}/>
<transition action={ApplicationFacade.PROJECTS_LOADING_FAILED} target={ApplicationFacade.PROJECTS_LOADING_FAILING}/>
</state>
</fsm>;


Thank you.


Title: Re: Small Sequencing Issue
Post by: polykrom on August 21, 2009, 11:30:54
Hi,

If you are in a StateMachine logic for the main application, you could use StateMachine in all other "components" or Modules... Each Core can have its own StateMachine (you have to use the multicore package for that).

The way you use StateMachine seems not to be the right way.. You should have one State Machine for your main app with two views LOGIN and POPULATE COMBO.
And in each view, other StateMachines or Notifications handlers to swap between components view.
 
For your FSM, i think the one you provide would be for the Project loading module... not for the main one.. and don't forget to define the target state in your FSM :

ApplicationFacade.STARTUP_FAILED,ApplicationFacade.PROJECTS_LOADED and ApplicationFacade.PROJECTS_LOADING_FAILING

regards

:::Poly:::


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 23, 2009, 04:31:28
Hi,

If you are in a StateMachine logic for the main application, you could use StateMachine in all other "components" or Modules... Each Core can have its own StateMachine (you have to use the multicore package for that).

The way you use StateMachine seems not to be the right way.. You should have one State Machine for your main app with two views LOGIN and POPULATE COMBO.
And in each view, other StateMachines or Notifications handlers to swap between components view.
 
For your FSM, i think the one you provide would be for the Project loading module... not for the main one.. and don't forget to define the target state in your FSM :

ApplicationFacade.STARTUP_FAILED,ApplicationFacade.PROJECTS_LOADED and ApplicationFacade.PROJECTS_LOADING_FAILING

regards

:::Poly:::
Hi.  I am still confused.  I just need to projects to load before the user can interact with the app.  Maybe the startup monitor is more appropriate since it is a startup resource?  I was trying to define my FSM so that after puremvc is started up the projects would load to the combo box.  Still not getting it.


Title: Re: Small Sequencing Issue
Post by: polykrom on August 23, 2009, 11:33:02
Hi,

so, if it's just to be sure your comboBox content is loaded, you can use StartupManager and, when the content is loaded, send a stateMachine.ACTION notification to swap to the comboBox view and use a bindable var wich contain the combo values to populate the component...


Title: Re: Small Sequencing Issue
Post by: puremvc on August 24, 2009, 10:18:57
View components can have their own states. If you're using Flex, states are built in. But if not, don't try to burden the Mediator with statekeeping for its view component.


-=Cliff>


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 25, 2009, 08:10:39
Thank you Cliff.  That's what I was doing. 

PolyKron. You are right. I was trying to get the State Machine to do what the Loadup was meant to do.  I got it to work. Somewhat. I created my ProjectProxy as an ILoadupProxy. 

I thought I could send the proxy's project data with the ApplicationFacade.PROJECTS_LOADED notification.  I was following the LoadupAssets example. It sends the notification as sendNotification( ApplicationFacade.PROJECTS_LOADED, NAME, SRNAME ); I am not sure of the purpose of SRNAME.  So to get my list of projects I had to send another notification sendNotification( ProjectProxy.PROJECTS_RETRIEVED, data  );.  But doing it this way I think may be overriding the purpose of the Loadup utility in terms of blocking until the startup data is available.  When I run it the UI is displayed and then a few seconds later the combo box is populated.  Is this where the state machine would come in handy?
At first I had my LoginFormMediator listening for the LoadupMonitorProxy.LOADING_COMPLETE: notification.  Now my ApplicationMediator is interested LOADING_COMPLETE but I am not doing anything with the note.  I don't want the login page displayed if the project fail to load so maybe the ApplicationMediator should be responsible for handling that scenario?
Is the following the correct way to return the Proxy's project data to the interested mediator?  Am I breaking the chain of events by sending both notifications when the data is retrieved from the Project Proxy?

Thank you.

:

public class ProjectProxy extends EntityProxy implements ILoadupProxy
{
        //  send LoginAttempt as proxy data
public function ProjectProxy() {
super( ProjectProxy.NAME );
}

// notification name constants
public static const NAME:String = "ProjectProxy";
public static const SRNAME:String = 'ProjectSRProxy';
public static const PROJECTS_RETRIEVED:String = NAME+'/notes/projects_retrieved';
public static const PROJECTS_RETRIEVAL_FAILED:String = NAME+'/notes/projects_retrieval_failed';

// project service
        private var projectService:RemoteObject;
        private var tryCount:int = 0;
       
// configure the proxy when registered
public override function onRegister():void {
// configure the remote object
        projectService  = new RemoteObject("GenericDestination");
        projectService.source = "ProjectService";

        // is this ok? Had do listen for the remote call.  I thought this would be inherited behaviour
        projectService.getOperation("getProjects").addEventListener( ResultEvent.RESULT, loaded );
        projectService.getOperation("getProjects").addEventListener( FaultEvent.FAULT, failed );
}

// call the remote object service
public function load():void {
        tryCount++;   
        sendNotification( ApplicationFacade.PROJECTS_LOADING, NAME, SRNAME );
        projectService.getProjects();
}
       
// remote procedure is successfull
public function loaded( asToken:Object=null ):void {       
        var projects:Array = [];
        for each (var item:Object in asToken.result ) {
        projects.push( { label: item.domain, data: item.domain } );
        }
         
setData( projects );
        // not sure what this is for
        sendNotification( ApplicationFacade.PROJECTS_LOADED, NAME, SRNAME );
        // this is how I am sending the retrieved data.
      sendNotification( ProjectProxy.PROJECTS_RETRIEVED, data  ); 
}
       
// remote login procedure is successfull
public function failed( asToken:Object=null ):void {         
    sendNotification( PROJECTS_RETRIEVAL_FAILED ); 
}


Title: Re: Small Sequencing Issue
Post by: philipSe on August 26, 2009, 05:10:46
Just to clarify about 'loaded' notifications in the Loadup utility.  The release notes in version.txt state:
    On loaded and failed notifications sent by the client app, if
    the monitor proxyName is not the default name, the notification
    type MUST BE the monitor proxyName.

So, type should be empty unless the LoadupMonitorProxy has been given a custom name.

This business of SRNAME may have arisen from the LoadupAsOrdered demo, where there are code instances like sendLoadedNotification( blah_LOADED, NAME, SRNAME ). This 'sendLoadedNotification' method is local to the demo; it is not part of the Loadup API.
----Philip




Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 27, 2009, 07:00:34
Just to clarify about 'loaded' notifications in the Loadup utility.  The release notes in version.txt state:
    On loaded and failed notifications sent by the client app, if
    the monitor proxyName is not the default name, the notification
    type MUST BE the monitor proxyName.

So, type should be empty unless the LoadupMonitorProxy has been given a custom name.

This business of SRNAME may have arisen from the LoadupAsOrdered demo, where there are code instances like sendLoadedNotification( blah_LOADED, NAME, SRNAME ). This 'sendLoadedNotification' method is local to the demo; it is not part of the Loadup API.
----Philip

Thanks Philip.
I am getting this error even though I have not give the LoadupMonitorProxy a custom name.

:
Sent ApplicationFacade/action/startup
Sent ApplicationFacade/note/started
Sent ApplicationFacade/action/showSplashScreen
Sent ApplicationFacade/action/loadResources
Sent ApplicationFacade/note/loading_projects
Error: null: Unknown ILoadupProxy in loaded/failed notification, not known in LoadupMonitorProxy instance named :LoadupMonitorProxy
at org.puremvc.as3.multicore.utilities.loadup.model::LoadupMonitorProxy/resolveAppProxyNameElseError()[C:\My Documents\Flex Builder 3\PureMVC\Utility_AS3_Loadup_2_0\multicore\org\puremvc\as3\multicore\utilities\loadup\model\LoadupMonitorProxy.as:485]
at org.puremvc.as3.multicore.utilities.loadup.model::LoadupMonitorProxy/resourceLoaded()[C:\My Documents\Flex Builder 3\PureMVC\Utility_AS3_Loadup_2_0\multicore\org\puremvc\as3\multicore\utilities\loadup\model\LoadupMonitorProxy.as:448]
at org.puremvc.as3.multicore.utilities.loadup.controller::LoadupResourceLoadedCommand/execute()[C:\My Documents\Flex Builder 3\PureMVC\Utility_AS3_Loadup_2_0\multicore\org\puremvc\as3\multicore\utilities\loadup\controller\LoadupResourceLoadedCommand.as:46]
at org.puremvc.as3.multicore.core::Controller/executSent ApplicationFacade/note/projects_loaded

When the projects are returned from the service I am sending an ApplicationFacade.PROJECTS_LOADED notification that was registered as a resource loaded notification.  I think this wrong because isn't this the notification that loadup sends when the resources have finished loading?  I tried not sending any notifications from the loaded function to see if ApplicationFacade.PROJECTS_LOADED is sent by the Loadup Utiltity, but it is not.

I know these posts have hit a lot of different areas.  But I appreciate your patience and assistance.
Thank you.

:
   
ApplicationFacade
registerResourceLoadedCommand( PROJECTS_LOADED );
registerResourceFailedCommand( PROJECTS_LOADING_FAILED );

ProjectProxy
    // remote login procedure is successfull
        public function loaded( asToken:Object=null ):void {       
        var projects:Array = [];
        for each ( var item:Object in asToken.result ) {
        projects.push( { label: item.domain, data: item.domain } );
        }
setData( projects );
sendNotification( ApplicationFacade.PROJECTS_LOADED, data );
        }

But in the LoadResourcesCommand i am using the default name.

:
public class LoadResourcesCommand extends SimpleCommand implements ICommand
{
private var monitor:LoadupMonitorProxy;

public override function execute( note:INotification ):void {
facade.registerProxy( new LoadupMonitorProxy() );
this.monitor = facade.retrieveProxy( LoadupMonitorProxy.NAME ) as LoadupMonitorProxy;

var projectProxy:ILoadupProxy = new ProjectProxy();
facade.registerProxy( projectProxy );

var rProjectPx:LoadupResourceProxy = makeAndRegisterLoadupResource( ProjectProxy.NAME, projectProxy );
this.monitor.loadResources();
}

private function makeAndRegisterLoadupResource( proxyName :String, appResourceProxy:ILoadupProxy ):LoadupResourceProxy {
var r:LoadupResourceProxy = new LoadupResourceProxy( proxyName, appResourceProxy );
facade.registerProxy( r );
monitor.addResource( r );
return r;
}
}



Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 27, 2009, 07:45:13
I see my answer.  Right in the documentation.  Thanks.


Title: Re: Small Sequencing Issue
Post by: philipSe on August 27, 2009, 07:59:41
'loaded' notifications are sent by your app, they are not sent by Loadup, they are consumed by Loadup.  You must include the proxy name of the ILoadupProxy as the body of the loaded notification - note ILoadupProxy refers to the proxy in your app that has the load() method for the resource; it does not refer to the monitor.  If you don't supply a recognisable name in the body, you get the 'Unknown ILoadupProxy' Error.

When Loadup judges that loading of all resources is complete, on account of having received a loaded notification for each resource, then Loadup sends a LOADING_COMPLETE notification.
----Philip


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on August 27, 2009, 11:29:42
Yes.  I got rid of that error. By sending my ILoadupProxy (ProjectProxy.NAME) in the resource loaded command notification. 

But... this brings me right back to an earlier question.  I have to send another notification from the ProjectProxy to get its data. So my ApplicationFacade reacts to the ApplictionFacade.PROJECTS_LOADED note and changes to the Login view (just until I figure out the STATE MACHINE) and my LoginMediator responds to the ProjectProxy.PROJECTS_RETRIEVED note and tries to populate the combo box with the data from the ProjectProxy.  Everything seems to be working.   I'm just wondering if it is ok to do it this way.

Thanks.

:
ProjectProxy
        // remote login procedure is successfull
        public function loaded( asToken:Object=null ):void {       
        var projects:Array = [];
        for each ( var item:Object in asToken.result ) {
        projects.push( { label: item.domain, data: item.domain } );
        }
setData( projects );
sendNotification( ApplicationFacade.PROJECTS_LOADED, ProjectProxy.NAME );
sendNotification( ProjectProxy.PROJECTS_RETRIEVED, data );
        }

ApplicationFacade
case ApplicationFacade.PROJECTS_LOADED:
       app.appView.selectedIndex = 2;
break;

LoginMediator
case ProjectProxy.PROJECTS_RETRIEVED:
       loginForm.projectSource = ( body as Array );
break;
 


Title: Re: Small Sequencing Issue
Post by: philipSe on August 28, 2009, 10:20:04
Just 2 alternatives to consider.
1. you could drop PROJECTS_RETRIEVED, just use PROJECTS_LOADED in the LoginMediator, use the body (i.e. the proxy name) to retrieve the project proxy and use that to get the data property.
2. use of 'app.appView.selectedIndex = 2' in a mediator might be considered too closely coupled to the internals of the viewcomponent - I think the slacker demo has an example of mediator/component interaction where the component contains a view stack - see MainDisplay.mxml and MainDisplayMediator.
----Philip


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on October 01, 2009, 02:58:00
Hi. Been away for a while. But thank you for responding.  The following gives me a null proxy object.  The facade isn't able to find it based on the name.  Am I doing something wrong?
:
                [b]Project Proxy[/b]
// setting the name
public static const NAME:String = "ProjectProxy";

        // set the proxy's data to be retrieved
setData( projects );

// send the project's loaded notification.  mediators can get its data from the facade using the NAME passed in the body
sendNotification( ApplicationFacade.PROJECTS_LOADED, ProjectProxy.NAME );

                [b]LoginMediator[/b]
            case ApplicationFacade.PROJECTS_LOADED:
            projectProxy = facade.retrieveProxy( body as String ) as ProjectProxy;
            loginForm.domainSource = ( projectProxy.getData() as Array );
            break;


Title: Re: Small Sequencing Issue
Post by: philipSe on October 02, 2009, 02:20:19
Have you registered the proxy? - must be registered before it can be retrieved.
----Philip


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on October 02, 2009, 06:33:54
Yes.  It is the ILoadupProxy.  I am setting its data with results from the remote call.  I can see where the data is populated.  However, trying to retrieve it from the mediator by the name is giving me a null exception.


Title: Re: Small Sequencing Issue
Post by: puremvc on October 02, 2009, 06:41:57
Sounds as if the Proxy isn't registered.

By the way, you should define the notification constant on the Proxy so that the Proxy isn't bound to the ApplicationFacade. The Proxy can then be reused in other applications without relying on a constant that it depends on to be defined elsewhere.

-=Cliff>


Title: Re: Small Sequencing Issue
Post by: bestbuyernc on October 02, 2009, 07:21:17
Sounds as if the Proxy isn't registered.

By the way, you should define the notification constant on the Proxy so that the Proxy isn't bound to the ApplicationFacade. The Proxy can then be reused in other applications without relying on a constant that it depends on to be defined elsewhere.

-=Cliff>

Thank you. I registered the ProjectProxy in the LoadResourcesCommand

:
public class LoadResourcesCommand extends SimpleCommand implements ICommand
{
private var monitor:LoadupMonitorProxy;

public override function execute( note:INotification ):void {
facade.registerProxy( new LoadupMonitorProxy() );
this.monitor = facade.retrieveProxy( LoadupMonitorProxy.NAME ) as LoadupMonitorProxy;

var projectProxy:ILoadupProxy = new ProjectProxy();
facade.registerProxy( projectProxy );

makeAndRegisterLoadupResource( ProjectProxy.NAME, projectProxy);
this.monitor.loadResources();
}

private function makeAndRegisterLoadupResource( proxyName :String, appResourceProxy:ILoadupProxy ):LoadupResourceProxy {
var r:LoadupResourceProxy = new LoadupResourceProxy( proxyName, appResourceProxy );
facade.registerProxy( r );
monitor.addResource( r );
return r;
}
}

I did what you said and defined the notification constant in the ProjectProxy.

:
        public function loaded( asToken:Object=null ):void {       
        var projects:Array = [];
        for each ( var item:Object in asToken.result ) {
        projects.push( { label: item.domain, data: item.domain } );
        sendNotification( ApplicationFacade.LOADING_STEP, asToken.result.length / projects.length * 100 );
        }
        // set the proxy's data to be retrieved from interested mediators
setData( projects );

// send the project's loaded notification.  mediators can get its data from the facade using the NAME passed in the body
sendNotification( ProjectProxy.PROJECTS_RETRIEVED, ProjectProxy.NAME );
        }

... and then to get the data ...
:
            case ProjectProxy.PROJECTS_RETRIEVED:
            var projects:Array = facade.retrieveProxy( body as String ).getData() as Array;
            loginForm.domainSource = ( projects );
            break;

but the projects is still null.


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on October 05, 2009, 04:44:41
You seem to be using the same proxy name for the ProjectProxy instance and for the corresponding LoadupResourceProxy instance.  So, when the latter is registered, it supersedes the former.  So, when you retrieve the proxy, it is the LoadupResourceProxy you are retrieving.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: bestbuyernc on October 05, 2009, 06:45:54
I don't understand.  I am doing what is being done in the LoadUpAsOrdered demo.  In the LoadResourcesCommand,  a customer proxy is created as an ILoadupProxy and then registered with the facade.  That same proxy reference is passed to the makeAndRegisterLoadupResource method to create a LoadupResourceProxy.  The only difference I can see is that no data is actually being passed in the mediator to the notification.  Is it that my scenario is not the right one for the loadup utility?  Or maybe i am just lost  ???


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on October 05, 2009, 10:12:14
In the case you mention, from LoadUpAsOrdered demo, the line of code is
:
var rCus :LoadupResourceProxy = makeAndRegisterLoadupResource( CustomerProxy.SRNAME, cusPx );
Note the first argument is CustomerProxy.SRNAME as opposed to CustomerProxy.NAME.  That's what I mean.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: bestbuyernc on October 05, 2009, 01:05:46
Thanks Phillip... Unfortunately, I tried that also but get the same results.  I have just elected to just get the projects after PureMVC starts up and use a notification to send the data to my login view and just pop a database down message to the user if the projects cant be loaded.  I may not have had the best scenario for the utility.  Maybe somewhere down the line i will retry it.  I have learned a lot however, just be trying to implement it though.  Thanks for the help!


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: jts on November 16, 2009, 11:48:52
Let's assume that I have a ProductProxy that is responsible for retreiving products from the server. ProductProxy.data contains an object named ProductCatalog that stores all of the products that have been loaded onto the client. When my app starts I will call a method on the proxy named loadProductCatalog() which will get some basic info about each product. When a product is selected I will call another method on the proxy named loadProductDetails(prodId:int) that will be responsible for loading the details and merging them into the ProductCatalog(ProductProxy.data) structure.

I want to use the LoadUp utility in my system and am trying to figure out the best way to refactor this proxy to work with the Loadup.

First I believe I can simply rename loadProductCatalog() to load() and conceptially they will be the same thing. The  Product Proxy will be loading the products when load is called. So this naturally works. The point of confusion is how to handle other methods within my proxy. For the LoadProductDetails call, would I be best to to create a new proxy named ProdudDetailsProxy. This proxy would then contain only one method named load which would do the same thing as my old method named loadProductDetails. Then when this proxy loads the data, it would retreive the default instance of the ProductProxy and merge the just retreived ProductDetails into the ProductCatalog(ProductProxy.data) structure. So really my ProductDetails proxy would only be a short lived object since I only need it to load the data and merge it into my ProductProxy. Going with this pattern, it seems I would need a new proxy type for every load operation i plan to do on my model. I though it would be nice to keep load operations grouped within one proxy. For instance all operations related to a product would go inside a ProductProxy. What do you all think?

Thanks!!


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: jts on November 16, 2009, 01:56:55
I want to us the same LoadupMonitorProxy in different use cases but am having trouble identifying which use case was was being performed when the command attached to LoadupMonitorProxy.LOADING_COMPLETE fires. Maybe I need to track which state I am in with the state machine and check the state in my command and send the appropriate notification?


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: puremvc on November 16, 2009, 02:27:35
That would be my suggestion.

-=Cliff>


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: jts on November 16, 2009, 04:41:54
That would be my suggestion.

-=Cliff>

This may not be so easy as it looks like there is not a good way to get the current state out of the state machine. This is the general command I am attempting to use to attach to LoadupMonitorProxy.LOADING_COMPLETE notes that I want to be able to handler all use cases. Then in this command I can check my app state to know how to handle. Note that my CustomSimpleCommand grabs a ref to StateMachine from the facade. Is their a way to get the current state from state machine without having to track outside of state machine?

:
public class LoadingCompleteCommand extends CustomSimpleCommand
{
public override function execute(note:INotification):void
{
//if we are in the starting command we can move out of the state into the configuring commadn
if (this.stateMachine.currentState.name == StateNames.STARTING)
{
this.sendNotification(StateMachine.ACTION, null, StateNames.CONFIGURING_PRODUCT);
}
}
}


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on November 17, 2009, 05:14:52
This is not a response to the state machine query, just a comment regarding LoadupMonitorProxy.

If I understand correctly, it seems that there are separate Loadup sessions - one for the ProductCatalog load and one for each Product load - but using the one LoadupMonitorProxy instance.  Instead, if you use separate instances of LoadMonitorProxy for these, then
- you can have concurrent retrieval of more than one product
- the loading complete notification will have the instance name in the type, hence differentiating the different contexts.

However, I well recognise the role the state machine can have in overall management of this.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on November 18, 2009, 04:46:14
Since my previous post, it has occurred to me that...
- the intermittent, ad hoc product loads could also be done with a single instance of LoadMonitorProxy, where keepResourceListOpen() is invoked
- then, as required, a product resource can be added to the monitor; it will be loaded as usual
- there will not be a loading complete notification until closeResourceList() is invoked and all outstanding resources have been loaded.

Just thought I'd mention it.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: puremvc on November 18, 2009, 09:35:13
Although it seems like you might, in reality, you don't really want to query the StateMachine for the current State and take branching actions based on State. That would lead to a brittle app where it is difficult to refactor the FSM.

Instead, you kick off actions when you arrive in a given State, and you wait until those actions have completed before sending off an ACTION notification to kick the StateMachine into another State.

-=Cliff>


Title: Loading images in a Gallery
Post by: pirol on November 30, 2009, 03:27:35
Hi,
Because I just started to programm with pureMVC, I have a question about loading images after I loaded a xml.
I use the Startup Manager from this site to load a xml and a css file. Now i have a ImageVO class which contents the urls of the images.
My problem is where I should put the loading Code and the ImageData.
On one hand it is a Data so it should be in a VO but on the other hand it is easier to load it in the view.

What way is the best:
Should I put the loading code and the data in the ImageVO
Should I create a new VO and a new Proxy
Should I load it in a Mediator at put the data into the viewComponent
Should I load it directly in the view

I hope u can understand my problem.




Title: Loadup - SoundAsset
Post by: Ross on February 10, 2010, 01:42:44
Hi Philip,
Thanks for this great utility. I just started a big project with a lot of asset-loading stuff and it's really amazing, how easily and clearly I can manage these loading operations with your Loadup utility. Thanks to Tek (http://www.tekool.net), I use it in a pure actionscript project.
But now I came to a problem. I would like to use this utility to load sound assets (.mp3). In fact, your utility does load such assets. At least I think it does. But I don't know how to cast this asset properly to a sound object.
I wrote an AssetOfTypeFlashAudio class, extending the AssetBase class and implementing IAsset with a getter method, that returns a Sound object. Finally I added a AUDIO_ASSET_TYPE const to the Loadup class.

When the asset is loaded now, it's returned by the AssetOfTypeFlashAudio class. Then I try to cast it with var sound:Sound = audioAssetClass.sound . This works, too. But as soon as I try to play it (sound.play) it throws an error #1009: Cannot access a property or method of a null object reference.

Has anyone already used this utility to load sound assets?

Thank you for your time.


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on February 11, 2010, 04:35:20
I presume the key factor here is the loader class.  You don't mention the AssetFactory /IAssetFactory class and interface.

By default, a file with extension .mp3 will get treated the same as a text file, since there is no specific recognition of the mp3 file type.  Hence, by default, the file will get loaded by a loader of type URLLoader (see AssetFactory and AssetTypeMap).

I note that the Sound class itself has the facility to load mp3 files, so maybe the Sound class must be used as the loader.  This would require a new loader class in Loadup, using Sound, and implementing the IAssetLoader interface.

No doubt there are others out there that can comment more knowledgeably on this requirement.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: Ross on February 11, 2010, 09:56:01
Thanks for this tip. I actually thought about this loader issue. But I didn't find the right place to change it... Now I found it and it's working.
I added a new loader AssetLoadBySoundLoader.as, which organizes the sound load. The only problem is, that the loaderContext should be of type SoundLoaderContext. If I change it, it cannot implement IAssetLoader... So I just set this parameter to null (loader.load( url, null)).
I'll send the files to you, so you can add them to the package, if you want.


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on February 12, 2010, 05:33:53
@Ross
Thanks for this work.  It should be a great addition to the utility.  I will incorporate it into a new release as soon as I can.  I expect the release to also include support for flv type files, based on work contributed by another forum member, and it should also address the flash-only requirement as dealt with previously on this forum.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: Tekool on February 12, 2010, 05:56:02
Excellent news Philip. If you want to find the latest version of the source code for the Flash Loadup dependencies, you can find it here (http://code.google.com/p/tekool/source/browse/#svn/tags/projects/PureMVC_LoadupForFlashDemo_v1.0/src/org/puremvc/as3/utilities/loadup/assetloader%3Fstate%3Dclosed) or through my blog post (http://www.tekool.net/blog/2009/12/06/using-puremvc-loadup-utility-with-flash-ide/).


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on June 09, 2010, 04:26:19
Hi Phillip,

Is there a way to cancel an active loading sequence?

Thnx in advance,
Sander


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on June 10, 2010, 10:18:17
@Sander

The answer is No, I suppose.  But let me contribute the following thoughts
  • the difficulty is that the resource loads are typically requested as asynchronous services to be executed on a remote server, so once requested, it is hard to influence them
  • if you have dependencies within the set of resources to be loaded, then if a load fails, the dependent loads will not commence
  • if, after starting the load via the loadResources() call, you decide that you no longer want the resources, you could simply discard the response messages as they return to you, and send a 'load failed' notification for each such response, including a 'do not retry' instruction; the objective of such failed notifications is to move loadup to the 'finished incomplete' state as soon as possible.

Hope this helps.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on June 14, 2010, 02:27:41
Hi Philip,

Thanks, the 3rd suggestion should be the way to go in my case.


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: puremvc on July 29, 2010, 03:01:16
Philip has updated the Loadup utility to Version 2.1 with some new asset types, separate flex and flash swcs and a new build script to create them. Note the Flex specific classes have been renamed to reflect it.

See the Release Notes: http://trac.puremvc.org/Utility_AS3_Loadup/wiki/ReleaseNotes

-=Cliff>


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on July 06, 2011, 04:57:01
Hi Philip,

It has been a while since i worked with this utility. But i want to come back to my previous question.

You pointed out the following:
* if, after starting the load via the loadResources() call, you decide that you no longer want the resources, you could simply discard the response messages as they return to you, and send a 'load failed' notification for each such response, including a 'do not retry' instruction; the objective of such failed notifications is to move loadup to the 'finished incomplete' state as soon as possible.

How would that fit in the new Loadup situation?

Can you give me an example of how to discard the response messages and send a load failed notification?
This happends in the mediator who initiated the loading right?

Thanks in advance, Sander


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on July 07, 2011, 09:01:29
Here is an approach. There may be other and better approaches. It does not involve the mediator.

Let there be a Loadup instance called lux, with name luxName.  Let there be a new proxy, of type Proxy, with name luxHelper, where luxHelper is easily derived from luxName.  luxName and luxHelper are Strings or course.  For example, luxHelper = luxName + "Helper".

If the event occurs that means we would like to abort the loadup process
- create and register the luxHelper proxy:  = new Proxy( luxHelper, new Boolean(true) );
- so, the data property of the proxy is a Boolean.

For each ILoadupProxy proxy that is interacting with lux, assume there is a 'loaded' method and a 'failed' method, invoked within the app. In the loaded method, we have
if ( facade.hasProxy( luxHelper ) {
    retrieve the helper proxy
    if the helper proxy data is true, invoke the 'failed' method and quit the loaded method
    else carry on with the loaded method
}

I have avoided making a new class for the helper proxy, but it could be better to have one. Also, the helper proxy could be created and registered at the outset, witrh data set to false.

I hope this makes sense and that it helps.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on July 13, 2011, 03:11:19
Hi Philip,

Thanks, it works. But i'm not sure if i interpreted everything ok.
I expanded the AssetProxy's loadingComplete function as following:

:
public function loadingComplete( loadedData :Object ) :void {
    loaded = true;
    assetData = loadedData;
    loadingErrorMessage = "";

    if(facade.hasProxy(assetGroupProxy.getLUMonitorProxyName() + "_HELPER"))
    {
var helperProxy:IProxy = facade.retrieveProxy(assetGroupProxy.getLUMonitorProxyName() + "_HELPER") as IProxy
if(helperProxy.getData())
{
    doSendNotification( Loadup.ASSET_LOAD_FAILED, getProxyName() );
}
    }
    else
    {
doSendNotification( Loadup.NEW_ASSET_AVAILABLE, asset );
assetGroupProxy.loadingProgress( this, /* force report */ true );
doSendNotification( Loadup.ASSET_LOADED, getProxyName() );
    }
}

Is this the way to go?

And maybe if I explain the situation in my application more clearly you could give some more suggestions.

I have a mediator wich starts loading 2 swf's. The load is initiated by a click on a chapterbutton.
There are multiple chapters and the user is able to switch between them.
If the user clicks chapter 1, two swf's start loading.
If the user clicks chapter 2 while the two swf's have not yet finished loading, it should cancel the first two and start loading those of chapter 2.

I hope this is understandable :)

Thnx, Sander




Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on July 18, 2011, 09:24:21
@Sander

My suggestions as follows.
1. To make the code more readable, you could create an explicit LoadupHelper class and include a property, with a name such as shouldAbort, implemented as a get method e.g. function get shouldAbort() :Boolean.  This function can access and interpret the proxy's data property.  Thus the usage of the data property is kept local to LoadupHelper and can evolve over time.  There would likewise be a function set shouldAbort(...) :void.

2. In the loadingComplete function of AssetProxy, when shouldAbort is true, I would be inclined to not set loaded and assetData etc., since we want to discard anything loaded and behave as though the load failed.

3. Instead of directly modifying AssetProxy, you could extend it with your own class and override the loadingComplete method.  In addition, that class could have another method, named say loadingBehaveAsFailed
- invoked from loadingComplete when shouldAbort is true
- content same as loadingSecurityError, without the ASSET_LOAD_FAILED_SECURITY line
- thus it uses a FailureInfo object, to inform Loadup not to retry.

 Hope this helps.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on July 27, 2011, 09:20:38
Hi Philip,

This is clear now, thanks for explaining.

There is one more thing where I could use your advise.

Let's say Asset 1 has started loading and I want to start loading Asset 2 with the same loadupmonitor and assetgroupproxy. How would I accomplish that?

I can not wait for Asset 1 to send a 'complete' or 'finished incomplete' notification. I want to discard everything that has anything to do with Asset 1.

Is this at all possible? Or do I need unique loadupmonitors / assetgroupproxies?

Thanks again, Sander

Edit:
I realise that Loader.close() isn't implemented in Loadup. Is there a specific reason for that?


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on August 02, 2011, 04:10:26
@Sander
In relation to your question about asset 1 and asset 2, see the API Docs of the LoadupMonitorProxy class, specifically see the section that begins with The utility can be used to load an open-ended list of resources. In general, each instance of loadup has an associated list of resources to be loaded. When the full list is not known at the beginning, then keepResourceListOpen() can be used and addResource() can be used, as the need arises, to add a resource to the list.  Please see the API Docs for the full story. So, you could adopt that approach and use the one loadup instance for the ongoing set of resources.

Continuing with this open-ended list feature, in your case, you have an asset group proxy.  So, as each new resource to be loaded becomes known, I suppose you add it to the asset group proxy using addAssetProxy(), in addition to adding it to the loadup resource list using addResource(). I dont have experience of adding assets to the asset group in this open-ended manner, but it seems like it should be ok.

Your mention of Loader.close() is interesting. Loadup has no feature to take advantage of this; it was not anticipated as a requirement. It looks like something worth investigating. There is is the possibility of you using it directly, outside of loadup.  If you have your own sub-class of AssetProxy, as suggested in my previous post, then you have access to the loader variable.  With this, you yourself could directly invoke loader.close(), having cast loader to the appropriate type.  I dont know what event(s) this gives rise to, but the loadup instance would be depending on some expected event (e.g. IO_ERROR) in order to know the status of the resource load.  Maybe youve already tried loader.close()?

Edit: My point above about loadup depending on an event from loader.close() might be irrelevant.  After you invoke loader.close(), you could send an ASSET_LOAD_FAILED notification and that informs loadup that the resource load is to be treated as failed.

Hope this helps.
----Philip


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: svleeuwen on August 03, 2011, 03:36:56
Hi Philip,

I did see the option to keep the resourcelist open. But this creates a problem when aborting the load. Lets say you load 3 assets. Asset 1 is loading. By starting asset 2 you flag the monitor that asset 1 is no longer required. Then you start loading asset 3. Now when asset 1 or 2 completes it sees the abort flag and aborts the load for only one of the two. You can't distinguish the requests to cancel from the ones not to. Or am I missing something?

Another thing is that an open resource list never sends loadcomplete notifications until you specifically close it. That's kind of unhandy for possible loader-views who respond to those notifications. This could be worked around by using only the progress notifications. If that's the only option.

Sander


Title: Re: Loadup - A PureMVC AS3 Utility
Post by: philipSe on August 04, 2011, 12:14:16
@Sander
As regards asset1 and asset2 and asset3, let's say the data property of the LoadupHelper class becomes more sophisticated: could be an array of pairs, each pair consisting of [ proxyName, shouldAbort ], or maybe it's just an array of the proxyNames that are to be discarded.  In any case, you then have a way of deciding for each case of asset loadingComplete whether it is one of the ones to discard or not.

As regards "open resource list never sends loadcomplete notifications", I'm not clear what you mean. My understanding is that the attempted load of each asset ends with invocation of one of the event handlers in the asset proxy class, such as loadingComplete. Yes, the loadup instance will not send a loading finished notification (or a loading finished incomplete notification) until all the resources it has been charged with loading have been processed.  It does send the 'waiting for more resources' notification when it has dealt with the list so far.

Hope this helps.
----Philip