View Full Version : eventDispatcher in nested class
Maquisard
04-27-2005, 05:28 PM
Hi! Once again i will try to be clear even if my english is bad.
I'm a newbie that try to understand expert stuff.
Ok, my problem, i got a main class that extend a movie clip. This main class must have the capabilities to send events. And this main class have some other movieClip in it that are classes itself. This other's movieClip must also raised event that informed the main class of their status.
For that i use eventDispatcher, like this:
dynamic class mainClass extends MovieClip {
function mainClass() {
init();
mx.events.EventDispatcher.initialize(this);
}
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
function sendMessage(p_msgtxt:String):Void {
// set up the event object:
var eventObj:Object={target:this,type:"message"}
eventObj.msgtxt = p_msgtxt;
// dispatch the event
dispatchEvent(eventObj);
}
//...
It's working great for the main class.
Now, it is a good approach? Do i have to repeat that code in ALL of my other's movieClip to had to them the capability to raise event? Is their a better approach... like modifying the movieClip prototype, or...???
I'm confused...
thanks!
deadbeat
04-27-2005, 06:10 PM
Probably the easiest thing to do is put all the EventDispatcher related code into one class, then subclass that as needed:
class MyDispatcher extends MovieClip{
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
function MyDispatcher(){
mx.events.EventDispatcher.initialize(this);
}
function sendMessage(p_msgtxt:String):Void {
var eventObj:Object={target:this,type:"message"}
eventObj.msgtxt = p_msgtxt;
dispatchEvent(eventObj);
}
}
Then, any class that you want to be able to dispatch events can simply extend this class:
class MyClass extends MyDispatcher{
function MyClass(){
// constructor
}
// etc...
}
HTH,
K.
senocular
04-27-2005, 06:20 PM
extending is a good idea. I personally, however, apply EventDispatcher to a class prototype so that it's inherited instead of defined individually for each class instance created.
I also define the functions as var name:Function instead of actual functions. In the case of applying EventDispatcher.initialize to instances, using functions creates redundant empty functions in the actual class itself.
These are, of course, incredibly minor things and nothing to be worried about ;)
deadbeat
04-27-2005, 06:32 PM
Interesting...I also usually define them as vars rather than functions, but I didn't realize there was any real difference...I always assumed the functions were overwritten during the call to mx.events.EventDispatcher.initialize() - didn't know it was actually creating copies of the functions...
K.
senocular
04-27-2005, 06:34 PM
functions defined in a class are defined in the prototype of the class object. When initialize is used in the constructor, its initializing and adding the functions to the actual class instance. The original empty functions still exist - they are overridden, not overwritten.
deadbeat
04-27-2005, 06:38 PM
OK, that makes sense...
You always have the inside scoop...
:D
K.
senocular
04-27-2005, 06:49 PM
;)
.
Maquisard
04-27-2005, 07:13 PM
Hey thanks guy's. I will go for now with the extending class solution.
But i'm stuck again.... :(
In my main class i try to make the sendMessage function more generic and i name it sendEvent. So now i have:
dynamic class mainClass extends MovieClip {
function mainClass() {
init();
mx.events.EventDispatcher.initialize(this);
}
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
function sendEvent(e:Object):Void {
var eventObj:Object;
eventObj.target = this;
eventObj.type = e.type;
switch (e.type) {
case "message" :
eventObj.mess = e.mess;
break;
case "finished" :
break;
default: break;
}
dispatchEvent(eventObj);
}
function message(p_eventObj) {
trace("I received a message: "+p_eventObj.mess);
}
function myTest() {
this.addEventListener("message",this);
sendEvent({type:"message",mess:"my message"});
}
Now i run the myTest function, sendEvent is called, but the "message" funcion associated with the event "message" is never fired. Do you understand why?
And thank's again for you help! For two weeks it's incredible the progress i made with AS2.
Vincent
Maquisard
04-27-2005, 07:37 PM
i just answered my own question.
I change this line:
var eventObj:Object;
to that:
eventObj = {};
Now it work's, but for a reason i don't understand!
deadbeat
04-27-2005, 07:43 PM
This simply defines a variable's datatype as Object, but doesn't create a new instance:
var eventObj:Object;
This actually creates a new instance of an object:
eventObj={};
You can combine the two to create an instance of a specific datatype:
var eventObj:Object={};
K.
Maquisard
04-27-2005, 08:47 PM
hey thanks again deadbeat for the explanation.
Got another question for you (and all the master's!)"
I make a superclass MyDispatcher as you suggest and i make all my other classes extending the MyDispatcher Class.
Now, my mainClass wants to receive an event (my event is called "finished") from a movieClip nested inside of him.
Something like this:
//in mainClass.as
function finished(p_eventObj) {
trace("my subClass has finished!");
}
subMC.addEventListener("finished",this);
And the subclass want to broadcast an event:
//in subClass.as
sendEvent({type:"finished"});
The event is received by the dispatcher class but not propagated to the mainClass (the function "finished" is never fired).
Now i found a way to "propagate" the event to the mainClass... but i'm not sure it's intelligent.
What i do, i change the way sendEvent works by assigning a target to dispatchEvent:
//in MyDispatcher.as
function sendEvent(e:Object):Void {
var eventObj:Object = {type:e.type};
trace("Event:"+e.target+" "+e.type);
switch (e.type) {
case "message" :
eventObj.mess = e.mess;
break;
case "finished" :
break;
default: break;
}
e.target.dispatchEvent(eventObj);
}
//in subClass.as
sendEvent({target:_parent,type:"finished"});
And it works! Once again i'm confused! Do i have to do that? I was thinking that dispatchEvent broadcast it's event to ALL the listeners.
Your help is really appreciated. Ther's not a lot of documentation for the eventDispatcher stuff!!
Thanks!
deadbeat
04-27-2005, 09:23 PM
Is your sub_MC linked to a class that extends the MyDispatcher superclass?
If not, it won't be capable of broadcasting events...although, as you've discovered, you can broadcast the event through the _parent...
K.
Maquisard
04-27-2005, 09:32 PM
No, the subMC extend directly the myDispatcher Class. I don't want it to extend the mainClass because subMc is not a subset of the mainClass. It's more like an idependent object used inside the main movie clip. Hope you understand! :rolleyes:
Now, i found my solution to broadcast by the _parent tag not very elegant. It is a possibility to make the MyDispatcher class a global object and to "grab" a reference to it in all my classes? Would that be more elegant? Any suggestion?
Thanks!
Maquisard
04-28-2005, 06:48 PM
Does someone have a good model for broadcasting EVENT between movieclips?
It is possible to have a global broadcaster, then each movieClip could register to it?
Any idea?
Thanks... i browse everything on the net before asking but i can't find a good and simple solution for that.
Vincent
senocular
04-28-2005, 07:09 PM
yes, its possible. It all depends on what you're doing.
Maquisard
04-28-2005, 07:46 PM
Senocular: And it is a good approach to implement event broadcasting between movie clip or class?
And if yes, any idea on how to implement it. Let say i start with the MyDispatcher class that deadbead describe a fex post ago.
Where do i put this line:
mx.events.EventDispatcher.initialize(this);
in the MyDispatcher class? or in each movie clip or class that wants to register to event broadcasting?
//MyDispatcher.as
class MyDispatcher extends MovieClip{
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
function MyDispatcher(){
//where should this LINE of code go?
mx.events.EventDispatcher.initialize(this);
}
//i REMOVE THE TARGET STUFF
function sendEvent(e:Object):Void {
var eventObj:Object = {type:e.type};
//trace("Event:"+e.target+" "+e.type);
switch (e.type) {
case "message" :
eventObj.mess = e.mess;
break;
case "finished" :
break;
default: break;
}
//e.target.dispatchEvent(eventObj);
dispatchEvent(eventObj);
}
}
Should I instantiate in the FLA something like this:
//in the FLA
var x:MyDispatcher;
x = new MyDispatcher;
_global.dispatchGlobal = x;
Then in my class or movieclip what should i add? Do i have to only send the event:
_global.dispatchGlobal.sendEvent({type:"myEvent"});
No "targetting" of the sendEvent? Because everyone who add a listener would be inform of the event?
Once again, sorry if it's confused. I'm confused, and the fact that english is not my native language give me difficulty to express clearly my confusion. ;)
Maquisard
04-28-2005, 09:09 PM
Also, what i understand is that when this line is executed:
mx.events.EventDispatcher.initialize(this);
All this pointer is populated:
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
I am right? So if it's the case, i can't have a global broadcaster (with global pointer) for every class or movieclip i have because each time i want to register (a class or movie clip) the pointer will be replaced.... No? Yes? So much confusion.... Arghhh.
senocular
04-28-2005, 09:28 PM
I dont understand what you're asking. "event broadcasting between movie clip or class?" ?
Its not that difficult of a concept. I think you're making it harder on yourself than it really needs to be.
The concept is this:
An object plays the part of "broadcaster".
- this can be any object you want, or multiple
- broadcasters are defined as broadcasters using EventDispatcher.initialize
- broadcasters send events to their listeners
Other, multiple objects play the part of "listeners"
- These can be any objects you want, or even functions with EventDispatcher
- listeners become listeners of broadcaster objects using the add listener method
- listeners for EventDispatcher listen to specific events as specified in addEventListener, broadcaster.addEventListener("event", listener);
Broadcasters send events using broadcaster.dispatchEvent(eventObject); All listeners to that broadcaster who is listening to the event specified in the event object gets that event called for them.
You, as a developer need to decide:
what events you are using
what objects (listeners) need to receive those events
and who decides when those events are called (broadcaster)
What is used for what and how is dependant on your application design and needs.
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.