PDA

View Full Version : Delegate Class Hack



creatify
July 2nd, 2006, 05:18 PM
I hesitate to post this as I know its not a preferred way of using this especially if you're building a flash app with strict Design Patterns. With that said, I really like using the Delegate Class, but as I've found a number of posts about not being able to pass an argument when using Delegate.create(obj,func);. I too wish there was some type of support for this (and I realize there are other ways of achieving this with Event handlers etc). Anywho, I have added to the Delegate class to support this. Getting the arg out is hacky, but for some very small classes I've build, it works well.

This is what I've added to the Delegate Class file:

/**
The Delegate class creates a function wrapper to let you run a function in the context
of the original object, rather than in the context of the second object, when you pass a
function from one object to another.
*/

class mx.utils.Delegate extends Object
{
/**
Creates a functions wrapper for the original function so that it runs
in the provided context.
@parameter obj Context in which to run the function.
@paramater func Function to run.

//ADDED
@paramater args array to pass to Function.
*/

static function create(obj:Object, func:Function, args:Array):Function
{

var f = function()
{
var target = arguments.callee.target;
var func = arguments.callee.func;
return func.apply(target, arguments);
};

f.target = obj;
f.func = func;

//ADDED function.args
f.args = args;

return f;
}

function Delegate(f:Function)
{
func = f;
}

private var func:Function;

function createDelegate(obj:Object):Function
{
return create(obj, func);
}
}


And to retrieve args past, see this simple class

import mx.utils.Delegate;

class Foo {
private var __btn:MovieClip;
private var __name:String;

public function Foo(_b:MovieClip) {
__btn = _b;
init();
}

private function init() {
var myArgs:Array = ["one","two"];

//here I'm passing an array of items
__btn.onRelease = Delegate.create(this,clicker,myArgs);

}

private function clicker():Void {
//this is the hacky way to retrieve the args from arguments.caller
trace(arguments.caller.args);
}
}


Hope this may be of some use to someone.

TheCanadian
July 2nd, 2006, 08:05 PM
You never pass arguments to an event like onRelease without Delegate so I don't see why you would need to with it.

creatify
July 2nd, 2006, 09:49 PM
Hi TheCanadian, Attached is an fla where I may end up using this. Its an over-simplified example, but I use an id for each of the attached buttons to make things happen. Maybe there's a better way, without having to create a class for the buttons, but still keeping it all within one class? The effort here is to have the onRelease event utilize a class method that may be used by other movieclips or even other classes etc., but being able to simply pass a button ID to the method without losing scope in the class... hope this makes sense, would love some input.

TheCanadian
July 2nd, 2006, 10:13 PM
Well I know what it does and how it works, but I've already had an argument like this with someone else on another forum so I'll just drop it :)

creatify
July 2nd, 2006, 10:20 PM
I would be interested in the best / most proper way to do this though, or rather an explanation of why not to do this - a link to that forum would help me out, thank you in advance.

micheeel
July 3rd, 2006, 07:14 AM
I would be interested in the best / most proper way to do this though, or rather an explanation of why not to do this - a link to that forum would help me out, thank you in advance.

Would like to know too, as I have the same problem as you do sometimes.
What I'm currently doing is creating a variable that receives the current class, +/- like this:

----

public function addColors(name:String, colors:Array):Void
{
var i:Number;
var j:MovieClip;

//this.colors_name = name;
this.colors = colors;

for (i=0; i <= this.colors.length; i++)
{
this.root[name+i].classe = this;
this.root[name+i].id = i;
this.root[name+i].onRelease = function()
{
this.classe.setActiveColor(this.id);
this.classe.paintMouse();
}
}
...........

mprzybylski
July 3rd, 2006, 10:26 AM
Joey Lott created a class called Proxy that is the same as delegate but allows the passing of arguments.

http://www.person13.com/articles/proxy/Proxy.htm