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]
1  Announcements and General Discussion / General Discussion / Re: Mediator Problem on: May 13, 2009, 07:49:00
Hey Isra!

Your code is correct!

You should checkout the source files of the demos. They cover pretty much of all those questions.

=)
2  Announcements and General Discussion / Getting Started / Re: creationComplete vs onRegister on: March 31, 2009, 12:06:11
Sorry. I was in a hurry last time. I´ll try to be more specific.

This my Application.mxml:
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">
<mx:TitleWindow x="106" y="174" width="426" height="275" layout="absolute" title="User Detail" showCloseButton="true">
<mx:TabNavigator x="0" y="0" width="100%" height="100%">
<mx:HBox label="My Self" width="100%" height="100%">
<mx:Image width="152" height="202">

</mx:Image>

<mx:VBox width="100%">
<mx:HBox width="100%">
<mx:Label text="Status: " fontWeight="bold"/>
<mx:Text text="At Work" width="100%"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Name: " fontWeight="bold"/>
<mx:Text text="William Rafael Ribeiro" width="100%"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label text="Personal Message: " fontWeight="bold"/>
<mx:Text text="Hi there!" width="100%"/>
</mx:HBox>
</mx:VBox>
</mx:HBox>
<ns1:UsersList label="Friends" width="100%" height="100%">
</ns1:UsersList>
</mx:TabNavigator>
</mx:TitleWindow>

</mx:Application>

And this is the UserList:
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Accordion xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
<mx:Canvas label="Work" width="100%" height="100%">
<mx:DataGrid x="0" y="0" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Status" dataField="status"/>
<mx:DataGridColumn headerText="Name" dataField="name"/>
<mx:DataGridColumn headerText="Personal Message" dataField="pmessage"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
<mx:Canvas label="College" width="100%" height="100%">
<mx:DataGrid x="0" y="0" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Status" dataField="status"/>
<mx:DataGridColumn headerText="Name" dataField="name"/>
<mx:DataGridColumn headerText="Personal Message" dataField="pmessage"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
<mx:Canvas label="Family" width="100%" height="100%">
<mx:DataGrid x="0" y="0" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Status" dataField="status"/>
<mx:DataGridColumn headerText="Name" dataField="name"/>
<mx:DataGridColumn headerText="Personal Message" dataField="pmessage"/>
</mx:columns>
</mx:DataGrid>
</mx:Canvas>
</mx:Accordion>

I want one mediator for each component, ApplicationMediator and UsersListMediator, (wich I don´t have the code right now) but the doubt is, where do I register the UsersListMediator? on the TabNAvigator´s index change event? on UsersList´s creationComplete event? On ApplicationMediator´s onRegister?
My guess is that there´s more than one solution but wich one is better or the correct one?

Thanks!
3  Announcements and General Discussion / Getting Started / Re: creationComplete vs onRegister on: March 30, 2009, 02:28:27
Wow ... there´s a warning about this post beeing old but ... I guess I´m pretty sure to reply.

Ok, to the question. In my code I do something like this.
:
...
facade.registerMediator( new UsersListMediator( new UsersList() ) );
...

So, everything changes on the UsersListMediator. Should I use the Container initialize() method or FlexEvent.CREATION_COMPLETE????

I can be more specific if that wasn´t clear enought.

Thansk!
4  PureMVC Manifold / MultiCore Version / FSM Utility Question on: December 18, 2008, 10:26:29
Hi guys,

I just started using the FMS utility, wich I think it´s a incredible utility, and I already got some questions.

I´m making a simple remote login app. The FMS xml is as follow

:
<fsm initial={App.STATE_READY}>
  <state name={App.STATE_READY} entering={LoginPanelMediator.RESET} exiting= LoginPanelMediator.LOGIN_TRY}>
    <transition action={LoginPanelMediator.VALID_LOGIN_FORM} target={App.STATE_TRY_LOGIN}/>
  </state>
   
  <state name={App.STATE_TRY_LOGIN} entering={ApplicationFacade.CMD_LOGIN}>
    <transition action={UserProxy.ACTION_LOGIN_OK} target={App.STATE_USER_HOME}/>
    <transition action={UserProxy.ACTION_LOGIN_FAIL} target={App.STATE_READY}/>
  </state>
   
  <state name={App.STATE_USER_HOME} >
    <transition action={App.ACTION_LOGOUT} target={App.STATE_READY}/>
  </state>    
</fsm>;

The idea is that simple: Initial state presents the Login Panel. When the user click on button "Log me in!" the app changes to the "Trying to Login" State that shows a wait message. The login is validated on a PHP remote server. If the response is a valid login, change the app state to the "User Home State" wich shows the user´s home screen. If not valid login, goes back to initial state showing the error message sent by the server. The only action that is avaiable on User Home state is the Logout wich brings the user back to the initial state of the app.

Well, that didn´t work as I expected. In fact, I found my self traped in a mase of notifications and actions and commands. And the timming and flow of them.

The problem was that the remote response was being faster that the FSM could change state. In detail: the UserProxy executes the login() method, the response is instantaneous, so it send the UserProxy.ACTION_LOGIN_* notification. But, the app is still in STATE_READY that doesn´t know how to process the action, so the app stops working.

To fix that, I just changed the StateMachine.as, transitionTo() method like this:
:
// Enter the next State
currentState = nextState;
if ( nextState.entering ) sendNotification( nextState.entering, nextState );
//currentState = nextState;

I don´t know if this right but ... what do you guys think? I really don´t feel confortable changing the Utilitys source but other fixes would need much more coding.

Looking foward for you solutions and comments.  :)
5  PureMVC Manifold / MultiCore Version / Different SWF communicating with LocalConnection and Pipes? on: September 05, 2008, 03:15:22
Hi guys,

one of the great things of building applications is the opportunity to put in practice great ideas that solve great problems.

And I´m in the edge of solving a simple problem: How to make two PureMVC MultiCore-Pipes applications in different SWFs  communicate.

I hope you guys can help me.

One Swf is the Shell and the other is operating as Module but in fact it is a <mx:Application> that implements IPipeAwareModule and all other PMVCMCP classes for regular modules. The Shell loads the external SWF and cast it as local ExternalModule that implements IPipeAwareModule.

Something similar as
:
public class ExternalModule extends UIComponent implements IPipeAwareModule{

private var _request:URLRequest;
private var _loader:Loader;
private var _url:String;
private var _conn:LocalConnection;

public function ExternalModule ()
{
_request = new URLRequest(url);
_loader = new Loader();

_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);

_loader.contentLoaderInfo.addEventListener(FaultEvent.FAULT, onFault);

_conn = new LocalConnection();

_conn.allowDomain();

_conn.addEventListener(StatusEvent.STATUS, onStatus);

                _conn.client = this;
}

               public function load():void{
CursorManager.setBusyCursor();
try{
_loader.load(_request);
}
catch (error:Error)
                       {
                           CursorManager.removeBusyCursor();
                              trace("Unable to load URL: " + error);
                        }
        }

                private function onLoaded(evt:Event):void{
CursorManager.removeBusyCursor();

// Loader can be added to the UIComponent class. ???
addChild(_loader);

try
{
// listen to events from child
    _conn.connect("fromChild");
}
catch (error:ArgumentError)
{
    trace("Error:"+error.message);
}

// Inform everything went just fine.
dispatchEvent(new AddModuleEvent(this as DisplayObject) );
}

                public function acceptInputPipe( name:String, pipe:IPipeFitting ):void
{
// try to execute in the external SWF
_conn.send("fromParent","acceptInputPipe",name,pipe);
}

public function acceptOutputPipe( name:String, pipe:IPipeFitting ):void
{
// try to execute in the external SWF
_conn.send("fromParent","acceptOutputPipe",name,pipe);
}

public function garbageCollection():void
{
//dispatchEvent( new Event( COLLECT_GARBAGE ) );
}

private function onStatus(event:StatusEvent):void {
switch (event.level) {
case "status":
trace(event.toString());
break;

case "error":
trace(event);
break;
}
}
}

And on the external SWF something like this:
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
implements="com.common.IPipeAwareModule" initialize="initializeHandler(event)">

<mx:Script>
<![CDATA[
import org.osflash.thunderbolt.Logger;
import org.puremvc.as3.multicore.utilities.pipes.plumbing.JunctionMediator;
import mx.events.FlexEvent;
import com.mapmodule.ApplicationFacade;
import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeFitting;

public static const NAME:String = 'MapModule';

private var facade:ApplicationFacade = ApplicationFacade.getInstance(NAME);

private var _facade: ApplicationFacade;

private var _conn:LocalConnection;

private function initializeHandler(event: FlexEvent):void
{

_facade = ApplicationFacade.getInstance( NAME );
_facade.startup( this );

_conn = new LocalConnection();
_conn.allowDomain();
_conn.client = this;

try
{
Logger.debug("Tentando se conectar a fromParent...");
// listen to events from the parent
    _conn.connect("fromParent");
}
catch (error:ArgumentError)
{
    trace("Error:"+error.message);
}
}

public function acceptInputPipe( name:String, pipe:IPipeFitting ):void
{
Logger.debug(NAME+".acceptInputPipe");
_facade.sendNotification( JunctionMediator.ACCEPT_INPUT_PIPE, pipe, name );
}

public function acceptOutputPipe( name:String, pipe:IPipeFitting ):void
{
Logger.debug(NAME+".acceptOutputPipe");
_facade.sendNotification( JunctionMediator.ACCEPT_OUTPUT_PIPE, pipe, name );
}

public function dispose():void
{
_facade.sendNotification(ApplicationFacade.DISPOSE);
}
]]>
</mx:Script>
<mx:ViewStack id="vwsViewstack" creationPolicy="all" height="100%" width="100%">
<mx:Canvas height="100%" width="100%">
<mx:Text text="Carregando mapa ..." fontSize="16" color="#CFF1F8" fontWeight="bold" bottom="261" top="250" left="30" right="50"/>
</mx:Canvas>

<mx:Canvas height="100%" width="100%">
<mx:UIComponent id="mapLayer" width="100%" height="100%" />
</mx:Canvas>
</mx:ViewStack>
</mx:Application>


So, the main idea is to register the in/out pipes. But I´m getting some strange error on the onStatus(event:StatusEvent) that has no info, no code no nothing. The trace is:
[StatusEvent type="status" bubbles=false cancelable=false eventPhase=2 code=null level="error"].

And the Logger.debug(NAME+".acceptInputPipe"); in acceptInputPipe/acceptOutputPipe never executes.

And when I try to send a message from Shell to external Module (junction.sendMessage( PipeAwareModuleConstants.SHELL_TO_MODULE_PIPE, msg); )I get this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
   at org.puremvc.as3.multicore.utilities.pipes.plumbing::Pipe/write()[C:\eclipseWorkspace\Utility_AS3_MultiCore_Pipes\src\org\puremvc\as3\multicore\utilities\pipes\plumbing\Pipe.as:72]


That´s the general idea and the general error. Did you guys get it? If not, I can post more code here. I´m kinda messed here right now trying to solve this.

So please, tips appreciated!

6  PureMVC Manifold / MultiCore Version / Re: Flash CSS/AS3 example of loading external swf as module under MultiCore - Help on: September 04, 2008, 01:18:31
AHA! I finally made it! I´ll just put the code of my solution here so anyone can have a look.

Foo class:
:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.System;

import mx.core.UIComponent;
import mx.managers.CursorManager;
import mx.rpc.events.FaultEvent;

// Foo is a UIComponent. It´s responsible for loading the modules and stuff.
//I did this because I was getting an Error saying that Loaded isn´t a IUIComponent.
public class Foo extends UIComponent
{
private var _request:URLRequest;
private var _loader:Loader;
private var _loaded:Boolean;
private var _url:String;

public function Foo(url:String)
{
super();
_url = url;
_request = new URLRequest(url);
_loader = new Loader();

_loaded = false;
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
_loader.contentLoaderInfo.addEventListener(FaultEvent.FAULT, onFault);
}

// Try to load the Module from the URL passed on the constructor
public function loadIt():void{
CursorManager.setBusyCursor();
try{
_loader.load(_request);
}
catch (error:Error)
            {
            CursorManager.removeBusyCursor();
                trace("Unable to load URL: " + error);
            }
}

// Try to clear everything.
public function unlonadIt():void{
removeChild(_loader);

_loader.unload();

_loader = null;

_loaded = false;

// Try to GC again.
flash.system.System.gc();

dispatchEvent(new Event("REMOVED",true));
}

//
private function onLoaded(evt:Event):void{
//trace(_url+" load success");
CursorManager.removeBusyCursor();

_loaded = true;

// Loader can be added to the UIComponent class. ???
addChild(_loader);

// Inform everything went just fine.
dispatchEvent(new Event("OK",true));
}

// Inform something went wrong
private function onFault(evt:FaultEvent):void{
//trace(_url+" load FAIL");
_loaded = false;
dispatchEvent(new Event("ERROR",true));
}

public function get loaded():Boolean{
return _loaded;
}
}
}

SimpleShell.mxml
:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">

<mx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;

// Flag to control module loading
private var _hasModule:Boolean = false;

// My module manager class
private var _foo : Foo;

// The previous value of memory avaiable from System.totalMemory
private var _pmem:Number = 0;

// Local path to your SWF. Change all '\' to '/'.
private static const MAP_MODULE_URL:String =
"C:/mymodules/ModuleA.swf";

private static const CAPTIONATOR_MODULE_URL:String =
"C:/mymodules/ModuleB.swf";

// Add listeners for events dispatched by Foo class.   
private function init():void{
this.addEventListener("OK", onComplete);
this.addEventListener("ERROR", onFault);
this.addEventListener("REMOVED", onComplete);

// Initializate the memory indicator before loading modules
_pmem = System.totalMemory;

// Divided by 1024 to simplify viewing
lblMemory.text = "Total Memory: "+String(_pmem/1024);
}

private function onComplete(evt:Event):void{
// the current total memory value after module loading
var mem:Number = System.totalMemory;
lblDelta.text = "Diff: "+String((_pmem - mem)/1024);
lblMemory.text = "Total Memory: "+String(mem/1024);

// now previous value is the current one
_pmem = mem;

// Parse the event sent by Foo.
if(evt.type == "OK")
_hasModule = true;
else if(evt.type == "REMOVED")
_hasModule = false;
}

private function onFault(evt:Event):void{
_hasModule = false;
}

// Try to invocate the Garbage Collector. Not sure if it will in fact collect.
private function garbage():void{
var mem:Number = System.totalMemory;
flash.system.System.gc();
lblMemory.text = "Total Memory: "+String(mem/1024);
lblDelta.text = "Diff: "+String((_pmem - mem)/1024);
_pmem = mem;
}

// Invoked everytime the load button is clicked.
private function loadModule():void{

// Change buttons behavior
if(_hasModule == false){

btnLoad.label = "Unload";

// Load module selected in the Combo Box
if(cbxModules.selectedIndex == 0) {
_foo = new Foo(MAP_MODULE_URL);
_foo.loadIt();
}
else {
_foo = new Foo(CAPTIONATOR_MODULE_URL);
_foo.loadIt();
}

// Add the Foo class to the UIComponent. Foo´s also an UIComponent.
module.addChild(_foo);
}
else{
// Clear things up...
btnLoad.label = "Load";
_foo.unlonadIt();
module.removeChild(_foo);
_foo = null;

// ...and try to free memory
garbage();
}
}
]]>
</mx:Script>

<mx:VBox width="100%">
<mx:ApplicationControlBar x="10" y="10" width="100%">
<mx:ComboBox id="cbxModules" dataProvider="{['Module A', 'Module B']}"/>
<mx:Button label="Load" id="btnLoad" click="loadModule()"/>
<mx:Button label="GarbageCollection" id="btnGarbage" click="garbage()"/>
<mx:Label id="lblMemory" text="" width="100%"/>
<mx:Label id="lblDelta" text="" width="100%"/>
</mx:ApplicationControlBar>
<mx:UIComponent id="module" width="100%" height="100%"/>
</mx:VBox>
</mx:Application>


I used the Loader class to load my external SWFs and it worked. Now it´s pumbling time!
 ;D
7  PureMVC Manifold / MultiCore Version / Re: Flash CSS/AS3 example of loading external swf as module under MultiCore - He on: September 04, 2008, 06:03:02
Hello guys,

I´m stuck with loading external SWF files. I´m building a modular app in Flex using PureMVC MultiCore-Pipes(PMVCMCP). The main idea is to have several stand alone applications that are all PMVCMCP that are loaded in a big Shell app that coordinate them all. I have all my modules built, each one in a Flex project with different output folders.

The problem is in the Shell. I´ve tried loading the external SWFs in two different ways: using the techinique used by Jens (http://www.websector.de/blog/2008/06/21/a-basic-puremvc-multicore-as3-example-using-pipes-utility-and-modules/) but it doesn´t work because it needs a reference to the Module Class and my app are completly unknow/unaware of each other.
So I tried using Joshua´s (http://www.joshuaostrom.com/2008/06/17/pipe-demo-mortgage-app/) techinique but he uses his own PureMVCModules lib that is way too "powerfull" for my current needs. I found the source of the lib here http://www.joshuaostrom.com/2008/05/24/as3-puremvc-dynamic-modules/.
Then I tried some Adobe techiniques (http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html) but got NO donut.  :-\

When I use the techiniques described above, the SWF is loaded by the ModuleManager but it never dispatch the ModeEvent.READY event. I´ve tried some hacking but it didn´t work since my hacking skills are just l4m3.

I also tried this tech (http://livedocs.adobe.com/flex/3/html/help.html?content=Working_with_MovieClips_7.html) from Adobe but I get Error #1034: Type Coercion failed: cannot convert flash.display::Loader@756bec1 to mx.core.IUIComponent.

So I´m stuck. I need help real bad! I just don´t know what to try now! And I really, really don´t want to merge all my apps/modules in one single Flex Project. They all have to be stand alone apps.

Thanks
8  PureMVC Manifold / MultiCore Version / Re: Easy Pipes Demo? on: September 02, 2008, 12:36:28
Hi there!

I don´t want to be a prick or anything but I guess all the demos are "Easy". If the demos where a little simplier, it would be difficult to use PMVC and Pipes because there wouldn´t be much to modulate.

Just read all the code, try to go debuggin it and tracing parts of the code and you´ll soon get it out figured. And most important off all, don´t give up!

Cheers!

ps: Have you read Josh´s excellent post ? Here´s the link: http://www.joshuaostrom.com/2008/06/15/understanding-puremvc-pipes/
9  PureMVC Manifold / Bug Report / Re: [ WILL FIX ] Unexpected behaviour when registering the same mediator twice on: May 20, 2008, 03:09:24
Thanks guys.

I´ll try to make a good "Singleton Mediator" manager class, or add-on, or something or whatever.  ::)

Now I´m facing a hole new challenge with mediators and States!

See ya!
10  PureMVC Manifold / Bug Report / Re: [ WILL FIX ] Unexpected behaviour when registering the same mediator twice on: May 16, 2008, 11:33:29
Nice replies!

Here is my final, hopefully, fail safe code for managing mediators. Just to remember that the main idea is to have the fewest possible mediators registered at a time so they are registered and removed from the facade often. I want to reduce my Observers list so it can be scanned faster.
:

// Remove unused/unnecessary mediators first
facade.removeMediator( MyOtherMediator.NAME );

// If there´s no instance of MyMediator.NAME registered in the facade, get a instance and register it!
if( facade.hasMediator( MyMediator.NAME ) == false )
    facade.registerMediator( MyMediator.getInstance( viewComponent ) );


Now, not only I am sure that there´s only one instance of mediators, due to the Singleton Pattern, I´m sure when to register them or not!

Please, advise me if my thinking is wrong or bad or unnecessary .

^_^
11  PureMVC Manifold / Bug Report / Re: [ WILL FIX ] Unexpected behaviour when registering the same mediator twice on: May 15, 2008, 11:48:44
Hello Cliff,

This syntax: facade.registerMediator(new MyMediator(viewComponent) )

It´s when I instantiate a new Mediator in the arguments of the registerMediator method. It make sense to me since I´m creating a hole new instance of a class. The only thing I didn´t know is that the method really register the mediator even if there exists another instance, registered, of that mediator´s class.

I´m trying a new test code here and later I´ll post it the result behavior.
12  PureMVC Manifold / Bug Report / Re: [ WILL FIX ] Unexpected behaviour when registering the same mediator twice on: May 14, 2008, 08:12:17
Oops, forgot to mention that I´m using the latest version of the Framework: 2.0.3.

I saw a lot of other posts concerning this strange behavior and I´m reading all of them to see if there was a already a solution posted.


I hope my solution´s handy for someone.

=)
13  PureMVC Manifold / Bug Report / Re: [ WILL FIX ] Unexpected behaviour when registering the same mediator twice on: May 14, 2008, 08:03:05
Hello guys,

this my first post ever on the PureMVC community. I hope that I can contribute positively with the community.

Now, to the strange stuff:
This behavior also happens with notifications. Each instance of the IMediator added in the facade, responds to the notifications that it has interest. I noticed it by some strange behaviors that were occurring:
 1- The method facade.removeMediator(MyMediator.NAME) wasn´t removing properly the specified mediator because when I call it, the mediator is still there and responds to notifications. Or maybe is something wrong with the observers. I don´t know yet.

 2 - The method facade.registerMediator(new MyMediator.(viewComponent) ) works fine. But I suddenly noticed that there where lots of extra instances of a Mediator that I didn´t need because of the new syntax. When I first started to user the framework, I thought that the registerMediator() method only registered one instance of a mediator by it´s name no matter if I used new or not. The solution I came up was using the Singleton pattern for my Mediators. Now I use this syntax for my apps: facade.registerMediator(MyMediator.getInstance(viewComponent) ) and now I´m sure that it will be only one instance of my mediators registered in my Facade.

Well, thats it. I hope this hint helps other folks. And please, if there´s another way for solving this, or if you noticed that I´m using the wrong commands/syntax, tell me!

See ya
Pages: [1]