PDA

Volledige versie bekijken : Custom event hell


Nelus
%Europe/Berlin %545 %2009, 13:06
Hallo iedereen,

Ik ben ondertussen al weer even met AS3.0 bezig en werk nu onderhand met custom events. Op de 1 of andere manier krijg ik het elke keer weer voor elkaar om problemen met mijn custom events te krijgen, vrij frustrerend. Ik heb al verschillende voorbeelden van custom events van internet erbij gepakt om te kijken wat hun anders doen. Maar ik zou het even niet weten.

Mijn applicatie maakt gebruik van AMFPHP om zijn data te ontvangen. Zodra de classe "BuddyConnection" een random conversation heeft ontvangen via zijn gateway, dispatched hij een event genaamt "NewConversationEvent".

De hierarchie van mijn applicatie (die van belang zijn voor dit probleem):
main.as
BuddyConnection.as
Conversation.ConversationHolder.as
Conversation.Events.NewConversationEvent.as

main.as:


package
{
import Conversation.*;
import Conversation.Events.NewConversationEvent;
import flash.display.Sprite;
import flash.events.Event;

/**
* ...
* @author ...
*/
public class Main extends Sprite
{

private var ConversationHold:ConversationHolder = new ConversationHolder();
private var MyBuddyConnection:BuddyConnection = new BuddyConnection();

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);

addEventListener(NewConversationEvent.NEWCONV, startNewConversation);

this.addChild (ConversationHold);

MyBuddyConnection.getRandConversation();
}

private function startNewConversation (e:NewConversationEvent) {
trace ("Event gesignaleerd! We zijn nu bij startNewConversation");
ConversationHold.parseNewConversation(e.myConversa tion);
}

}

}



BuddyConnection.as

package
{
import Conversation.Events.NewConversationEvent;
import flash.display.MovieClip;
import flash.net.NetConnection;
import flash.net.Responder;

/**
* ...
* @author ...
*/
public class BuddyConnection extends MovieClip
{

private var MyConnection:NetConnection = new NetConnection();

private var ParseRandomTalk:Responder = new Responder(resultGetRandConversation);

public function BuddyConnection()
{
MyConnection.connect ("***************************");
}

public function getAllBuddyComps()
{

}

public function getRandConversation ()
{
MyConnection.call ("BuddyGateway.getRandomTalk", ParseRandomTalk, "1");
trace ("Nu bij: getRandConversation ");
}

private function resultGetRandConversation (resultConv:Object)
{
trace("Conversation ontvangen, dispatch event!");
if (dispatchEvent(new NewConversationEvent(resultConv, NewConversationEvent.NEWCONV, true, false)) == true) {
trace ("goed verstuurd");
}
}
}

}


ConversationHolder.as:


package Conversation
{
import Conversation.Events.NewConversationEvent;
import flash.display.MovieClip;

/**
* ...
* @author ...
*/
public class ConversationHolder extends MovieClip
{

private var ConversationGraph:ConversationHolderGraph = new ConversationHolderGraph();

public function ConversationHolder()
{
ConversationGraph.x = 0;
ConversationGraph.y = 0;

this.addChild (ConversationGraph);

}

public function parseNewConversation (results:Object)
{
trace (results.toString());
trace ("Elluw!");
}

}

}



NewConversationEvent.as

package Conversation.Events
{
import flash.events.Event;

/**
* ...
* @author ...
*/
public class NewConversationEvent extends Event
{

public static const NEWCONV:String = "newconv";

public var myConversation:Object;

public function NewConversationEvent(conversationResult:Object, type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
trace("Binnenin het event...");

super(type, bubbles, cancelable);
myConversation = conversationResult;

}

public override function clone():Event
{
return new NewConversationEvent(myConversation, type, bubbles, cancelable);
}

public override function toString():String
{
return formatToString("NewConversationEvent", "conversationResult", "type", "bubbles", "cancelable", "eventPhase");
}

}

}




Zoals jullie zien heb ik er al een aardig zootje van gemaakt met mijn traces, maargoed. De output tot nu toe:


Nu bij: getRandConversation
Conversation ontvangen, dispatch event!
Binnenin het event...
goed verstuurd

Dauntless
%Europe/Berlin %554 %2009, 13:18
De grootste fout hier is dat je de initialisatie bij de declaratie van je instantie variabelen hebt.

private var ConversationHold:ConversationHolder;
private var MyBuddyConnection:BuddyConnection;

public function Main():void
{
ConversationHold = new ConversationHolder();
MyBuddyConnection = new BuddyConnection();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

Het kan zijn dat het hierdoor al wel werkt.

(Even tussendoor: laat variabelen met een kleine letter beginnen en enkel classes/interfaces met een hoofdletter.)

Daarnaast heeft het laten bubbelen van het event niet zo veel nut en kan je veel eenvoudiger de listener rechtstreeks aan de BuddyConnection instantie hangen.
MyBuddyConnection.addEventListener(NewConversation Event.NEWCONV, startNewConversation);

Nelus
%Europe/Berlin %562 %2009, 13:29
Juist! Door de eventlistener aan MyBuddyConnection te hangen, werkt het blijkbaar ineens wel! Waarom kan mijn main.as (die zover ik weet de "root" vertegenwoordigt?) niet een eventlistener hebben die naar mijn custom event luisterd?

Wat betreft de hoofdletters voor variabelen en classes enzo, normaal doe ik dat wel, maar ik ben nu bezig voor een school project wat extreem veel haast heeft, dus de structuur gaat hier helaas een beetje aan ten onder. :)

Dauntless, bedankt weer!

jawel
%Europe/Berlin %771 %2009, 18:30
MyBuddyConnection staat niet op de stage, vandaar dat het event nooit aankomt:

http://4.bp.blogspot.com/_x0Mqwpk8Pw8/RnFXiNLMxvI/AAAAAAAAAAk/FYgA3lgFSjg/s400/event_bubbling.png

Nelus
%Europe/Berlin %523 %2009, 12:34
Daar heb ik wel aan gedacht, dat hij niet terug zou bubblen, maar ik dacht dat door de instantie in main.as aan te maken hem al aan de main zou koppelen? Maar moet je dan nog addChild doen als referentie dat hij daadwerkelijk bestaat in main (stage)?

Dauntless
%Europe/Berlin %526 %2009, 12:37
Het bubbelen werkt inderdaad enkel via een display list. Je kan bv meerdere referenties naar dezelfde instantie hebben in verschillende classes. Als het op die manier ook zou bubbelen zou je uiteindelijk met 100'en gebubbelde events zitten.

Maar het heeft in dit geval geen zin om je buddy list de Sprite classe te laten extenden en toe te voegen aan de display list. Gewoon de listener rechtstreeks aan de buddy list hangen is de gebruikelijke manier.

Nelus
%Europe/Berlin %533 %2009, 12:48
Nu je het zo uitlegt klinkt het erg logisch. :)

Nogmaals bedankt, ditmaal voor de verhelderende uitleg. ;)