Patching NetStreamClient

(February 14th, 2010)

I couple of days ago I noticed that my conceptual NetStreamClient was failing when connecting it towards a NetStream, the debugger threw errors regarding missing a Proxy implementation of getProperty.

The problem was when building the class I took for granted that NetStream referenced against the client object and invoked the callback function from the object when a callback took place. But the fact is that when you assign a client object to netstream it saves a reference to the callback function, not the client object itself. So it was clear why my class didnt work.

So I patched it up with the proxy implementation getProperty (it looks a bit hackish but it does the trick).

flash_proxy override function getProperty(name:*) : *
{
        var qName:QName = name as QName;
       
        return function ( args ) : void
        {
                flash_proxy::callProperty( qName, args[0] );
        }
}

I also noticed that in my usage example I used an object instead of the NetStreamClientEvent. So this is how you “really” use it.

// create a instance
client = new NetStreamClient();
// assign the client
netStream.client = client;
// then just add listeners to the client
client.addEventListener( NetStreamClientEvent.CUE_POINT, client_cuePointHandler );

// an example of the handler function
function client_cuePointHandler ( event:NetStreamClientEvent ) : void
{
        // the info object holds the original data
        var info:Object;
                       
        info = event.arguments[0];
                       
        trace( [info.name, info.time, info.cuetype] );
}

Updated classes here: Download it here here, or view the NetStreamClient class here.

Note to self: Connecting MySQL with Django using Mamp in OSX

(February 14th, 2010)

Having trouble connecting your MAMP mysql database wth django?

Add the path DATABASE_HOST and connect it towards

{path to your MAMP directory}/tmp/mysql/mysql.sock

So my connection is for instance

DATABASE_HOST = ‘/Applications/MAMP/tmp/mysql/mysql.sock’

And the full mysql settings for for django

DATABASE_ENGINE = ‘mysql’ # ‘postgresql_psycopg2′, ‘postgresql’, ‘mysql’, ’sqlite3′ or ‘oracle’.
DATABASE_NAME = ‘mydb’ # Or path to database file if using sqlite3.
DATABASE_USER = ‘root’ # Not used with sqlite3.
DATABASE_PASSWORD = ‘root’ # Not used with sqlite3.
DATABASE_HOST = ‘localhost’ # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ‘8888′ # Set to empty string for default. Not used with sqlite3.
DATABASE_HOST = ‘/Applications/MAMP/tmp/mysql/mysql.sock’

Its straightforward, but good to know, since adding the mysql.sock file in a folder named tmp seems a bit odd.

A nicer way of using NetStream.client

(January 11th, 2010)

* UPDATE: This class has been patched

After working with the NetStream class for quite some time it has always striken me how badly the “client” approach is.

Default behaviour

netStream.client = {onCuePoint:myCuePointCallback};

function myCuePointCallback ( point:Object ) : void
{
}

Basicly to retrive a cue point we have to assign the client property with a object populated with a needed set of callback functions, that in the end will be triggered by the NetConnection class. You rarely see this callback mechanism in as3 and it can easly get a bit confusing, mainly beacuse you need to remember the callback function names.

So I made a specific client class for NetStream which extends the Proxy util and converts the callbacks into actual events with EventDispatcher. It works like this.

Usage

// create a instance
client = new NetStreamClient();

// assign the client
netStream.client = client;

// then just add listeners to the client
client.addEventListener( NetStreamClientEvent.CUE_POINT, client_cuePointHandler );
client.addEventListener( NetStreamClientEvent.META_DATA, client_metaDataHandler );

// an example of the handler function
function client_cuePointHandler ( info:Object ) : void
{
        trace( [info.name, info.time, info.cuetype] );
}

The NetStreamClient covers the most used callbacks (such as metadata, play status), and the callbacks it cannot identify gets labeled as a Unknown call.

Try it out and just shout if you have any comments!
Download it here here, or view the NetStreamClient class here.

/ Martin

Dealing with the NetStatus info codes

(November 16th, 2009)

I never liked dealing with the NET_STATUS info codes that NetStream generates, beacuse I always forget the different codes. And there is no built in class which holds the string constant as representations for the different codes. So I basicly did a very simple wrapping of the status codes from the Adobe Reference into a simple to use class.

Usage

protected function netStream_netStatus ( event:NetStatusEvent ) : void
{
        switch( event.info.code )
        {
                case NetStatusConstants.NETSTREAM_PLAY_START:
                        trace("Start!");
                        break;
        }
}

So if you are like me, with a memory like a pacific sea turtle, this might come in handy. Download it here here, or view the class here.

Bug in the sabreamf drupal module

(November 3rd, 2009)

I stumbled upon this bug while trying out the excellent sabreamf drupal module (which enables flash remoting support for drupal). The problem was that all method calls witch required arguments just failed. So after some peeking under the hood I noticed that the method name was added as a parameter, together with the regular parameters in the service call, something that in the end caused the service fail.

To correct this error, simply remove the $method variable from the call arguments.

Locate the file sabreamf.module in your sabreamf drupal module folder (not to be confused with the SabreAMF folder)

On line 66 replace this line of code…

return sabreamf_method_call($method, array($method, $arguments));

…With this

return sabreamf_method_call($method, $arguments);

All set!

Note to self: Wordpress and uploading .flv files

(October 21st, 2009)

It seems like the latest version of wordpress (2.8.5) does not allow the upload of .flv files. To fix that issue, do the following:

1. Locate the file wp-includes/functions.php
2. Locate the function “wp_check_filetype” (line 2228)

Then finally add the. flv mimetype into the $mimes array

‘flv’ => ‘video/flv’,

Done!

Note to self: settings.py and mysql.sock

(October 15th, 2009)

If the path for your mysql.sock does not correspond to the default tmp/mysql.sock you will recive the following error in osx.

File “/Library/Python/2.5/site-packages/MySQL_python-1.2.2-py2.5-macosx-10.5-i386.egg/MySQLdb/connections.py”, line 170, in __init__
_mysql_exceptions.OperationalError: (2002, “Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)”)

To correct this, find the real path for your mysql.sock (mine was var/mysql/mysql.sock) and then add the following param (under the mysql related params).

DATABASE_HOST = ‘/var/mysql/mysql.sock’

That should do the trick!

PureMVC hints and tips

(October 11th, 2009)

PureMVC has been my framework of choice for the last 18 months, the beginning of our relationship was a bit rocky but after a while we got to know each outher. Now, looking back at atleast the ten bigger projects I have done since, I’d say we know one another well, so well that I have learned a bunch of new hints and tips. Something I thought I might aswell share on this blog.

Im not only making this little article as a reflection of my past experiences, but also to mark a new start for me with my new framework of choice RobotLegs, and this felt like a good way to end things :) In time I might go back to using PureMVC, perhaps not. PureMVC is anyway a great framework and alot of fun, so I hope some of these puremvc tips comes in handy!

1. Dare to use Proxies
The hardest part for me was to use Proxies. In the beginning I often ended up using a mediator when I could have used a proxy instead. Take a look at these examples.

SizeProxy = This Proxy listens for stage resize events and sends out resize notifications all through the application. In the past I embedded this functionality into a mediator called ApplicationMediator.

AddressProxy = This Proxy takes care of all state management related data, and do everything from setting, retriving, formatting and finally sending out notifications. In the past I had this functionality into a mediator aswell. (Shame on me!)

2. Keeping track of your proxies and mediators
Avoid always re-typing string representations when dealing with proxies and mediators. Add a static constant variable named NAME in your classes and refer to that variable any time you need to access the proxy/mediator. Like this.

The class

package se.marteinn.puremvc.single.view
{
        import org.puremvc.as3.interfaces.IMediator;
        import org.puremvc.as3.patterns.mediator.Mediator;

        public class ApplicationMediator extends Mediator implements IMediator
        {
                public static const NAME:String = "applicationMediator";
        }
}

Registrating the mediator

this.facade.registerMediator( new ApplicationMediator( ApplicationMediator.NAME, application ) );

Retriving the mediator

this.facade.retriveMediator( ApplicationMediator.NAME ) as ApplicationMediator

Aww, you get the idea!

3. Dont forget your OOP
Remember that Mediators are still classes that you can extend. So dont be afraid to make your own “abstract” classes.

Like this

package se.marteinn.puremvc.single.view.states
{
        import org.puremvc.as3.interfaces.IMediator;
        import org.puremvc.as3.patterns.mediator.Mediator;

        public class StateMediator extends Mediator implements IMediator
        {

                public function StateMediator(mediatorName:String=null, viewComponent:Object=null)
                {
                        super(mediatorName, viewComponent);
                }

                public function singJohnnyCash ()
                {
                        trace( “Ring of fire” );
                }
        }
}

And then extending it.

package se.marteinn.puremvc.single.view.states
{
        import se.marteinn.puremvc.single.view.states.StateMediator;
        import org.puremvc.as3.interfaces.IMediator;

        public class PageStateMediator extends StateMediator implements IMediator
        {
                public function PageStateMediator(mediatorName:String=null, viewComponent:Object=null)
                {
                        super(mediatorName, viewComponent);

                        singJohnnyCash();
                }
        }
}

4a. Be nice to the commands
Keep them as clear and as re-usable as possible. Try not to manipulate mediators directly in the command, use notifications instead. (Since its all ok for a mediator to retrive notifications).

4b. But use a command whenever you can
Commands makes your application easier to understand and to work with, so use commands whenever it feels right.

5. Organizing notifications
Placing all notifications into one class (placed in the application root) helps keeping track of things.

package se.marteinn.puremvc.single
{
        public class ApplicationNotifications
        {
                public static const STARTUP:String = "startup";
               
                // preload related
                public static const INIT_PRELOAD:String = "initPreload";
                public static const START_PRELOAD:String = "startPreload";
               
                public static const LOAD_CONFIG:String = "loadConfig";
                public static const CONFIG_LOADED:String = "configLoaded";
               
                // yada yada..
        }
}

And its easy to access

sendNotification( ApplicationNotifications. STARTUP );

6. Organizing parameters
To place values the application needs to actually work, such as api keys and values you dont want to store in a external config file, into its own class is a good idea.

package se.marteinn.puremvc.single
{
        public class ApplicationParameters
        {
                public static const GOOGLE_MAPS_API_KEY:String = "asd234234dssdf";
        }
}

And its easy to access

loadStuff( ApplicationParameters. GOOGLE_MAPS_API_KEY );

7. Use onRegister whenever you can on your proxies and mediators
My advice is not to place construction code into the constructor of proxies/methods, instead override the onRegister method and place your code there. It makes you code easier to read and give you less bugs in the future (when porting a app to multicore). Read more here http://lowpitch.com/blog/puremvc-multicore-vs-standard-singlecore/

8. The namespace
So, how should a PureMVC namespace be organized? Well, a namespace can be organized in many forms, this is my way in doing it.

se.marteinn.project
        controller     
                vo
                        (My controller specific VO:s here)

                (My commands here)

        model
                vo
                        (My model specific VO:s here)
                services
                        (My model specific services here)

                (My proxies here)
               
        view
                               
                components
                        (View related components here)
       
                (My mediators here)

        ApplicationFacade
        ApplicationNotifications
        ApplicationParams

It could also look like this:

se.marteinn.project
        controller     
                vo
                        (My controller specific VO:s here)
                commands
                        (My commands here)

        model
                vo
                        (My model specific VO:s here)
                services
                        (My model specific services here)
                proxies
                        (My proxies here)
               
        view
                               
                components
                        (View related components here)
                mediators
                        (My mediators here)

        ApplicationFacade
        ApplicationNotifications
        ApplicationParams

9. Adding a interface to the application main class
To make things as flexible as possible and to simplify when installing my puremvc base into a new application, I have a interface called IApplication, where the main Application implements IApplication. That way:

The application class can be named whatever, as long its implementing IApplication…

package
{
        import flash.display.Sprite;
        import flash.display.StageAlign;
        import flash.display.StageScaleMode;
        import flash.events.Event;
       

        import se.marteinn.puremvc.single.IApplication;

        [SWF(frameRate="31", backgroundColor="#000000")]
        public class TestApp extends Sprite implements IApplication
        {
               
                protected function draw () : void
                {
                        ApplicationFacade.getInstance().startup( this );
                }
               
        }
}

…the facade will be fine with it

package se.birth.puremvc.single
{
        import org.puremvc.as3.interfaces.IFacade;
        import org.puremvc.as3.patterns.facade.Facade;
       
        import se.marteinn.puremvc.single.controller.StartupCommand;

        public class ApplicationFacade extends Facade implements IFacade
        {
                protected static var instance:ApplicationFacade;
               
                public static function getInstance () : ApplicationFacade
                {
                        if( instance == null )
                                instance = new ApplicationFacade ();
                        return instance;
                }
               
                override protected function initializeController():void
                {
                        super.initializeController();
                       
                        this.registerCommand( ApplicationNotifications.STARTUP, StartupCommand );
                }
               
                public function startup ( application:IApplication ) : void
                {
                        this.sendNotification( ApplicationNotifications.STARTUP, application );
                }
               
        }
}

Read more
If you are looking for more advice and thoughts on how to build better PureMVC applications, look at these links:

10 tips for working with PureMVC by Jens Krause
http://www.flex-labs.de/blog/2008/10/10-tips-for-working-with-puremvc-by-jens-krause/

Building a Flash site using PureMVC
http://hubflanger.com/building-a-flash-site-using-puremvc/

My own PureMVC collection of links (both Singlecore and Multicore)
http://delicious.com/marteinn/puremvc

Last but not least, the PureMVC.org website with the all mighty guru of know it all Cliff Hall
http://www.puremvc.org/

Cheers!
/ M

Note to self: Robotlegs and injections

(October 11th, 2009)

When injecting a instance (or whatever) in robotLegs be sure to spell inject with a capital “I”.

Bad

[inject]
public var pageOnFrontProxy:PageOnFrontProxy;

Good

[Inject]
public var pageOnFrontProxy:PageOnFrontProxy;

Vacation over and eleven more months…

(August 1st, 2009)

..of work! Yes, after a month of well deserved vacation I am back on the force again, and I though the best way to get started is to list a few intresting links I stumbled upon the last month.

This is a very fancy as3 plugin, written by Simon Gregory, for textmate. Great work Simon!
http://blog.simongregory.com/09/as3-autocompletion-in-textmate/

The best explanation I have seen regarding the puremvc multicore version. Busdriver: move that cheese!
http://www.as3dp.com/2009/07/22/a-non-flex-actionscript-example-of-a-puremvc-multicore-application/

A must have collection of OSX commands. I stole this tip right of Jankees delicious (http://delicious.com/jankeesvw/)
http://ss64.com/osx/

A nice and breif list of various php frameworks. (Although, I am, for the time beeing sticking to my beloved Codeigniter)
http://www.noupe.com/php/discussing-php-frameworks.html

I’m for certain not Joomlas biggest fan, but this extension looks pretty fun for insane people like me who just loves to connect flash to various cms-systems.
http://extensions.joomla.org/extensions/miscellaneous/development/4820/details
http://figo.tandolin.co.za/adobe-air/how-to-use-jamfphp-for-joomla-remoting.htm

Another “actionscript efficency” must read slides, from http://lostinactionscript.com/
http://docs.google.com/present/view?id=d4jrvds_0hjb794hr

Tips in how the secure Wordpress (I think this link was digged?)
http://sixrevisions.com/wordpress/12-essential-security-tips-and-hacks-for-wordpress/

Another article that has been digged earlier. With breif comments of various php based cms systems.
http://www.webdesignbooth.com/20-promising-open-source-php-content-management-systemscms/

At the end of my vacation, I occupied myself with extending Magento (My goal is to have a fully working API against flash). Anyhow, these links got my started when extending the API with custom methods
http://100101.kurodust.net/2008/10/22/writing-a-magento-custom-api-call/
http://www.magentocommerce.com/boards/viewthread/43818/

Thats it for now, and all these links, including several others, can be found on my delicious. Cheers!