Actionscript has events, sort of, but there are a few issues. While doing the C# events/delegate translation into swf, I had to make some Actionscript prototype code - it may or may not be useful to you if you need events (like in C#) using Actionscript. It isn't exactly the same of course (unless you use the csswf compiler ; ), however it adds zero overhead to your file for unused events (other than a bit of stub code), so there is still something to like. The usage syntax looks like this:

anyObj.addDelegate("Press", myDelegate);

This adds a delegate to the newly generated multicast Press event. To invoke it manually, just say instance.onPress(args). To remove it say anyObj.removeDelegate("Press", myDelegate);, and (if that was the only method ref) the whole thing disappears. A delegate is just an object with an obj (instance/function ref) and a name (optional - only needed for instance methods).

You can dnld a fla at
http://debreuil.com/CSharp/csswf/swfUtil/events.fla
however it is pretty small and simple, so alternately you could just paste in the code below and go... Of course I would recommend csswf, and use that beautiful C# syntax directly, however that isn't available yet ; ) (just doing the last tests, update soon!).

Le code:

_global._oo = {};
_oo.Delegate = function(obj, name)
{ 
this.obj = obj;
this.name = name;
}
_oo.DelegateList = function(delg)
{
this._delegates = [];
if(delg.obj!=null)
this._delegates.push(delg); 
}
_oo.DelegateList.prototype._delegates = null;
_oo.DelegateList.prototype._invoke = function()
{
for(var i = 0; i < this._delegates.length; i++)
{
var d = this._delegates[i];
if(d.name != "")
d.obj[d.name].apply(d.obj, arguments);
else
d.obj.apply(null, arguments);
}
}
_oo.DelegateList.prototype._add = function(delg)
{
this._delegates.push(delg);
}
_oo.DelegateList.prototype._addList = function(delgList)
{
for(var i = 0; i < delgList._delegates.length; i++)
{
this._delegates.push(delgList._delegates[i]);
}
}
_oo.DelegateList.prototype._remove = function(delg)
{
var success = false;
for(var i = 0; i < this._delegates.length; i++)
{
if(this._delegates[i].obj == delg.obj && this._delegates[i].name == delg.name)
{
this._delegates.splice(i,1);
success = true;
}           
}
return success;
}
_oo.DelegateList.prototype._removeList = function(delgList)
{
var success = true;
for(var i = 0; i < delgList._delegates.length; i++)
{
var ret = this._remove(delgList._delegates[i]);
if(ret == false) success = false;
}
return success;
}
Object.prototype.addDelegate = function(event, delg)
{
if(this[event+"Delg"] == null)
{
this[event+"Delg"] = new _oo.DelegateList();
this["on"+event] = function()
{
arguments.callee.delgRef._invoke.apply(
arguments.callee.delgRef, arguments);
}
this["on"+event].delgRef = this[event+"Delg"];
}
this[event+"Delg"]._add(delg);
return this[event+"Delg"];
}
ASSetPropFlags(Object.prototype, ["addDelegate"], 1);

Object.prototype.removeDelegate = function(event, delg)
{
var success = this[event+"Delg"]._remove(delg);
if(this[event+"Delg"]._delegates.length == 0)
{
this[event+"Delg"] = null;
this["on"+event] = null;
}
return success;
}
ASSetPropFlags(Object.prototype, ["removeDelegate"], 1);
posted on Wednesday, August 04, 2004 2:29 AM
Feedback
  • # re: Events for actionscript
    Craig Babcock
    Posted @ 8/4/2004 11:30 AM
    Nice work Robin - as always.

    How does your "Delegate" differ from the component Class "Delegate"? (apart from AS version ;) )

    http://www.macromedia.com/devnet/mx/flash/articles/eventproxy.html

  • # re: Events for actionscript
    Mike
    Posted @ 8/4/2004 4:37 PM
    Looks like the AS1 equivalent?

  • # re: Events for actionscript
    Robin Debreuil
    Posted @ 8/5/2004 12:23 AM
    To be honest I haven't had a chance to look at that, but yeah it seems fairly similar. One thing I noticed is it seems to hard code the method name though (doesn't use a string, uses a reference)..? If that is the case, then I'm not sure what will happen with virtual dispatch - eg: You have a subclass that implements the same method differently, so if you send a Child instance you want the child method called, a parent instance should be the parent. Maybe the addListener somehow converts that to a string internally, not sure.

    The other main difference is this one is designed to automatically hook into 'on' methods. The plus side is system events call your delegates without the need to manually catch those events, which was actually the reason for needing this. So if you add a "Press" event for a movieclip instance, it will overwrite the 'onPress' method, catch those events, and pass them to any subscribed delegates. It doesn't seem that event system does that, but again I could be wrong. Oh, and the down side is you can't use 'on' methods for your own callbacks in the same instance. The csswf compiler will rename your 'on' methods (actually all mehtods are renamed to support method overloading), but if using this in AS directly that is something you have to avoid. I guess I should have mentioned that, I would of had I thought of it ; ).

    Not sure if those may only be for components? That would just depend on where they added the 'addEventListener' methods, on a component base class or on object. I used object mostly because C# requires it, and it was the system events I wanted piped into this all, which mostly come from mc's, text fields etc.

    Last thing, I'm not sure if those are multicast or not, but that was a requirement for C#. You need to be able to subscribe multiple delegates, and subscribe the same delegate multiple times if need be. I know some of the older event systems people used didn't do this - though seeing the 'add' word there, and a separate delegate object it probably it does.

    Basically this needed to a complete rip of C#, and it seemed easier to just write one that avoided all the built in listener stuff, rather than try to black box debug that (as you can see it isn't very long or complex doing it all manually). Event systems are pretty straight forward though, you need a scope and method name (I thought string, but maybe not), an event name/collector that goes in the instance, and a way of adding, removing and invoking the references from lists. So they usually look and act fairly similar - most of the differences come down to single/multicast, and how they integrate with system events. And of course, syntax, syntax, syntax ; ).

  • # re: Events for actionscript
    Craig Babcock
    Posted @ 8/5/2004 10:22 PM
    Thanks for the explanation!

    Do you anticipate migrating this to AS2?

    I assume you have a ton of legacy AS1 code and, like many, are caught between versions. I have only recently made the switch to AS2 and feel a bit like a fish out of water - techniques that have served me well for years are now obsolete at best, or throw errors. Hooray for progress!

  • # re: Events for actionscript
    Robin Debreuil
    Posted @ 8/6/2004 7:11 AM
    Maybe if anyone actually uses it ; ). It is actually already converted, as I had to insert it as bytecode, ugh. To go to AS2 would be pretty painless, though I'm not sure how it would react to some of the built in stuff like ASSetPropFlags..?

    It is indeed a big step moving to AS2, I have no idea why they (js people that is) decided to put the type after the variable name. Just to be different I guess ; ).

  • # re: Events for actionscript
    Owen van Dijk
    Posted @ 8/8/2004 5:38 PM
    the awkward type notation in AS2 is just a plain old historical mistake basically..and it's mentioned in the copy of EAS2 that Colin sent you ;)

Blog Stats

  • Posts - 121
  • Stories - 1
  • Comments - 1441
  • Trackbacks - 47

.Net Blogs

01101 Blogs

Flash Blogs

Graphics

People