Custom event dispatchment location - actionscript-3

I've been looking into custom event (listeners) for quite some time, but never succeeded in making one. There are so many different methods, extending the Event class, but also Extending the EventDispatcher class, very confusing!
I want to settle with this once and for all and learn the appropriate technique.
package{
import flash.events.Event;
public class CustomEvent extends Event{
public static const TEST:String = 'test'; //what exac is the purpose of the value in the string?
public var data:Object;
public function CustomEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, data:Object = null):void
{
this.data = data;
super();
}
}
}
As far as I know a custom class where you set the requirements for the event to be dispatched has to be made:
package
{
import flash.display.MovieClip;
public class TestClass extends MovieClip
{
public function TestClass():void {
if (ConditionForHoldToComplete == true) {
dispatchEvent(new Event(CustomEvent.TEST));
}
}
}
}
I'm not sure if this is correct, but it should be something along the lines of this.
Now What I want is something like a mouseevent, which can be applied to a target and does not require a specific class.
It would have to work something like this:
package com.op_pad._events{
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.EventDispatcher;
import flash.events.Event;
public class HoldEvent extends Event
{
public static const HOLD_COMPLETE:String = "hold completed";
var timer:Timer;
public function SpriteEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super( type, bubbles, cancelable );
timer = new Timer(1000, 1);
//somehow find the target where is event is placed upon -> target.addEventlistener
target.addEventListener(MouseEvent.MOUSE_DOWN, startTimer);
target.addEventListener(MouseEvent.MOUSE_UP, stopTimer);
}
public override function clone():Event
{
return new SpriteEvent(type, bubbles, cancelable);
}
public override function toString():String
{
return formatToString("MovieEvent", "type", "bubbles", "cancelable", "eventPhase");
}
//////////////////////////////////
///// c o n d i t i o n s /////
//////////////////////////////////
private function startTimer(e:MouseEvent):void
{
timer.start();
timer.addEventListener(TimerEvent.TIMER_COMPLETE, complete);
}
private function stopTimer(e:MouseEvent):void
{
timer.stop()
}
public function complete(e:TimerEvent):void {
dispatchEvent(new HoldEvent(HoldEvent.HOLD_COMPLETE));
}
}
}
This obviously won't work, but should give you an idea of what I want to achieve. This should be possible because mouseevent can be applied to about everything.The main problem is that I don't know where I should set the requirements for the event to be executed to be able to apply it to movieclips and sprites.

You are almost there actually, just for the last part, wouldn't this be more of an OOP related issue than stricly a confusion about the way of using custom events ?
Usually, Events in AS3 are value objects whose sole responsibility is to transport information from the event dispatcher to the listener(s). The dispatcher dispatches the event each time a defined momentum is reached, and the listener(s) may or may not react when this happens.
In the example above, I guess it is up to the listener to start a timer and so on when a mouse-down has been detected. In a more sophisticated context the Event could independently trigger more than one listeners actioning separate tasks which neither the Dispatcher nor the Event itself should have to bother about, that is probably why it's worth avoiding amending the dispatcher or the event itself with any soever logic.
For your very example, you could maybe create a handler checking if the mouse has been held down?
The following is just pseudocode, and there are obviously tons of other ways to get to the same result:
public class MouseDownHandler
{
// ...
public function( target:Sprite ) {
this.target = target;
start();
}
public function start():void{
// Listen for the target's mouseUp event
}
public function dispose():void{
// Stop listeners and eventually the timer
}
private function onMouseDown(e:MouseEvent):void{
// Start timer + listening for the stage's mouse up event (target.stage)
}
private function onMouseUp(e:Event):void{
// Cancel timer
}
private function onTimerComplete(e:TimerEvent):void {
dispatchEvent(new HoldEvent(HoldEvent.HOLD_COMPLETE));
}
}
Which could be reused for example this way:
var mc:MovieClip = new MovieClip(); ...
var mouseHandler:MouseDownHandler = new MouseDownHandler(mc);
mouseHandler.addEventListener(HoldEvent.HOLD_COMPLETE, onMcHoldComplete);
... or this way :
public class TestMovieClip extends MovieClip
{
private var mouseHandler:MouseDownHandler;
public function TestMovieClip() {
mouseHandler = new MouseDownHandler(this);
mouseHandler.addEventListener(HoldEvent.HOLD_COMPLETE, onMouseHoldComplete);
}
private function onMouseHoldComplete(e:HoldEvent):void {
// Do something
}
}

I just use robber penners signals. Very easy to use.
http://github.com/robertpenner/as3-signals

Related

Custom events not working in AS3

I have an event called SelectEvent. Whenever I click the buyer, the select event should be launched. But that is not what is happening.
My code of base:
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
public class FashionFrenzy extends MovieClip
{
public var Buyer_mc:Buyer;
public var Buyers:Array;
private var BuyerNumber:Number;
public var xpositions:Array;
public var ypositions:Array;
public var SelectedBuyer:Number;
public function FashionFrenzy()
{
GameTimeController();
xpositions=new Array();
xpositions.push(523,563,603);
ypositions=new Array();
ypositions.push(377,377,377);
Buyers = new Array ;
BuyerNumber=0;
Time_mc.gameTimer.addEventListener(TimerEvent.TIMER,GenerateBuyers);
addEventListener(SelectEvent.BUYERSELECT,showselectbuyer);
}
public function GameTimeController()
{
Time_mc.StartGame();
}
public function showselectbuyer(event:SelectEvent):void
{
trace("Bamba");
}
public function GenerateBuyers(event:TimerEvent):void
{
if(BuyerNumber<6)
{
if (Math.random() < 0.01)
{
var position:Number = Math.floor(Math.random()*3);
var newBuyer_mc = new Buyer(xpositions[position],ypositions[position],BuyerNumber);
ypositions[position]-=40;
Buyers.push(newBuyer_mc);
addChild(newBuyer_mc);
BuyerNumber++;
}
}
for each (var buyer_mc:Buyer in Buyers)
{
if(buyer_mc.walking==true)
{
buyer_mc.Enter();
}
}
}
}
}
My code of the buyer:
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
public class Buyer extends MovieClip
{
public var buyerTimer:Timer;
public var walking:Boolean;
public var stopposition:Number;
public var buyerCode:Number;
public function Buyer(startx:Number, stopy:Number, code:Number)
{
x=startx;
stopposition=stopy;
walking=true;
buyerCode=code;
BuyerProperties();
}
public function Enter():void
{
if(y>stopposition)
{
walking=false;
StartFunction();
}
else
{
y= y+3;
}
}
public function BuyerProperties():void
{
buyerTimer = new Timer( 25 );
trace(" I am generated");
}
public function StartFunction():void
{
buyerTimer.start();
addEventListener(MouseEvent.CLICK,Select);
trace("My timer starts now within Buyer.as");
}
public function Select(event:MouseEvent):void
{
trace(buyerCode);
dispatchEvent( new SelectEvent(SelectEvent.BUYERSELECT));
}
}
}
Now that when I'm clicking the buyer, the MouseEvent.CLICK is activated and then in the buyer.as, buyercode is traced on the screen. But the event is not dispatched or else it is dispatched but the eventlistener is not executing the code. I'm not getting any runtime errors. the function "showselectbuyer" is never even launched.
How should I solve it?
The accepted answer is incorrect. The provided solution works but for the wrong reasons. It creates a direct dependency to the object supposed to listen to the custom event and then makes that object be the dispatcher. All together this makes the whole idea of using event/custom event unnecessary at best since in that case a simple callback would work just as well. Instead using the useCapture flag would make the whole system work as expected:
addEventListener(SelectEvent.BUYERSELECT,showselectbuyer, true);
The accepted solution is also the inverse way of dealing with non DisplayObject event propagation. The dispatcher should be the listener (no dependencies) and not the listener should be the dispatcher (dependency necessary).
The trouble with custom events is that they don't bubble up the display list, so in case your event to be registered you need to dispatch it to the class instance that has a listener to that event attached. In your case it's an instance of FashionFrenzy. Apparently buyers don't know about a fashion frenzy instance they are running in, so they dispatch the event to themselves and wonder why no one else listens. In order to resolve this, either attach the listener to the buyer, or in the buyer class dispatch the event to parent, which is apparently the instance you want to receive the event.

How to remove a event listener with an unknown function in as3?

My idea in a small upload software is to use always the same object for all tasks (defined before), I just add and remove the events and make the requests, since the parameters are always the same (same method, same url...).
Any time the request is completed, I remove the listeners so the same object can be used again.
The problem is when some error occurs, than the listener call the the function ioerror, but I don't know what function should be called instead if there was no error:
private function ioerror(e:IOErrorEvent){
e.target.removeEventListener(Event.COMPLETE, unknownfuncion);
e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
msg("Error somewhere ("+e.text+")");
}
How to get the name of "unknownfunction" ? My fear is to leave events behind...
You could set up a couple of simple classes to manage a collection of event listeners. Lets call the collection EventBatch, which could look like this:
public class EventBatch
{
private var _items:Vector.<EventBatchItem> = new <EventBatchItem>[];
public function addListener(target:IEventDispatcher, type:String, callback:Function):void
{
var item:EventBatchItem = new EventBatchItem(target, type, callback);
_items.push(item);
target.addEventListener(type, callback);
}
public function removeAll():void
{
for each(var i:EventBatchItem in _items)
{
i.target.removeEventListener(i.type, i.callback);
i.dispose();
}
_items = new <EventBatchItem>[];
}
}
And here's the accompanying model to represent an item:
internal class EventBatchItem
{
private var _target:IEventDispatcher;
private var _type:String;
private var _callback:Function;
public function EventBatchItem(target:IEventDispatcher, type:String, callback:Function)
{
_target = target;
_type = type;
_callback = callback;
}
internal function dispose():void
{
_target = null;
_callback = null;
}
internal function get target():IEventDispatcher{ return _target; }
internal function get type():String{ return _type; }
internal function get callback():Function{ return _callback; }
}
This way, you can add your event listeners like this:
var batch:EventBatch = new EventBatch();
batch.addListener(urlLoader, Event.COMPLETE, completeHandler);
batch.addListener(urlLoader, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
batch.addListener(urlLoader, IOErrorEvent.IO_ERROR, ioErrorHandler);
And in any of those listener functions, simply use the .removeAll() method:
batch.removeAll();
If you known all the functions that could possibly be added as a Listener, you can just remove all of them. Using removeEventListener() with a method that is not actually listening do nothing. So you could use something like that :
private function ioerror(e:IOErrorEvent){
// I know that Event.COMPLETE could be listened by function1, function2 or function3
// I remove all of them
e.target.removeEventListener(Event.COMPLETE, function1);
e.target.removeEventListener(Event.COMPLETE, function2);
e.target.removeEventListener(Event.COMPLETE, function3);
e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
msg("Error somewhere ("+e.text+")");
}
Another possibility is to keep track of the method(s) actually listening the event in a variable.
public function doSomething() {
loader.addEventListener(Event.COMPLETE, onCompleteSomething);
listeningComplete= onCompleteSomething;
}
public function doSomethingElse() {
loader.addEventListener(Event.COMPLETE, onCompleteSomethingElse);
listeningComplete= onCompleteSomethingElse;
}
private function ioerror(e:IOErrorEvent){
e.target.removeEventListener(Event.COMPLETE, listeningComplete);
e.target.removeEventListener(IOErrorEvent.IO_ERROR, ioerror);
msg("Error somewhere ("+e.text+")");
}
private var listeningComplete:Function;
Assuming the handler is reset and an instance to the object is retained, you could simply set useWeakReference to true in your addEventListener() function for garbage collection.
However, a better design pattern is to abstract service methods to a class.
Then, calling dispose can remove all handlers.
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
public class AbstractService extends EventDispatcher
{
public var data:Object;
public var requestMethod:String = URLRequestMethod.GET;
public var url:String;
protected var urlLoader:URLLoader;
protected var urlRequest:URLRequest;
public function AbstractService()
{
super();
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
/**
*
* #param url
* #param data String or URLVariables
*/
public function load(url:String=null, data:Object=null, requestMethod:String=URLRequestMethod.GET):void
{
if (url)
this.url = url;
if (data)
this.data = data;
if (requestMethod)
this.requestMethod = requestMethod;
urlRequest = new URLRequest(this.url);
urlRequest.data = this.data;
urlRequest.method = this.requestMethod;
urlLoader.load(urlRequest);
}
protected function completeHandler(event:Event):void
{
}
protected function ioErrorHandler(event:IOErrorEvent):void
{
}
protected function securityErrorHandler(event:SecurityErrorEvent):void
{
}
public function dispose():void
{
urlLoader.removeEventListener(Event.COMPLETE, completeHandler);
urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
}
}
Take a look at my previous answer to Is There A Way To Remove Events Easier?. Basically, there is no easy way to do it. In that answer, I put together a simple way to track events that are added to a class by simply overriding the event listener methods. Using that method, you could just call removeAllEventListeners() and be done with it. It works fairly well, so long as you consistently remember to call that function (otherwise things will never get removed from memory).
This is overkill for the majority of situations, however. I'm currently using it for a massive application and it has helped immensely, but for something simple, it is just going to add extra computations and memory consumption to your app that is unneeded.

AS3 - Having trouble with a basic game class

So I am creating a space shooter game. My document class is Engine and it looks like this:
package Classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
public class Engine extends MovieClip
{
private var startMenu:StartMenu;
private var numberOfStars:int = 80;
public static var enemyList:Array = new Array();
private var spaceShip:Ship;
private var hud:HUD;
public function Engine()
{
startMenu = new StartMenu();
stage.addChild(startMenu);
startMenu.x = (stage.stageWidth / 2);
startMenu.y = (stage.stageHeight / 2);
}
private function startGame()
{
stage.removeChild(startMenu)
spaceShip = new Ship(stage);
stage.addChild(spaceShip);
spaceShip.x = (stage.stageWidth / 2);
spaceShip.y = (stage.stageHeight / 2);
spaceShip.addEventListener("hit", shipHit);
hud = new HUD(stage); //create the HUD
stage.addChild(hud); //and display it.
for (var i:int = 0; i < numberOfStars; i++)
{
stage.addChildAt(new Star(stage), 1);
}
addEventListener(Event.ENTER_FRAME, createFighter);
}
}
So as you can see I am calling on another class called StartMenu. This is where I am having trouble: Here is the code (Or lack there of)
package Classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.*;
public class StartMenu extends MovieClip
{
public function StartMenu()
{
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
private function buttonClicked(e:MouseEvent)
{
}
}
}
(Ignore the indentation errors, it is correct in the real code)
Okay so imagine a button being displayed on the screen. This button is part of the StartMenu Class and is listening for a MouseEvent.CLICK.
Once the button is clicked I need to somehow travel back to the Engine class and call the function startGame() , but I can't just do Engine.startGame() , I have tried setting the function to a public function, and I have tried setting the function to a public static function. no luck. HELP PLEASE?? Any method will be fine, I just need a way for this class to go to the startGame function once the button is clicked!
Probably the quickest way to do this is to add an Engine variable into the StartMenu class and pass the engine through the start menu's constructor. Here's a short code sample:
StartMenu
public class StartMenu extends MovieClip
{
private var _engine:Engine // add a new variable to the start menu class
public function StartMenu(engine:Engine) // add a new parameter to the constructor
{
_engine = engine; // set the variable to the value passed through the constructor
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
private function buttonClicked(e:MouseEvent)
{
_engine.startGame()
}
}
Engine
public function Engine()
{
startMenu = new StartMenu(this);
// pass through the current instance of engine using the this keyword
...
}
public function startGame() // change private to public
{
...
}
I hope that helps
In your Engine.as class, you can put :
public static var instance:Engine;
public static function getInstance():Engine
{
return instance as Engine;
}
and in constructor of engine class put :
instance = this;
now you can use instace of Engine class and all the public functions and variables anywhere in your project by :
Engine.getInstance().startGame();
It can help you.
There are two types of solving such a case. One is using parent reference or specific reference to call a certain function, as Ethan Worley andwered, the other is using a customizable public clicker setter like this:
public class StartMenu extends MovieClip
{
private var button1:MovieClip; // or whatever type your button is
private var startGameFunction:Function;
public function StartMenu()
{
// some initialization code if needed, including allocating button1
startGameFunction=null;
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
public function set startGameClicked(value:Function):void {
if (value==startGameFunction) return; // nothing to set
startGameFunction=value;
}
private function buttonClicked(e:MouseEvent)
{
if (startGameFunction) startGameFunction(); // if there's a function assigned, call it
}
}
Engine class:
public function Engine()
{
startMenu = new StartMenu();
startMenu.startGameFunction=this.startGame;
// no "()" here, as we are giving a function reference
...
}
public function startGame() // change private to public
{
...
}
I am a bit surprised that no one mentioned an Events based approach yet. That's what I would have used for such a requirement, since I don't really find the idea of passing an entire class instance for just a function call to be that appealing (that would mean that I may be a bit biased towards this approach so please feel free to point out the drawbacks it has, if any).
Inside your Engine class:
public function Engine()
{
startMenu = new StartMenu();
startMenu.addEventListner('StartGame', startGame);
stage.addChild(startMenu);
..
}
private function startGame(e:Event)
{
startMenu.removeEventListner('StartGame', startGame);
..
}
Inside your StartMenu class:
private function buttonClicked(e:MouseEvent)
{
this.dispatchEvent(new Event('StartGame'));
..
}

Can't dispatch custom event from one class to another in Flash AS3

This is my custom event class:
package{
import flash.events.Event;
public class PetEvent extends Event{
public static const ON_CRASH:String = "onCrash";
public function PetEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false):void{
super(type, bubbles, cancelable);
}
override public function clone():Event {
return new PetEvent(type, bubbles, cancelable);
}
}
}
This is my game handler. I create a new instance of the class Surf from which I want to listen from.
package {
import flash.display.MovieClip;
import flash.events.Event;
public class GameHandler extends MovieClip {
public var newGame:Surf;
public function GameHandler() {
newGame = new Surf();
newGame.addEventListener(PetEvent.ON_CRASH, onCrash);
addChild(newGame);
}
public function onCrash(petEvent:PetEvent):void{
trace("MPAM");
var gameOver:GameOver = new GameOver(stage.stageWidth, stage.stageHeight);
addChild(gameOver);
newGame = null;
}
}
}
And the relevant lines from the Surf class:
public function startSurfing(timerEvent:TimerEvent):void
{
moveCatandDog();
for each ( var boat:Boat in armada)
{
boat.moveBoat(boatSpeed);
if ( cat.hitTestObject(boat) || dog.hitTestObject(boat) )
{
dispatchEvent( new PetEvent(PetEvent.ON_CRASH) );
gameTimer.stop();
}
}
}
So when Surf detects a crash I want it to send the event to GameHandler and GameHandler will create a GameOver instance.
I have tried everything and I don't even get a trace. I normally don't ask questions but this is for a uni project and I'm running out of time. I would really appreciate any feedback. Thanks!
Problem solved!
I had to change my Document Class to GameHandler and make a public static variable of stage.
Previously I had Surf as my Document Class because I had some keyboard listeners set to the stage.
So the PetEvent and the dispatch in Surf were correct. I changed the GameHandler as shown below, with another solution I found in StackOverflow.
Inside the constructor of GameHandler, if the stage is ready (not null) it sets it to the public static variable STAGE (via the init function), otherwise it adds a listener and when the stage is ready it does the same thing and removes the listener.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class GameHandler extends MovieClip {
public var newGame:Surf;
public static var STAGE:Stage;
public function GameHandler() {
if (stage){
init();
} else {
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
newGame = new Surf();
newGame.addEventListener(PetEvent.ON_CRASH, onCrash);
addChild(newGame);
}
private function init(e:Event=null):void{
removeEventListener(Event.ADDED_TO_STAGE, init);
// store stage reference when stage ready
STAGE=stage;
}
public function onCrash(petEvent:PetEvent):void{
var gameOver:GameOver = new GameOver(stage.stageWidth, stage.stageHeight);
addChild(gameOver);
newGame = null;
}
}
}
and I imported GameHandler into Surf with:
import GameHandler;
so I can set the listeners in Surf to GameHandler.STAGE.addEventListener (...)
Thanks everyone for the suggestions!

How do I modify existing AS3 events so that I can pass data?

So I want a way to set up events so that I can pass data without creating closures \ memory leaks. This is as far as I have got:
package com.events {
import flash.events.Event;
public class CustomEvent extends Event {
public static const REMOVED_FROM_STAGE:String = "removedFromStage";
public var data:*;
public function CustomEvent(type:String, customData:*=null, bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
this.data = customData;
}
public override function clone():Event {
return new CustomEvent(type, data, bubbles, cancelable);
}
public override function toString():String {
return formatToString("CustomEvent", "type", "data", "bubbles", "cancelable", "eventPhase");
}
}
}
This gets me the following behavior:
function testme(e:Event) {
trace(e);
}
test_mc.addEventListener(CustomEvent.REMOVED_FROM_STAGE, testme);
test_mc.dispatchEvent(new CustomEvent(CustomEvent.REMOVED_FROM_STAGE, 42));
//Traces [CustomEvent type="removedFromStage" data=42 bubbles=false cancelable=false eventPhase=2]
removeChild(test_mc);
//Traces [Event type="removedFromStage" bubbles=false cancelable=false eventPhase=2]
My goal is to get the custom data I want to pass to get passed from the event flash fires, not just the one that I fire. For example, what if I wanted to pass a movieclip along with a loader.COMPLETE event to put the resulting bitmap in?
You extended the Event class for it to dispatch with extra data, now if you want the Loader class to dispatch your custom event type, extend the Loader class to do that (or any other class you want to do this with). In this example I'll override URLLoader with this functionality (because Loader actually dispatches events from it's contentLoaderInfo, which needs two overridden classes, and I just want to keep it simple)
package com.net
{
import flash.net.URLLoader;
import flash.events.Event;
import com.events.CustomEvent;
public class CustomLoader extends URLLoader
{
// URLLoader already has a data property, so I used extraData
public var extraData:*;
override public function dispatchEvent(event: Event) : Boolean
{
var customEvent: CustomEvent = new CustomEvent(event.type, extraData, event.bubbles, event.cancelable);
return super.dispatchEvent(customEvent);
}
}
}
Now to use this with your CustomEvent class try this code in your .fla
import com.net.CustomLoader;
import com.events.CustomEvent;
var loader: CustomLoader = new CustomLoader();
loader.extraData = "Extra Data";
loader.load(new URLRequest("test.xml"));
loader.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete(event: CustomEvent) : void
{
trace(event.data); // Extra Data
}
BAM! Custom data on your innately dispatched events!
The following shows the cleanest way to create a custom event. Typically event types have public static references typed in all capitol letters. When an event is dispatched, it passes an Event, or CustomEvent, object to the event handler method. This is where you can retrieve your passed value.
package com.hodgedev.events
{
import flash.events.Event;
public class CustomEvent extends Event
{
public static const VALUE_CHANGED:String = "VALUE_CHANGED";
public var value:Number;
public function CustomEvent(pValue:Number)
{
super(CustomEvent.VALUE_CHANGED);
value = pValue;
}
public override function clone():Event
{
return new CustomEvent(value);
}
}
}
When we dispatch events, we create a new instance of the event to be passed as such.
private var _someValue:int = 12;
dispatchEvent(new CustomEvent(_somevalue));