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 5
Print
Author Topic: Pipes - A PureMVC AS3 MultiCore Utility  (Read 93261 times)
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #30 on: August 31, 2008, 02:35:16 »

The module proxy is going through all the motions of loading the modules and I'm sure it works fine, but as I said before, I consider modules view components and have a view-tier class that loads and manages the modules with a mediator controlling access to it. Modules are swf files and not data, therefore, IMHO, they do not belong in the Model domain. This is just my take on it.

That said, if this makes sense to you feel free to use it. In the end it's about what works while still maintaining separation of concerns in your code. People often use proxies to load other assets provided to the view like images. Even though view tier assets are not really model data, the aggregation of anything that talks to the server living in a Proxy is a strong argument for breaking the conceptual separation of what is and isn't actual domain model data.

As for refactoring to reduce the use of commands, and of multiple places to listen for notifications, if a command isn't registered for a given notification, then it should be clear that it must be an interest of some Mediator. I agree that tracking down which one(s) can be a pain, and what I sometimes do to combat this is to add a short comment to the definition of the constant saying which mediator or command is interested.

-=Cliff>
Logged
Jigz
Newbie
*
Posts: 6


View Profile Email
« Reply #31 on: October 13, 2008, 10:44:11 »

hi! im finding trouble in creating the multicore mvc pipes structure in flash as3 only...
can you help me..
do you have a sample as3 sample program that we could see..with no flex..
we would really appreciate it..
Logged
Jason MacDonald
Sr. Member
****
Posts: 243


View Profile Email
« Reply #32 on: October 14, 2008, 07:36:27 »

hi! im finding trouble in creating the multicore mvc pipes structure in flash as3 only...
can you help me..
do you have a sample as3 sample program that we could see..with no flex..
we would really appreciate it..

I don't believe there is any demo for as3. I have managed to work it out on my own, but my project is a bit complex to just post as an example. I can try to help explain things though if you let me know where you are having trouble. I'll mention that there's actually very little difference between the Flex Multi-core pipes examples and a pure AS3 one since most of the action takes place within PMVC itself and thus has no direct ties to Flex.

The one thing you will need to build is a Module Loader, like Flex, using the Loader class. Here's mine in raw form;
:
/**
* ...
* @author Jason MacDonald (Jason.MacDonald@vfmii.com)
*/
public class ModuleLoader extends Sprite{

public static const READY:String = "READY";
private var _module:ILoadableModule;
public var _moduleVo:LoadableModuleVo;

public function ModuleLoader() {

}

public function load(moduleVo:LoadableModuleVo):void {
var loader:Loader = new Loader();
_moduleVo = moduleVo;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onProgress);
var loaderContext:LoaderContext = new LoaderContext(true);
loader.load(new URLRequest(moduleVo.url), loaderContext);
}

protected function removeListeners(loader:LoaderInfo):void {
loader.removeEventListener(Event.COMPLETE,onLoaded);
loader.removeEventListener(IOErrorEvent.IO_ERROR,onIOError);
loader.removeEventListener(ProgressEvent.PROGRESS,onProgress);
}

protected function onLoaded(event:Event):void {
var loaderInfo:LoaderInfo = event.target as LoaderInfo;
_module = loaderInfo.content as ILoadableModule;
removeListeners(loaderInfo);
dispatchEvent(new Event(READY));
}


protected function onIOError(event:IOErrorEvent):void {
//do something
}

protected function onProgress(event:Event):void {
//do something
}

public function get moduleVo():LoadableModuleVo {
return _moduleVo;
}

public function set moduleVo( value:LoadableModuleVo ):void {
_moduleVo = value;
}

public function get module():ILoadableModule {
return _module;
}

public function set module( value:ILoadableModule ):void {
_module = value;
}
}

LoadableModuleVo is just
:
/**
* ...
* @author Jason MacDonald (Jason.MacDonald@vfmii.com)
*/
public class LoadableModuleVo {

private var _name:String;
private var _url:String;
private var _version:String;

public function LoadableModuleVo() {

}


public function get name():String {
return _name;
}

public function set name( value:String ):void {
_name = value;
}

public function get url():String {
return _url;
}

public function set url( value:String ):void {
_url = value;
}

public function get version():String {
return _version;
}

public function set version( value:String ):void {
_version = value;
}
}

And ILoadableModule
:
/**
* The interface definition for a loadable Module.
*
* <P>The only requirement of our [dynamically] loadable
* module is that it implements this interface so we can get
         * a unique ID back from the module</P>
*/

public interface ILoadableModule
{
function getID():String;

}

I use this in conjunction with a ModuleLoaderProxy and LoadModuleCommand. Note that I do not store anything in the proxy concerning the module, it simply acts as the go-between with the loader and the responder (itself). It then dispatches a notification that the module has loaded, using the loaded swf as its body for the rest of my app to listen for and act upon. This might not be the best solution, but it seemed to me the best place for service calls like this was in a proxy, but to let the mediator store the swf once it's loaded so the proxy forgets all about it after it has sent the notification.


This is  the proxy I use
:

    public class ModuleLoaderProxy extends Proxy implements IProxy {

public static const LOAD_MODULE:String = 'mlLoadModule';
public static const UNLOAD_MODULE:String = 'mlUnloadModule';
public static const MODULE_LOADED:String = 'mlModuleLoaded';
public static const MODULE_FAILED:String = 'mlModuleFailed';
public static const MODULE_PROGRESS:String = 'mlModuleProgress';


        public static const NAME:String = "ModuleLoaderProxy";

        /** Constructor **/
        public function ModuleLoaderProxy(data:Object = null){
            super (NAME, data);
        }

public function loadModule(moduleVo:LoadableModuleVo):void {
var loader:ModuleLoader = new ModuleLoader();
loader.addEventListener(ModuleLoader.READY, onLoaded);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
loader.load(moduleVo);
}

protected function onLoaded(event:Event):void {
var moduleLoader:ModuleLoader = event.target as ModuleLoader;
var module:ILoadableModule = moduleLoader.module;
var moduleVo:LoadableModuleVo = moduleLoader.moduleVo;

sendNotification(MODULE_LOADED, module, moduleVo.name);
removeListeners(moduleLoader);
}

protected function onIOError(event:IOErrorEvent):void {
var moduleLoader:ModuleLoader = event.target as ModuleLoader;
var module:ILoadableModule = moduleLoader.module;
sendNotification(MODULE_FAILED, module, event.text);
removeListeners(moduleLoader);
}

protected function removeListeners(moduleLoader:ModuleLoader):void {
moduleLoader.removeEventListener(ModuleLoader.READY, onLoaded);
moduleLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
}

protected function onProgress(event:Event):void {
//sendNotification(MODULE_PROGRESS, module);
}
« Last Edit: October 14, 2008, 07:44:40 by jasonmac » Logged
Jigz
Newbie
*
Posts: 6


View Profile Email
« Reply #33 on: October 14, 2008, 07:11:04 »

i have read your message Mr. jasonmac...
and I'm very grateful to your reply...
it help a lot..
we understand your idea of loading swf modules...
but we have a problem understanding the last part where you use ModuleLoaderProxy?
you already have two loader classes...
sorry..we find it hard to grasp your idea in using this class..

and if its not much trouble to you..
you didn't use pipes in this code...
thought this is already helpful..
i wish you can help us using "PIPES" in mvc multicore...

many thanks to you bro!
Logged
Jason MacDonald
Sr. Member
****
Posts: 243


View Profile Email
« Reply #34 on: October 14, 2008, 07:29:20 »

The first class is a ModuleLoader "Component" (like the Flex SWFLoader), which the proxy uses to load the swf modules and then discard them after they return. The next time a module is loaded a new ModuleLoader class (component) is created. It just allows me to use the same ModuleLoader Class in other projects/areas since it has no ties to PMVC, unlike the proxy which basically proxies the calls through to the ModuleLoader and is able to listen and respond using PMVC specific notifications.

As I mentioned earlier, the process of adding and using pipes is identical to the Flex examples once you have the swf modules loaded. Make a ModuleMediator and have it lay the pipes (or send a message to your shell to lay them, up to you) whenever a notification is received of a new module being loaded. You can see this process, minus the dynamic modules, in the PipeWorks demo.

NOTE: I only quickly cut out portions of my classes to give as a guide, they are missing other parts that weren't quite relevant to what I was trying to explain so I wouldn't use them directly :)
« Last Edit: October 14, 2008, 07:31:28 by jasonmac » Logged
Jigz
Newbie
*
Posts: 6


View Profile Email
« Reply #35 on: October 15, 2008, 02:07:37 »

I'm confused...
anybody have a sample on mvc multicore pipes as3 only..

i don't know how to apply this in as3 (no flex)..

i hope somebody can show a sample code for multicore pipes..
or any alternative...
Logged
Jason MacDonald
Sr. Member
****
Posts: 243


View Profile Email
« Reply #36 on: October 15, 2008, 06:15:15 »

I try to cover the difference in this thread. http://forums.puremvc.org/index.php?topic=457.msg3379#msg3379

There's no difference in using Pipes between Flex and Flash, the only difference is how you load modules since there is no Module class in as3. I gave a very simple example in the thread above on how to implement a module loader in as3. You might also look at the new Fabrication utility from Darshan  http://forums.puremvc.org/index.php?topic=681.0;topicseen since it covers the loading of modules AND applying pipes I believe.

There's also a new StateMachine Utility which us AS3 only guys might want to keep an eye on. http://forums.puremvc.org/index.php?topic=739.0
« Last Edit: October 16, 2008, 10:42:19 by puremvc » Logged
Jigz
Newbie
*
Posts: 6


View Profile Email
« Reply #37 on: October 16, 2008, 02:36:38 »

Thanks a lot jasonmac...

your really a big help...
we already make your code work.. :)
Logged
aLearnerRather
Newbie
*
Posts: 6


View Profile Email
« Reply #38 on: October 17, 2008, 12:50:40 »

I'm working on a PureMVC/Pipes project (both of which I ported down to AS2) and I'm unsure of the best way to pass data in to a module.

I have my main app, which has a UserVO object representing the user. I have a module with a bunch of self-contained logic that performs configuration operations on the userVO, and then passes it back to the main app.

I have gotten as far as getting the module to load and connect up with the main app via pipes, and I can send a message from one to the other.

How should I pass in the UserVO to the module? It seems like I should send it in via a Message--after the module loads and is connected, send it from the main app's JunctionMediator. But I think I don't get the Message yet. It seems like it is supposed to be a wrapper for a Notification--does it have to be? Is there any problem in just passing the UserVO as the body of a Message, and have the module's JunctionMediator create the notification and send it along from there?

Any help you can offer will be greatly appreciated!
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #39 on: October 23, 2008, 07:12:00 »

No problem at all.

The message name if constructed properly provides you with a unique string that you can also reuse as a notification name within your module. Your JunctionMediator can simply package the message inside the body of a notification with the same name and send it. Commands and Mediators can then do whatever they need to with the message.

This process is message tunnelling. Its useful if the message itself has a lot of properties that will be used at the recipient, such as a Command. No need to pluck all the values off the message at the receiving JunctionMediator before passing it on into the app where those values are used. This way, the Message subclass also acts as a VO. Put typed getters and setters on it that access properties you add to the message header.

The other possibility is put a VO into a Message body, send it, and at the receiving JunctionMediator, pluck out the VO, and send it in the body of a note with the same name.

-=Cliff> 
Logged
romantique
Newbie
*
Posts: 1


View Profile Email
« Reply #40 on: December 11, 2008, 12:10:19 »

Thanks for such a wonderfull util lib. I'm realy anjoying it's simplicity and understandability.

Two question have appeared when playing with pipes:

1. Messages are most likely relative to data part of an application, rather than to it's view. And generally mediators in PureMVC are used to mediate between "flash" view components and "flash-less" core. So why junction mediator? Why not some sort of junction proxy? Though I can understand that mediator pattern is more general than it's commonly used in PureMVC.

2. There is an already done (thanks for helping lazy coders) method in JunctionMediator

public function handlePipeMessage( message:IPipeMessage ):void
{
}


For me it's a bit strange why it's public. The only thing I can guess why it's public - it can serve as a usual function, rather than just pipe listener. Thus we can make some custom message inside module core and pass it to that. But the method is specificaly made only for pipe listening. I'd make it protected for sure.

3. Sorry for my english :)
« Last Edit: December 11, 2008, 12:22:11 by romantique » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #41 on: December 11, 2008, 07:55:41 »

1. A) Mediators can be sent notifications which makes it easy to get messages sent. B) the Model has no concern with messages being bassed between cores in an app, which are generally view related anyway.

2. You're right, handlePipeMessage should be protected.

3. I bet I'm worse at your language than you are at english :)

-=Cliff>
Logged
jowie
Jr. Member
**
Posts: 19


View Profile Email
« Reply #42 on: March 24, 2009, 07:44:26 »

Hi all,

I'm trying to get something working in Flash with Pipes, but I'm really struggling here. I really want it to work but I'm probably just too dumb!  ???

Anyway I've tried to connect a module to a shell using acceptOutputPipe and acceptInputPipe. I am then calling sendMessage with the body of the message just being "Hello"... But then it just crashes on the Pipe.write command because output is supposedly null...

Cliff you don't fancy doing another one of your fab seminars in London any time soon do you?  ;)
Logged
jowie
Jr. Member
**
Posts: 19


View Profile Email
« Reply #43 on: March 24, 2009, 08:40:22 »

Okay sorry about that outburst... I realised I'd added too many pipes!  ;D I'd added the teeSplit and Merge to the module as well as the shell. I removed them and it started working.

One thing I'd like to know a bit more about is the format of a Message, namely what the header and priority properties actually do... Is there any documentation on these?

I am getting to grips, slowly but surely!

 ;)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #44 on: March 24, 2009, 03:04:17 »

Yes, there is API  documentation of the Message class and all the other classes in the Pipes utility on the Pipes Utility project menu. tou can see an example of the Message class header being used in the LogMessage subclass in the PipeWorks demo. Priority is used by the Queue class which can be used to hold the messages coming down a pipeline until you flush the queue. Before flushing, you can have the Queue set to sort messages by priority. This functionality isn't used in any demos, but is fully exercised in the Pipes Utility unit tests, which are the ultimate place to go to understand Pipes, since each functional par is tested in isolation with plenty of assertions about expected behavior. Much easier than trying to sort it out of a big demo.
 
-=Cliff>
Logged
Pages: 1 2 [3] 4 5
Print