Site Moved / Attachments Missing

Hello all,

Just wanted to let everyone know that the site has been migrated to a new server. I was having a lot of problems with hackers and malware on the old hosting provider that was no fault of my own (poor hosting security). We are now up and running.

I would like to mention that many of the example files that are attached to posts are missing. I am working on getting these back up ASAP. Thanks!

Using the AMFPHPConnection class

In this post I’ll be talking about a class I’ve made called AMFPHPConnection that extends Flash’s NetConnection object. This class eases and enhances the process of using AMFPHP for Flash remoting. But before we begin, just a few notes: I’m not the usual author, and you’ll need to know how to use AMFPHP the normal way, or you may not get some of the terminology. If you want to learn how to use it, I have a series on my YouTube channel for that purpose, go here to watch it: http://www.youtube.com/user/BlackBulletIV#grid/user/CAD2DAE46A04939D

First go and download the class from here: http://www.nova-fusion.com/cms/FileFolder/AMFPHPConnection.zip

This zip file contains the minimized class in it’s package folders: com/novafusion/net/AMFPHPConnection.as. It also contains readable version of the class, which has documentation, comments and more whitespace; it is: AMFPHPConnectionReadable.as. If you actually want to use this class instead, rename it to AMFPHPConnection.as and place it in the proper package folders. The zip file also contains package details similar to what I’m talking about now, and instructions similar to what I’m going to be talking about below. Now let’s get onto how to use it.

Setup

To get started, import the class:

import com.novafusion.net.AMFPHPConnection;

Next create a new instance, you can call the variable name whatever you like but I’ll go with connection:

var connection:AMFPHPConnection = new AMFPHPConnection("http://localhost/amfphp/gateway.php");

When you create a new instance, you are expected to pass in one parameter, the path to your AMFPHP gateway.php file. When you create the instance the class will automatically set up a connection and a responder for your function calls. If you would like to change the gateway location at any point do this:

connection.gateway = "http://www.some-other-server.com/amfphp/gateway.php";

This will set the gateway location in the class and reconnect to that server. Access the path to the current gateway this way:

connection.gateway

Quick Service Referencing

Quick service referencing helps a lot in speeding things up and reducing the amount of code you have to right. If you have a service you use a lot in your code, the connection class can store it for you and cut down how much you have to type to reference it. Examples of referencing strings are:

"FlashPHPTest"; // just a class name, but this could be a folder name
"UsingAMFPHP.TalkBack"; // folder and a class inside it
"UsingAMFPHP.TalkBack.put_together"; // folder, a class inside it, and a method inside the class
"FlashPHP" // part of a class name (could be folder or method name)

You can basically store any string in them, and reference it quickly when calling a service. You could use each of these reference strings in calls like this:

"$1.spitBack"; // just a class name, but this could be a folder name
"$2.put_together"; // folder and a class inside it
"$3"; // folder, a class inside it, and a method inside the class
"$4Test.spitBack" // part of a class name (could be folder or method name)

You use your references with a dollar sign and then it’s number (which is assigned to it in the order you add them to the class). As you can see this will greatly reduce what you have to write in your code.

You can add service references in two ways. The first is to add them in when constructing the class:

var connection:AMFPHPConnection = new AMFPHPConnection("http://localhost/amfphp/gateway.php", "FlashPHPTest", "UsingAMFPHP.TalkBack");

The second way is to add them in with a method provided:

connection.addServices("FlashPHPTest", "UsingAMFPHP.TalkBack");

You can add as many as you like at one time, and use the method as many times as you like. You can also remove service references like this:

connection.removeServices("FlashPHPTest", "UsingAMFPHP.TalkBack");

It’s not recommended that you remove service references, as it might generate confusion as to the order in which to reference them afterwards (just more for you to keep track of).

Calling Services

To call a service, use this method and pass in your service and parameters (not the responder! That’s taken care of for you):

connection.talk("SomeService.someMethod", "Some parameter", "Another parameter");

The function is called talk because of confliction with the NetConnection object’s call method. However you can still use that method, like this:

connection.call("SomeService.someMethod", null, "Some parameter", "Another parameter");

You can pass in the responder either as null (the object’s responder object will be used instead, which is what you want), use connection.responder (replace connection with your instance name), or pass in your own custom responder (note that result and fault listeners won’t work).

You can use quick service referencing in your calls like this:

connection.talk("$1.spitBack", "Hello world!");

Just use strings in the style shown in the quick service referencing section and all will be well.

Result and Fault Listeners/Handlers

We need to see up some listener/handler functions to respond to results and faults from AMFPHP:

function onResult(event:Event):void {
// do whatever
trace(connection.result);
}
function onFault(event:Event):void {
// do whatever
trace(connection.fault);
}

Notice that instead of receiving objects they actually receive plain event objects; that’s because they’re triggered by custom event listeners. You access the last result object with connection.result (replace connection with your instance name) and the last fault with connection.fault (replace connection with your instance name). Now how do we add the listeners for these functions? Here’s how:

connection.setListeners(onResult, onFault);

Just pass in the result function and the fault function and they’ll be triggered for their respective events. Now you don’t have to set either one, if you want to set the fault handler but leave the result handler as it is just leave the onResult function as null. Now be careful about these handlers, when you set them like this they become the default handlers for all calls. One way to get around this is to remove the listeners in the on result or on fault functions, using this:

connection.removeListeners();

You could do that, but there’s a better way to do it. Set the third parameter of setListeners() to true; this will make these listeners only last for one call, and on the next result or fault they will be removed. Here’s how:

connection.setListeners(onResult, onFault, true);

You could also add listeners the harder way like this:

connection.addEventListener(AMFPHPConnection.RESULT, onResult); // For results
connection.addEventListener(AMFPHPConnection.FAULT, onFault); // For faults

And of course to remove them you just use them same code, just change the function to removeEventListener().

Conclusion

Hope that helps! Here’s a sample application to give you some perspective on how this class lessens your code when using AMFPHP:

import com.novafusion.net.AMFPHPConnection;

var connection:AMFPHPConnection = new AMFPHPConnection("http://localhost/amfphp/gateway.php", "UsingAMFPHP.TalkBack", "FlashPHPTest");

function result(event:Event):void {
trace(connection.result);
}

function fault(event:Event):void {
trace(connection.fault);
}

connection.setListeners(result, fault);
connection.talk("$1.put_together", "tom", "bob");
connection.talk("$2.spitBack", "tom");

Freeing up memory for Garbage Collection

Something that I’ve been noticing lately with Flash / Actionscript 3 is the need to pay close attention to how you are cleaning up your objects after you are done with them.

I’ve been working with a great as3 debugging tool called “De MonsterDebugger”. Strange name but great tool. Check it out here: http://www.demonsterdebugger.com/

Basically you just download the debugger and import the class:

import nl.demonsters.debugger.MonsterDebugger;

then as the first line in your constructor function:

new MonsterDebugger(this);

Now you just open the air application that came with the download and it will track everything that happens in your class in the interface. You can run functions from it as well. It rocks!

Anyway, my point being that as I was running it on some of my programs I noticed a significant amount of memory leakage on some of the classes. Here are a few tips to help flash along with garbage collecting your old used up objects.

One thing I like to do is to create a destroy() function at the end of my classfiles. The job of this function is to reset all variables possible in the script. I’ll explain more in a moment.

The ‘delete’ keyword:

This is a somewhat misunderstood keyword in as3 because it only works on dynamically created variables. let me explain. take the following code for example:

var fluffy:Cat = new Cat("happy");
var sally:Cat = new Cat("angry");

// now somewhere along the way we want to remove fluffy
delete fluffy;
// oops! This generates an error. This is because the delete
// keyword only works on dynamic properties.
fluffy = null;
// Ok, so this sets fluffy to null but references to fluffy elsewhere
// in the code may still cause Garbage Collection to not be able to
// clean it from memory.

So I have discovered that the only way to be sure that your flash variables will be garbage collected and the memory will be released is to make the variables in your classes dynamic by using arrays or objects to store them.

You could do this like so:

var cat:Object = new Object();

cat["fluffy"] = new Cat("angry");
cat["sally"] = new Cat("happy");

addChild(cat.sally);
addChild(cat.fluffy);

// ok, now later we can clean up with a destroy function

function destroy():void{

        for(var i:Object in cat){
                removeChild(cat[i]);
                delete cat[i];
        }
}

The destroy function iterates through all objects inside of the cat object and removes them from the display list.
Next, it deletes the property itself freeing it up for garbage collection.

Keep in mind that the Cat class should also have a destroy function that cleans itself out as well!
So the function would be modified to look like this:

function destroy():void{

        for(var i:Object in cat){

                removeChild(cat[i]);
                cat[i].destroy();
                delete cat[i];
        }
}

You can use the De MonsterDebugger to magically watch your memory performance increase dramatically by using this technique. Happy Flash coding!

Load AS2 SWF into your AS3 Project

There is a Flash game that I have been working on that I’ve had to load into an as3 interface and I noticed that my previous class will not work to do this.

There were a few modifications that I had to make… Here is the Actionscript 3 class:

// SWFLoader Class by Rick Nuthman
// 2.16.10
//
// Usage:
/*
var game:SWFLoaderAs2 = new SWFLoaderAs2("yourSwf.swf",20,0)
game.dispatcher.addEventListener("ready", gameLoaded);
function gameLoaded(event:Event){
   
    addChild(game);
}
*/


package com.frigidfish{

    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.events.EventDispatcher;       

    public class SWFLoaderAs2 extends Sprite {     
       
        public var dispatcher:EventDispatcher   = new EventDispatcher();
        private var contentLoader:Loader;      
       
       
        public function SWFLoaderAs2(pathToTheContent,x,y) {
           
            this.x = x;
            this.y = y;
            loadSWF(pathToTheContent);
        }
           
        private function loadSWF(pathToTheContent):void {
           
            var request:URLRequest  = new URLRequest(pathToTheContent);
            contentLoader           = new Loader();
            contentLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,swfLoaded);
            contentLoader.load(request);
        }

        private function swfLoaded(e:Event):void {
           
            addChild(contentLoader);
            dispatcher.dispatchEvent(new Event("ready"));                  
        }
    }
}

usage:

var game:SWFLoaderAs2 = new SWFLoaderAs2("yourSwf.swf",20,0)
game.dispatcher.addEventListener("ready", gameLoaded);
function gameLoaded(event:Event){
   
    addChild(game);
}

This will certainly work to load an as2 swf into your as3 project,
but keep in mind that you will not be able to access methods and properties of your as2 swf.
I will be updating this class or adding another to make this possible. In the meantime,
Grant Skinner has created this to make the job a snap!