Friday, December 15, 2006

Flex Builder 2.01 and mx.modules

Ok, so pong exploration project delayed slightly.
I'm working with flex builder 2.01 and they have put quite a bit of work into mx.modules.
There weren't any examples anywhere, so I was left to explore the API documentation.

Most of my day was spent wrestling in IIS PHP MYSQL hell getting a wiki setup, but after I got that done, I devoted fulltime to replacing my old classloader flex hacks with mx.modules.

I just got them working. They were very foreign at first and I was cursing at not having better examples to work with, but now that I know how they're used, I can drive home victorious.

Some code for others who may be struggling with these puppies:

First I created a ModuleEventHandler to hold an instance of my global framework that I want to pass into the module with an init method later. (You're supposed to be able to do this by passing it to the create method, but I couldn't get that working yet).

public class ModuleEventHandler {
public var gui:SomeFrameworkInterface;
public function ModuleEventHandler(gui:SomeFrameworkInterface) { this.gui=gui; }
public function onModuleReady(e:ModuleEvent):void {
var i:IModuleInfo = ModuleManager.getModule(e.target.url);
Object(i.factory.create()).init(gui);
}
}

Then I created a generic loadModule function that will do the dirty work. All my modules will be suffixed with Wrapper.swf.

public function loadModule(name:String):void {
var m:ModuleLoader = new ModuleLoader();
m.url = name+"Wrapper.swf";
m.loadModule();
m.addEventListener(mx.events.ModuleEvent.READY ,(new ModuleEventHandler(gui)).onModuleReady);
}

the SomeWrapper class looks like this

public class SomeWrapper extends mx.modules.ModuleBase implements IFlexModuleFactory
{
public var gui:SomeFrameworkInterface;
public function init(gui:SomeFrameworkInterface) { this.gui=gui;
//other code here to modify the gui how you want to using the module stuff
// most likely dispatch some event on it that it reacts to.
}
public function create(... parameters):Object { return new SomeWrapper(); }
public function info():Object { return {}; }
}

In my interface I have an accordian that the module adds itself to, and its working so I'm stoked =)

Thursday, December 14, 2006

VO Objects and a Command Pattern in Flex

I'm doing a bunch of experimenting with a sort of AJAX style Flex Client-Server implementation.
Basically, I'm setting up a one-way socket connection from the server to the client, sending an int of the size of an AMF3 object, followed by that object. (in c#.net using flourine), and if I don't need to send another object, the connection is keep-alive, so I just don't send it. A use case of this is any real-time network based application such as chat, or a networked game such as pong. Its less expensive to keep a connection rather than make a new one over and over. This is an excellent way of accomplishing Server-Push for applications where the client isn't sending data to the server that often, but is receiving it very often. (so no polling protocol is required)

The flex client reads an int SIZE, then waits for that many bytes to be available, then reads an AMF3 object, casts it to a type MessageVO, and then calls interpret on it.

[code]
package vo {
[RemoteClass(alias="vo.MessageVO")]
public class MessageVO { public var type:Number; public function interpret():void { } }}
[/code]

We can then have many different types of messages, each who's client implementation has a fleshed out interpret method, but who's server implementation has only the members defined.

For example:

import model.ModelLocator;
package .vo {
[RemoteClass(alias="vo.ChatMessageVO")]
public class ChatMessageVO extends MessageVO {
public var message:String;
public var fromUserID:Number;
public function interpret() { ModelLocator.getInstance().chatMessages.push(this); }
}
}

When flex reads the amf object, and calls interpret on it, flex knows the object type is a ChatMessage underneath the covers, so the implemented interpret method in the ChatMessage class is called, and the singleton ModelLocator gets a new chat message in the chatMessages array. (Which other classes are binding to).

I'm also debating making a new event type of MessageReceivedEvent which contains the message that was received, so anyone can listen for events that they broadcast.

I'm working on a very modular architecture at the moment, modules need to be able to implement a pattern and expect other modules to adhere to this pattern for interoperability, so I'm testing out a bunch of different patterns to see what will work best across the categories of development time, runtime execution, 3rd party implementation time.

Tomorrow I'll have a networked version of that pong app using this pattern available, additionally you will be able to chat with your opponent.

Tuesday, December 12, 2006

quickpong

I've created a fun test of flex framerate, object orientation, and integration of custom actionscript.
Took about 20 mins =)
http://groupnetwork.com/tools/pong/pong.html
(right click view source is available for it).