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 42800 times)
danieleUg
Courseware Beta
Full Member
***
Posts: 28


View Profile Email
« Reply #30 on: January 28, 2008, 03:10:29 »

Hi Philip,
thank for the suggestion, we look on it in depth.

For now I can say that I already have a similar implementation that is in the demo repository that Cliff will release soon.

In StartupMonitorProxy there is the addReesource method that have blockChain parameter

:
public function addResource( proxyName:String, blockChain:Boolean = false ):void
{
this.resourceList.push( new ResourceVO( proxyName, blockChain ) );
}

Your implementation is interesting because you can specify the the resources dependancy.



« Last Edit: January 28, 2008, 03:17:07 by danieleUg » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #31 on: January 29, 2008, 07:30:02 »

Hi guys,

Phillip just sent ma a copy of his code with a description of which classes could be extracted into a utility.

I wonder if we could turn this into a util nd refactor your demo to use it? Perhaps we could add some requirements that show how to use the dependency stuff too.

Demos will be far more useful if the special functionalities can be reused easily.

-=Cliff> 
Logged
philipSe
Sr. Member
****
Posts: 139


View Profile Email
« Reply #32 on: January 30, 2008, 03:43:18 »

Cliff /Daniele /others

Following on Cliff's comments, I have been thinking about this utility/demo suggestion and whether I should offer to contribute.  So, if you like, I would be willing to go ahead and...
1. package the relevant classes into a separate utility, with class level comments to explain usage
2. create a simple demo app to use this utility and show off the dependency feature.

Utility...
I could package this using my own company naming e.g. com.xyz.utils...., but I presume we want a generic naming so that more utilities can be added, code can be modified etc.
What about org.puremvc.forums as the base package?  Then we could have <base>.utils and <base>.demos as the next levels.  I'm new to this, so maybe I'm missing the point, or maybe I've missed some posts regarding this.

Anyway, for this case, say we have <base>.utils.startupWithDependencies.  The relevant classes (3 I believe) could then sit directly in that package, or do we prefer sub-folders for controller and model?

Is startupMonitor a better name for the utility? - I am avoiding this because I don't want to present this as the only startup solution.

Demo...
This would be packaged as <base>.demos.startupWithDependencies, with sub-folders for model/view/controller.  A demo app does not have to have the same name as a utility, of course, though I propose it in this case.

Finally I would zip all this to Cliff, with a .swf for the app, and presumably a .swc for the utility.  This code could then be enhanced (or ignored!), by others.

I am very aware that all I've done is adapt code originally created by daniele and meekgeek, and use daniele's ApplicationSkeleton demo as a reference.  So, if anyone else would like to take the lead on one or both of these items, that is fine by me.

Regards
    Philip
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #33 on: January 30, 2008, 06:32:05 »

Phillip,

For the packaging we're using in the rpository, as well as the general details of contributing to the project, have a look at the Contributor Central board.

I would call the project StartupManager - it does more than monitor it actively manages the startup process.

Once extracted from the demo is it dependent on Flex or is it possible to use with Flash? This will determine the package space:

org.puremvc.as3.utilities.startupmanager.*

Or

org.puremvc.as3.utilities.flex.startupmanager.*

-=Cliff>
Logged
philipSe
Sr. Member
****
Posts: 139


View Profile Email
« Reply #34 on: January 30, 2008, 07:34:44 »

Ok, Cliff, I'll take a look at Contributor Central.
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #35 on: January 31, 2008, 12:27:04 »

This is great!  Just what I needed.  I will be implementing timeouts for my project.  This is beautiful.  Thanks philipSe.
Logged
danieleUg
Courseware Beta
Full Member
***
Posts: 28


View Profile Email
« Reply #36 on: February 04, 2008, 10:32:53 »

Hi Cliff,
if you want I can work with Phillip and integrate him code in AppSkeleton, have sense?

Daniele
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #37 on: February 04, 2008, 11:26:42 »

So over the weekend I started to add the Time out functionality.  I have a site that did not load completely because a streaming server somewhere was turned off.  Needless to say, people were upset. :)

My delima is that until now, there was no flash spicific code in the framework.  I thought that best place to put the timer was in Phillip's StartupResource class, but this brings up other things like, "what's going to be listening for timer event?"  Does this really matter now that the framework is being ported to all these other languages and this version is more specifically the as3 version?

Probablly being the biggest newbe of the bunch, I'd like to know what's best practice, and if any body has any suggestions on how to implement the timeout functionallity.  The more I think about it, the more important it is to have this on a site that loads in data from other servers.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #38 on: February 04, 2008, 12:53:50 »

meekgeek,

There should be a configurable retry policy for each resource that determines how many times (if at all) it is allowed to retry before giving up and sending a fault notification. It should also govern the time between retries and the message to send when it fails.

The resource should send progress notifications as it is loading. It should also send notifications when it retries so that a mediator/view component that displays progress can indicate retries elapsed per resource. There should also be a message that is sent as a notification. Listen to these with the Proxy and turn them into Notifications.

It should contain its own system for displaying progress. True the developer could do this, but we could save them a lot of time by building it in and letting them control the look and feel of it.

A Mediator could pop up a TitleWindow that it displays progress in. If this resource loading process is supposed to complete before we register Mediators, then you can still register a Mediator prior to starting this process that listens for progress notifications and handles displaying them.

In fact you probably want a PrepStartupManagerCommand that is used to create and register the StartupProgressMediator, followed by the StartupMonitorProxy, and doing any other kick off operations.

For bonus points, you could pass true or false as an argument to the PrepStartupManagerCommand (in the notification body) that tells it whether or not to create and register the StartupProgressMediator as well as the StartupMonitorProxy. Send true and it starts the visual progress monitoring, fals and it doesn't. The notifications are still sent, so the user could do their own progress display or none at all.

The ApplicationFacade of the implementing app would do:

:
registerCommand( PrepStartupManagerCommand.NAME, PrepStartupManagerCommand)
The StartupCommand of the application that is using this utility would simply
:
sendNotification(PrepStartupManagerCommand.NAME)

-=Cliff>
Logged
judholliday
Newbie
*
Posts: 2


View Profile Email
« Reply #39 on: February 05, 2008, 01:04:59 »

I've been following this post with interest as I (and a couple co-workers) are working on setting up a Flash application using PureMVC.

The work that has been done with the StartupMonitorProxy so far has been great. However, I have a question about how you might go about passing data in to the proxies that are being managed by the StartupMonitorProxy.

In my example case the first proxy I want to load (ConfigProxy) is going to load in a configuration xml file. I would like to be able to specify the location of this xml file via FlashVars. Previously I was accomplishing this by passing in the app.loadInfo object when I called the 'load' method on ConfigProxy. But now that StartupMonitorProxy is in place it is calling 'load' automatically and obviously is not setup to pass information that way.

Is there a way to pass in data to the Proxy on load? Or is there another preferred way you could do something like this? It's entirely possible that I am missing an obvious answer because I am fairly new to PureMVC.

Thanks,
Jud
Logged
philipSe
Sr. Member
****
Posts: 139


View Profile Email
« Reply #40 on: February 05, 2008, 03:01:11 »

Jud
Is it a solution for you to set the file location info as a property of ConfigProxy, before starting the load of resources?  Then the load method of ConfigProxy can use that info.  Am I missing something?
    Philip
Logged
judholliday
Newbie
*
Posts: 2


View Profile Email
« Reply #41 on: February 05, 2008, 09:42:42 »

No, you are not missing something, and that is most definitely a possibility. I guess what I am looking for is a consistent way to pass information to a proxy before load. Creating and setting different properties on the proxies didn't seem like the most elegant solution because the interface for the class would essentially be different for each proxy. A new developer coming in might not know what properties have to be set before 'load' can be called. But maybe just adding an init method or something of the sort would work just as well.
Logged
philipSe
Sr. Member
****
Posts: 139


View Profile Email
« Reply #42 on: February 07, 2008, 02:52:27 »

Jud
Presumably, as an alternative to an init method, you could pass the file location info as an argument to the constructor of ConfigProxy.  This makes it very plain that it is essential to that proxy.  I'm assuming this does not contravene best practice.
    Philip
Logged
meekgeek
Full Member
***
Posts: 25


View Profile Email
« Reply #43 on: February 07, 2008, 01:35:13 »

Ok, I figured something out.  This is what I came up with for timing out.  I might be going in a different direction so feel free to pull me in.

I didn't want to get to far from where Philip was heading but I did want to keep things in reach of the ApplicationFacade so I could send notifications.

So here's what I did different.  Seeing as all these examples have the proxies using the same method ( loading, onComplete, etc).  I created the StartupResourceProxy which extends Proxy. All proxies that now work with the StartupMonitorProxy extend StartupResourceProxy in my project.  I also moved Philips StartupResource class in here.

Here's the code.
:
package org.puremvc.utilities.startupmanager
{
import com....ApplicationFacade;

import flash.events.TimerEvent;
import flash.utils.Timer;

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

public class StartupResourceProxy extends Proxy implements IProxy
{
private static const EMPTY :String = 'empty';
        private static const LOADING :String = 'loading';
        private static const LOADED :String = 'loaded';
        private static const TIMED_OUT:String = 'timed_out';

private var status :String;

private var _timeout:int;
private var timer:Timer;

// 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 StartupResourceProxy(proxyName:String=null, data:Object=null)
{
super(proxyName, data);

this.status = EMPTY;
this.requires = new Array();
}

public function setStatusToLoading() :void
{
    status = LOADING;
   
    if(this._timeout != 0)
    startTimer();
}

public function setStatusToLoaded() :void
{
    status = LOADED;
    if(this._timeout != 0)
    timer.stop();
}

public function setStatusToTimedOut() :void
{
status = TIMED_OUT;
}

public function isLoaded() :Boolean
{
    return status == LOADED;
}

public function isTimedOut() :Boolean
{
return status == TIMED_OUT;
}

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++) {
    var r:StartupResourceProxy = requires[i] as StartupResourceProxy;
        if ( !r.isLoaded())
        return false;
    }
    return true;
}

public function set timeout(value:int):void
{
this._timeout = value;
}

private function startTimer():void
{
    timer = new Timer(this._timeout*1000, 1);
        timer.addEventListener(TimerEvent.TIMER, timedOut);
        timer.start();
}

private function timedOut(e:TimerEvent):void
{
this.sendNotification( ApplicationFacade.STARTUP_RESOURCE_TIMEDOUT, this.getProxyName());
}
}
}
and here's the interface you can implement:
:
package org.puremvc.utilities.startupmanager
{
import flash.events.Event;

public interface IStartupResourceProxy
{
/**
* Get the Proxy name
*
* @return the Proxy instance name
*/
function getProxyName():String;

function onComplete(e:Event):void;
function load():void;
}
}

I've added some code to Philips StartupResouce class which handles the timer event.  If the resource times out before it's finished loading, it notifies the StartupResourceCommand as follows.

:
package com....controller
{
import com....ApplicationFacade;
import com....model.StartupMonitorProxy;

import org.puremvc.interfaces.ICommand;
import org.puremvc.interfaces.INotification;
import org.puremvc.patterns.command.SimpleCommand;

public class StartupResourceTimedOutCommand extends SimpleCommand implements ICommand
{
override public function execute(notification:INotification):void
{
( facade.retrieveProxy( StartupMonitorProxy.NAME ) as StartupMonitorProxy).
    resourceTimedOut( notification.getBody() as String );
}

}
}

This lets the monitor know what just timed out.  I added a few things to the monitor to work with the resources that have timed out. It primarily just adds the resource to a list and allows the system to keep going if it doesn't finish loading.

Here's the code:
:
package com....model
{

import com....ApplicationFacade;

import org.puremvc.interfaces.*;
import org.puremvc.patterns.proxy.Proxy;
import org.puremvc.utilities.startupmanager.StartupResourceProxy;


    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;
// array listing all the resources that timed out.
private var timedOutResourcesList:Array;
// number of loaded resources
private var loadedResources:int = 0;

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


/**
*Add a resource to be loaded

* @param r
*
*/
public function addResource( r :StartupResourceProxy, timeout:int=0 ):void
{
this.resourceList.push( r );

//If timeout included, add a timer;
if(timeout!=0)
r.timeout = timeout;
}

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

/**
*The resource timed out, adds proxy to a list of any timed out proxies.

* @param proxyName
*
*/
public function resourceTimedOut(proxyName :String ):void
{

for( var i:int = 0; i < this.resourceList.length; i++)
{
var r:StartupResourceProxy = this.resourceList[i] as StartupResourceProxy;
if ( r.getProxyName() == proxyName )
{
r.setStatusToTimedOut();
timedOutResourcesList.push(r.getProxyName());
this.loadedResources++;

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

/**
         * 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:StartupResourceProxy = this.resourceList[i] as StartupResourceProxy;
if ( r.getProxyName() == 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:StartupResourceProxy = this.resourceList[i] as StartupResourceProxy;
if ( !r.isLoaded() && !r.isTimedOut() )
{
return false;
}
}

this.sendNotification( ApplicationFacade.LOADING_COMPLETE );
return true;
}

public function timeOutList():Array
{
return timedOutResourcesList;
}
}
}

And here's the command that starts it all up.

:
package com....controller
{

public class ModelPrepCommand extends SimpleCommand implements ICommand
{

override public function execute( note:INotification ):void
{
/* ... register monitor proxies ... */
facade.registerProxy( new StartupMonitorProxy() );
    var monitor:StartupMonitorProxy = facade.retrieveProxy( StartupMonitorProxy.NAME ) as StartupMonitorProxy;
   
            /* ... register other proxies ... */
            facade.registerProxy( new ProxyA() );
            facade.registerProxy( new ProxyB() );
           
            var rA:StartupResourceProxy = facade.retrieveProxy( ProxyA.NAME ) as StartupResourceProxy;
            var rB:StartupResourceProxy = facade.retrieveProxy( ProxyB.NAME ) as StartupResourceProxy;

monitor.addResource( rA, 10);
monitor.addResource( rB, 10 );

          rA.requires = [ rB ];
           
          monitor.loadResources();
}
}
}

Sorry for the long post.  This seems to work for me and I like how it hide most of the code by just extending the StartupResourceProxy. I tought about getting the retry policies going but wanted to get some feed back about this first.  Let me know if this helps anybody. PUREMVC RULES!!  ;D
Logged
Joel Hooks
Courseware Beta
Sr. Member
***
Posts: 146


baby steps

 - 46288188  - passport@provinsal.com  - joeltuff
View Profile WWW Email
« Reply #44 on: February 07, 2008, 05:44:58 »

meekgeek,

The timers all fire right out of the gate, so if they are set to 10, then it starts counting immediately, which is something I could plan for, but as the sequence goes it started adding them as completed resources and fired the LOADING_COMPLETE note when they weren't actually loaded.

It is also incrementing the completed resources when they time out. A timed out resource is not complete ;)

I'm loading a large dataset from multiple MySQL tables, so this is partly to blame. Works great otherwise.
Logged

http://joelhooks.com - my ramblings about developing with actionscript and python using pureMVC and django respectively.
Pages: 1 2 [3] 4
Print