/* * Copyright the original author or authors. * * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.mozilla.org/MPL/MPL-1.1.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * {@code Delegate} was originally created by Mike Chambers * for Macromedia mx.events package. * *

As he said, this is a reusable class that acts as a proxy for events, * registering itself for specific events, and then proxying * the calls to the event handler and scope you specify. * *

This provides the following benefits and advantages : *

* *

For more explanations and a complete tutorial, * see there. * *

This version is also inspired from Peter Hall's EventDelegate. * You can instantiate and keep a reference of a Delegate instance. * For more informations, see there. * *

So, what are the new additions ? * *

- You can pass parameters and add some more further. * See examples below. * *

- One of the greatest feature is Command pattern implementation. * See classes documentation below to figure out benefits : *

* *

Here is a basic example with v2 Button component and {@code setArguments} use : * @example * * import com.bourre.commands.*; * import mx.controls.*; * * function test(event, a) : Void * { * event.target.label = String(++a); * d.setArguments(a); * } * * var d:Delegate = new Delegate(this, test); * var pb:Button = createClassObject(Button, '__pb', 10, {label:'0'}); * pb.addEventListener('click', d); * d.setArguments(0); * * * @author Francis Bourre * @version 1.0 */ import com.bourre.commands.Command; import com.bourre.events.IEvent; import com.bourre.log.PixlibStringifier; import com.bourre.transitions.IFrameListener; class com.bourre.commands.Delegate implements Command, IFrameListener { private var _f:Function; private var _o:Object; private var _a:Array; private var _fProxy:Function; private function handleEvent(e) : Object { return _f.apply(_o, [e].concat(_a)); } /** * Wrapper for MM compatibility. * Creates a method that delegates its arguments to a specified scope. * @param o Scope to be used by calling this method. * @param f Method to be executed. * @return Function that delegates its call to a different scope, method and arguments. */ public static function create(o:Object, f:Function) : Function { // MM original implementation updated var _f:Function = function() { var tt = arguments.callee.t; var ff = arguments.callee.f; var aa = arguments.concat(arguments.callee.a); return ff.apply(tt, aa); }; _f.t = o; _f.f = f; _f.a = arguments.splice(2); return _f; } /** * Constructs a new {@code Delegate} instance. * * @param o Scope to be used by calling this method. * @param f Method to be executed. */ public function Delegate(o:Object, f:Function) { _o = o; _f = f; _a = arguments.splice(2); _fProxy = Function(Delegate.create.apply(this, [_o].concat([_f], _a) )); } /** * Get scope reference. * @return Scope to be used for method calling. */ public function getScope() { return _o; } /** * Get proxy reference. * @return Function that delegates its call to a different scope, method and arguments. * * @example * import com.bourre.commands.*; * * var d:Delegate = new Delegate(this, test, "hello world"); * * function test( s:String ) : Void * { * trace( s ); * } * * mc.onPress = d.getFunction(); */ public function getFunction() : Function { return _fProxy; } /** * Execute proxy method in the provided context. * No return type is provided for interfaces compatibility. * @return Returns result if there's one. */ public function callFunction() { return _fProxy(); } /** * Execute proxy method in the provided context. * Command polymorphism. * @see com.bourre.commands.command */ public function execute( e: IEvent ) : Void { _fProxy(); } /** * Set or change arguments of proxy method. * See examples above. */ public function setArguments() : Void { if (arguments.length > 0) { _a = arguments; _fProxy.a = _a; } } /** * Add arguments to proxy method. * *

Here is a basical example with {@code Delegate.addArguments} : * * @example * * import com.bourre.commands.*; * * function test() : Void * { * trace(arguments); * } * function temporisation() * { * d.execute(); * d.addArguments( Math.round(Math.random()*9) ); * } * * var d:Delegate = new Delegate(this, test, 0); * setInterval(temporisation, 100); * */ public function addArguments() : Void { if (arguments.length > 0) { _a = _a.concat(arguments); _fProxy.a = _a; } } /** * Returns the string representation of this instance. * @return the string representation of this instance */ public function toString() : String { return PixlibStringifier.stringify( this ); } // public function onEnterFrame() : Void { _fProxy(); } }