PDA

Volledige versie bekijken : [PureMVC] moeite met asynchronous notifications


nrocco
%Europe/Berlin %726 %2008, 17:25
In mijn PureMVC applicatie heb ik een aantal mediators die views beheren.
Zodra ik ergens in mijn applicatie op een button click die een panel toont, moeten er meerdere dingen gebeuren.

Mediator X stuurt een notification uit, bijv: REQUEST_PANEL

#1 Mediator A moet er voor zorgen dat er op de background view lichten uit gaan.
#2 Mediator B moet (als er een panel in beeld is) dit panel uit tweenen en weghalen
#3 Command A moet controleren of Panel als geladen is..
- zo nee, #3.1 Proxy A laat het panel in (externe SWF).
als panel is geladen of hij was al geladen...
#4 Mediator A tweent op de background view weer de lichtjes aan en
#5 Mediator B laat het nieuwe panel zien.

stap 4 en 5 moeten pas worden uitgevoerd als de tween van stap #1 en #2 volledig klaar zijn.

afhankelijk van wat voor panel er getoont moet worden, doen Mediator C, D enz.. ook nog dingen.

als een panel reeds geladen is gaan de tweens 'lampjes uit', 'lampjes aan', 'panel weghalen', 'panel laten zien' zo snel dat je niet meer ziet dat de tweens gebeuren.

Hoe zorg ik ervoor dat ik in PureMVC, dit soort synchrome acties kan uitvoeren?
Iemand hier ervaring mee?

PsK
%Europe/Berlin %408 %2008, 09:47
Misschien is het een idee om een Command B te maken die een extra notification stuurt naar Med A en B om alles te activeren wanneer alles gereed is.
Dus Command B krijgt een notification van Med A en B dat ze klaar zijn met tweenen en van Command A of proxy A dat hij klaar is met inladen.
Zodra deze 3 notifications binnen zijn stuurt Command B een notification naar A en B dat ze kunnen beginnen met tweenen.

nrocco
%Europe/Berlin %581 %2008, 13:57
Misschien is het een idee om een Command B te maken die een extra notification stuurt naar Med A en B om alles te activeren wanneer alles gereed is.
Dus Command B krijgt een notification van Med A en B dat ze klaar zijn met tweenen en van Command A of proxy A dat hij klaar is met inladen.
Zodra deze 3 notifications binnen zijn stuurt Command B een notification naar A en B dat ze kunnen beginnen met tweenen.

Hmm, klinkt goed.
Alleen hoe zorg ik ervoor dat een command 1x ge-execute wordt, en gedurende die tijd wacht (en dus blijft bestaan) totdat hij alle 3 notifications heeft ontvangen?

Ik begrijp dat vanuit het gedachtegoed PureMVC commands altijd een korte levensduur dienen te hebben en dus eigenlijk ook geen eventlisteners mogen bevatten. Zodra een notification een command triggerd wordt een nieuwe instantie van de Command gemaakt, wordt de execute() functie uitgevoerd en is het de bedoeling dat deze instantie zo snel mogelijk in de Garbage Collection terecht komt ivm geheugen.

Zoals beschreven hier: http://puremvc.org/content/view/80/188/

Volgens mij zijn Commands geen singletons (zoals Proxies en Mediators)... het framewerk zal bij elke notificatie (waar een command naar luisterd) een nieuwe Command aanmaken.


Ik ben bezig geweest met een oplossing vanuit een iets andere hoek:
Op dit moment gebruik ik de derde property die je een nieuwe Notification kan meegeven.. de getType property. de type gebruik ik om een fasering te geven aan een notification.
Bijv. een REQUEST_PANEL notification begint met een type "phaseStart"

Een command ziet er bij mij dan zo uit:

public static const PHASE_START:String = "phaseStart";
public static const PHASE_LIGHTS_ARE_OFF:String = "phaseLightsAreOff";
public static const PHASE_PANEL_LOADED:String = "phasePanelLoaded";

override public function execute( note:INotification ) : void
{
switch( note.getType() )
{
case PHASE_START:
// command doet hier niets mee
// de mediator A luistert alleen naar deze fase,
// tweent het licht uit, en als die tween klaar is stuurt
// de mediator dezelfde REQUEST_PANEL notification
// maar dan met de type property op "phaseLightsAreOff"
break;

case PHASE_LIGHTS_ARE_OFF:
// deze command roept de proxy aan,
// kijkt of het panel aanwezig is, zoja dan stuurt het
// de notification REQUEST_PANEL maar dan met de
// type property op "phasePanelLoaded"
break;

case PHASE_PANEL_LOADED:
// command doet niets met deze fase want Mediator A
// luistert hierna om de lichtjes weer aan te doen en
// Mediator B luisterd hier ook naar om het panel te tonen
break;

default:
trace("RequestPanelCommand::execute - ERROR, phase not recognized");
break;
}
}

Ik ben me er van bewust dat op deze manier drie keer een instantie van deze Command wordt aangemaakt terwijl dit maar 1x nodig is, maar het lijkt mij in kilobytes besparender dan aparte commands te maken. Lijkt mij onoverzichtelijk en dan moet je ook meerdere Notifications gebruiken... het in en uit tweenen van panels is maar een onderdeel van de App die ik wil bouwen dus ik heb al een overvloed (lees: chaos) aan notifications.

De case: PHASE_START en PHASE_PANEL_LOADED neem ik niet eens op in m'n switch statement maar heb het hier op flashfocus voor de sake of clarity er toch even bijgezet.
Voor de twee fases dan deze command niets doet gaat de instantie van die command vrij snel naar de garbage collection, lijkt mij.

Waar ik nu eigenlijk benieuwd naar ben is of dit een best practice is om de getType property op deze manier te gebruiken.

BernardV
%Europe/Berlin %721 %2008, 17:18
Niet dat ik veel met PureMVC werk, maar zou je zoiets niet in je Facade inbouwen?
Die communiceert namelijk met alle Mediators, Proxies en Commands.. immers mag je niet eens een command aanroepen vanuit een Mediator of Proxy.. die ontvangen alleen een Command.

//edit: Niet mogen is natuurlijk een groot woord.

nrocco
%Europe/Berlin %908 %2009, 21:47
Niet dat ik veel met PureMVC werk, maar zou je zoiets niet in je Facade inbouwen?
Die communiceert namelijk met alle Mediators, Proxies en Commands.. immers mag je niet eens een command aanroepen vanuit een Mediator of Proxy.. die ontvangen alleen een Command.

//edit: Niet mogen is natuurlijk een groot woord.

Hoe zie jij dit 'inbouwen in de facade' voor je? In principe maak ik gebruik van Notifications, een middel wat al is ingebouwd in de facade.
In proxies en mediators roep je inderdaad niet direct Commands aan, maar stuur je Notifications die op hun buurt de betreffende Command triggeren.

Ik wil voorkomen dat ik te veel Notifications ga gebruiken voor één use-case (laden van een panel) zoals REQUEST_PANEL, TURN_LIGHTS_OFF, LIGHTS_ARE_OFF, SHOW_PANEL.
Ook wil ik voorkomen dat ik een hele ketting aan acties krijg. Want daarmee lijm ik Mediators weer te veel aan elkaar.

Misschien zit ik te ingewikkeld te denken. Voorheen wou ik het uit doen van de lichten en het inladen van een panel parallel laten lopen. Want stel dat het uit doen van de lichten een Tween is van 1.5 seconden, dan zijn toch 1.5 seconden die ik op de achtergrond had kunnen gebruiken voor het inladen van een panel (die bijv 800kb kan zijn).
Nou zal die tween niet 1.5 seconden zijn, maar eerder 0.5... dat is nog te overzien

Bovenstaande is wel te bereiken:
Probleem is dat ik niet vantevoren weet wanneer een panel klaar is met laden, nog voordat de 'licht uit' tween klaar is, of pas daarna. Beide situaties zijn mogelijk en kunnen zich voordoen.
Een andere mogelijkheid is namelijk om op de Mediator twee variabelen bij houden.
panelLoaded = false
tweenLightsOutDone = false
en pas als beide true zijn (dus als de mediator twee notifications heeft ontvangen) dan panel intweenen en lichten aan doen.