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
Print
Author Topic: first project with pureMVC  (Read 67219 times)
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #15 on: October 30, 2007, 02:51:56 »

I have a question about the demo...

Where is com.ugoletti.controller.StartupMonitorCommand implemented?  I can't find it.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #16 on: October 31, 2007, 10:56:29 »

In the ApplicationSkeleton.zip, StartupMonitorCommand is in ApplicationSkeleton\com\ugoletti\controller\

-=Cliff>
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #17 on: October 31, 2007, 11:35:24 »

Yeah, I see that, but in the code, ApplicationFacade calls ApplicationStartupCommand which add two sub commands, ModelPrepCommand and ViewPrepCommand.  I can't find where StartupMonitorCommand is used.  Am I downloading a different zip?

Sorry if I'm missing something right in front of my face.  I'm new to this framework.  Heard this was better than cairngorm ;)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #18 on: October 31, 2007, 01:01:37 »

Actually, that's a good question. Looking through the code, it looks like it might be an unused bit that was refactored out.

I'm hoping Daniele can chime in here on this one.

-=Cliff>
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #19 on: October 31, 2007, 02:32:59 »

I just created this...

I thought this might be a little more reusable then counting.

If someone can advise if it's complying to best practice  :)  I'd like to contribute something to this post.  8)

:
package com.meekgeek.model
{
import flash.utils.Dictionary;

import org.puremvc.interfaces.IProxy;
import org.puremvc.patterns.proxy.Proxy;

import com.meekgeek.ApplicationFacade;

public class StartupMonitorProxy extends Proxy implements IProxy
{
public static const NAME:String = "StartupMonitorProxy";

private var resourceList:Dictionary;

public function StartupMonitorProxy(proxyName:String=null, data:Object=null)
{
super(proxyName, data);
resourceList = new Dictionary();
}

override public function getProxyName():String
{
return StartupMonitorProxy.NAME;
}

public function addResource(name:String):void
{
resourceList[name] = false;
}

public function loadResources():void
{
trace('loading resources');
for(var key:String in resourceList)
{
trace('load resource: '+key);
var proxy:* = facade.retrieveProxy( key ) as Proxy;
proxy.load();
}
}

public function resourceComplete( name:String ):void
{
resourceList[name] = true;
checkResources();
}

private function checkResources():void
{
var resourcesLoaded:Boolean = true;
for(var key:String in resourceList)
{
if(!resourceList[key])
{
resourcesLoaded = false;
break;
}
}
if(resourcesLoaded)this.sendNotification( ApplicationFacade.LOADING_COMPLETE);
}
}
}

It's the first proxy to be registered.  All other proxies that need to be loaded before moving on, will call addResource() which adds them to a list of resources.  Once all proxies have been added, you execute a command to call loadResources() which calls load() on all proxies in the list.  Once the individual proxies complete the load process, they call resourceComplete() to advise StartupMonitorProxy that something has finished loading.  It then checks to see if all proxies are ready.  If all proxies check out, it notifies the framework to move on :)

If this is looking like something that other's can use I can upload the files I'm using.
« Last Edit: October 31, 2007, 02:42:23 by meekgeek » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #20 on: October 31, 2007, 06:20:45 »

This is a really elegant solution. I like it much better than counting as well.

In Cairngorm on a big project a couple of years ago, I did a take on this resource loading problem based on a counter being preset to the number of resources to load and each resource loaded decrementing the counter, etc. It's a little better than the counting approach, possibly, but your class above is really the cleanest take on the problem I've seen yet.

Great work! Please do post what you've got working here. Soon (really, I promise) there is going to be a much better way for the community to contribute.

-=Cliff>
Logged
danieleUg
Courseware Beta
Full Member
***
Posts: 28


View Profile Email
« Reply #21 on: November 05, 2007, 02:34:04 »

Yeah, I see that, but in the code, ApplicationFacade calls ApplicationStartupCommand which add two sub commands, ModelPrepCommand and ViewPrepCommand.  I can't find where StartupMonitorCommand is used.  Am I downloading a different zip?

Sorry if I'm missing something right in front of my face.  I'm new to this framework.  Heard this was better than cairngorm ;)

Hi meekgeek,
the file StartupMonitorCommand  isn't used, you can delete it, sorry but I forgot to delete before post the zip :)


Daniele
Logged
danieleUg
Courseware Beta
Full Member
***
Posts: 28


View Profile Email
« Reply #22 on: November 05, 2007, 04:26:37 »

Hi meekgeek,
your suggestion is very cool and I have modify my ApplicationSkeloton code, the new version can be downloaded here:

http://dev.ugoletti.com/puremvc/ApplicationSkeleton_v1.3.zip

I have based the new version to your code but with few differences:
- I have add a parameter to addResource function, because some resources can be loaded before others, ie in my example the config.xml must be read before the other resources.
- I have used a Array insteed a Dictionary becase during the iteration the keys are in different order how are created


I just created this...

I thought this might be a little more reusable then counting.

If someone can advise if it's complying to best practice  :)  I'd like to contribute something to this post.  8)

......

It's the first proxy to be registered.  All other proxies that need to be loaded before moving on, will call addResource() which adds them to a list of resources.  Once all proxies have been added, you execute a command to call loadResources() which calls load() on all proxies in the list.  Once the individual proxies complete the load process, they call resourceComplete() to advise StartupMonitorProxy that something has finished loading.  It then checks to see if all proxies are ready.  If all proxies check out, it notifies the framework to move on :)

If this is looking like something that other's can use I can upload the files I'm using.
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #23 on: November 08, 2007, 11:03:25 »

I'm glad I could help in some way. :)
Logged
deltajam
Courseware Beta
Full Member
***
Posts: 25


View Profile Email
« Reply #24 on: November 22, 2007, 09:38:00 »

Why is the swf footprint so big?  When I compile the project ... it seems to be a massive 346kb.  When I extract the files it seems to be 222kb (which is still pretty big don't you think) and when I compile it, it's 346kb.  What gives?  Is there a setting in Flashdevelop that I'm not aware of?
Logged
danieleUg
Courseware Beta
Full Member
***
Posts: 28


View Profile Email
« Reply #25 on: November 22, 2007, 09:59:01 »

Hi deltajam,
if you are using FlexBuilder 3 try to read this: http://www.buntel.com/blog/index.cfm/2007/10/15/The-Export-Release-Wizard


Daniele
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #26 on: November 22, 2007, 10:27:47 »

Here's a video that explains everything pretty well:
http://labs.adobe.com/technologies/flex/videos/exportreleasewizard/

-=Cliff>
Logged
Joel Hooks
Courseware Beta
Sr. Member
***
Posts: 146


baby steps

 - 46288188  - passport@provinsal.com  - joeltuff
View Profile WWW Email
« Reply #27 on: December 20, 2007, 05:10:01 »

I'm refactoring my application, and used this instead of chaining remote service calls in a single proxy. it really ( really ) cleaned up my code and made it easier to understand. Prior to this I had one single 'DataProxy' to facilitate this, and it led to one monster class that was starting to get confusing.

Anyways, thanks!

I just created this...

I thought this might be a little more reusable then counting.

If someone can advise if it's complying to best practice  :)  I'd like to contribute something to this post.  8)

It's the first proxy to be registered.  All other proxies that need to be loaded before moving on, will call addResource() which adds them to a list of resources.  Once all proxies have been added, you execute a command to call loadResources() which calls load() on all proxies in the list.  Once the individual proxies complete the load process, they call resourceComplete() to advise StartupMonitorProxy that something has finished loading.  It then checks to see if all proxies are ready.  If all proxies check out, it notifies the framework to move on :)

If this is looking like something that other's can use I can upload the files I'm using.
Logged

http://joelhooks.com - my ramblings about developing with actionscript and python using pureMVC and django respectively.
philipSe
Sr. Member
****
Posts: 139


View Profile Email
« Reply #28 on: January 28, 2008, 09:23:47 »

Thanks to Cliff for Puremvc and for these forums etc., and to danieleUg and to meekgeek for the StartupMonitorProxy solution, as implemented in the ApplicationSkeleton code.

My application requires a more powerful method of sequencing the loading of data resources at startup.  Specifically, I want to be able to specify that a resource cannot be loaded until specific other resources have been loaded. The dependencies are such that use of the blockChain boolean on the resource would result in sub-optimal loading, in that loading of some resources would be unnecessarily delayed.

I am presenting the basics of my code here, in case it is of interest to others.

My resource is called StartupResource, as follows.
:
package com...model
{
/*
*  From original code of Daniele Ugoletti and Meekgeek
*  on the puremvc forums, modified to use 'requires' instead
*  of blocking boolean.  Also have a multi-valued status instead
*  of a 'loaded' boolean.

* @author Philip Sexton
* @since  11.01.2008
*/
public class StartupResource
{
        private static const EMPTY :int = 1;
        private static const LOADING :int = 2;
        private static const LOADED :int = 3;

public var proxyName:String;

private var status :int;

// StartupResources, pre-requisites for this resource, if any.
// These pre-requisites must be loaded before this resource can be loaded.
private var _requires :Array;

public function StartupResource( proxyName:String )
{
this.proxyName = proxyName;
this.status = EMPTY;
this.requires = new Array();
}
public function setStatusToLoading() :void {
    status = LOADING;
}
public function setStatusToLoaded() :void {
    status = LOADED;
}
public function isLoaded() :Boolean {
    return status == LOADED;
}
public function set requires( resources :Array ) :void {
    _requires = resources;
}
public function get requires() :Array {
    return _requires;
}
public function isOkToLoad() :Boolean {
    if ( status != EMPTY ) return false;
    for( var i:int =0; i < requires.length; i++) {
        if ( ! (requires[i] as StartupResource).isLoaded() )
            return false;
    }
    return true;
}
}

}

StartupMonitorProxy is as follows.  Note that method addResource() is not called from the individual resource proxies; it is called from the startup command.  In fact, the individual resource proxies contain no code specific to the startup monitor.

:
package com...model
{
import org.puremvc.interfaces.*;
    import org.puremvc.patterns.proxy.Proxy;
import com...model.StartupResource;

/*
*  A proxy for the startup loading process.
*  From original code of Daniele Ugoletti and Meekgeek
*  on the puremvc forums, modified to use a StartupResource
*  designed to cater for more complex constraints.

* @author Philip Sexton
* @since  11.01.2008
*/
    public class StartupMonitorProxy extends Proxy implements IProxy
    {
public static const NAME:String = "StartupMonitorProxy";
// array listing all the resources to be loaded
private var resourceList:Array;
//---- total resource to read
//-----private var totalResources:int = 0;
// number of loaded resources
private var loadedResources:int = 0;

public function StartupMonitorProxy ( data:Object = null )
        {
            super ( NAME, data );
this.resourceList = new Array();
        }


/**
         * Add a resource to be loaded
         */
public function addResource( r :StartupResource ):void
{
this.resourceList.push( r );
}

/**
         * Start/Continue to load all resources
         */
public function loadResources():void
{
for( var i:int = 0; i < this.resourceList.length; i++)
{
var r:StartupResource = this.resourceList[i] as StartupResource;
if ( r.isOkToLoad() )
{
var proxy:* = facade.retrieveProxy( r.proxyName ) as Proxy;
r.setStatusToLoading();
proxy.load();
}
}
}

/**
         * The resource is loaded, update the state and check if the loading process is completed
*
         * @param name proxy name
         */
public function resourceLoaded( proxyName :String ):void
{
for( var i:int = 0; i < this.resourceList.length; i++)
{
var r:StartupResource = this.resourceList[i] as StartupResource;
if ( r.proxyName == proxyName )
{
r.setStatusToLoaded();
this.loadedResources++;

// send the notification for update the progress bar
//this.sendNotification( ApplicationFacade.LOADING_STEP, this.resourceList.length / this.loadedReources * 100 );

// if not all loaded, continue load.
if ( !allResourcesLoaded() )
{
this.loadResources();
}
break;
}
}

}

/**
         * Check if the loading process is completed
*
         * @return boolean process is completed
         */
private function allResourcesLoaded():Boolean
{
for( var i:int = 0; i < this.resourceList.length; i++)
{
var r:StartupResource = this.resourceList[i] as StartupResource;
if ( !r.isLoaded() )
{
return false;
}
}
//this.sendNotification( ApplicationFacade.LOADING_COMPLETE );
return true;
}
}
}

The StartupCommand has code as follows, here presented in pseudo-code.
:
public class StartupCommand extends SimpleCommand implements ICommand {

private var monitor :StartupMonitorProxy;

override public function execute( note:INotification ) : void {

    facade.registerProxy( new StartupMonitorProxy() );
    this.monitor = facade.retrieveProxy( StartupMonitorProxy.NAME ) as StartupMonitorProxy;
            ... register other proxies ...

            var rA :StartupResource = makeAndRegisterStartupResource( ProxyA.NAME );
            var rB :StartupResource = makeAndRegisterStartupResource( ProxyB.NAME );
            var rC :StartupResource = makeAndRegisterStartupResource( ProxyC.NAME );
            var rD :StartupResource = makeAndRegisterStartupResource( ProxyD.NAME );
            var rE :StartupResource = makeAndRegisterStartupResource( ProxyE.NAME );
            var rF :StartupResource = makeAndRegisterStartupResource( ProxyF.NAME );
            var rG :StartupResource = makeAndRegisterStartupResource( ProxyG.NAME );
            var rH :StartupResource = makeAndRegisterStartupResource( ProxyH.NAME );

            rC.requires = [ rA, rB ];
            rD.requires = [ rC ];
            rE.requires = [ rD ];
            rH.requires = [ rE, rF, rG ];
            monitor.loadResources();

... register mediator(s) ...
}
private function makeAndRegisterStartupResource( proxyName :String ) :StartupResource {
    var r :StartupResource = new StartupResource( proxyName );
    monitor.addResource( r );
    return r;
}
}

With the completion of each resource load, in the proxy/responder objects, a 'loaded' notification specific to the resource is sent.  All such notifications are handled by a StartupResourceLoadedCommand.  The application facade has registered this command against each of the notifications.  The command code is as follows.

:
public class StartupResourceLoadedCommand extends SimpleCommand {

/**
* Inform the startup monitor that a resource is now loaded.
* The notification body identifies the particular resource.
*/
override public function execute( note:INotification ) : void {
    ( facade.retrieveProxy( StartupMonitorProxy.NAME ) as StartupMonitorProxy).
        resourceLoaded( note.getBody() as String );
}
}


I hope the above makes sense.  Some people may think it unnecessary.  Any comments are welcome.

Thank you
    Philip
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #29 on: January 28, 2008, 12:58:16 »

Phillip,

This is great work. Could you send me a copy of the code as a demo so that I can look it over more closely? My net connection is dead and I read this post on my phone. I like the way you set the dependencies on resources needing to be loaded.

I'd like to see if we can extract some of this into an off the rack utility with a demo that uses the utility. Are you up for that? Perhaps you could do the utility and work with daniele to modify his demo to use your utility. Or do another demo that uses the utility but with a more complex  requirement showing off the dependency handling.

Of course to really make it complete we'd want to be able to implement timeout and retry policies or each resource...

:)
-=Cliff>
Logged
Pages: 1 [2] 3 4
Print