В одном из проектов ( связка Robotlegs2 + Starling + Feathers ) подключал звуки. Очень не удобно было работать через медиаторы для каждой вью, где нужно было озвучить клик мышки или другие звуки интерфейса. Плюс тот же функционал нужен и внутри фреймворка ( при инжекте ). Сигналы добавлять пробывал, но это дополнительный импорт классов, менялась архитектура приложения в принципе, что-то сыпалось. Да и вродь как не в POC роботлегса ( есть расширения, но это уже больше похоже на костыль, решая вопрос оптимизации разработки). Но всё же очень хотелось что-бы всё было по стандартам и прямо из вью, работать со звуком не создавая 100-500 обработчиков.
Решение немного замудрённое.
Конфиги
Код AS3:
package com.pentagames.libobingo.configuration.platform
{
import com.pentagames.libobingo.model.SoundManager.SoundManager;
import robotlegs.bender.framework.api.IConfig;
import robotlegs.bender.framework.api.IContext;
public class ModelConfig implements IConfig
{
[Inject]
public var context:IContext;
public function configure():void
{
var prepare:Vector.<Class> = new <Class> [
SoundManager
];
while ( prepare.length ) context.injector.map( prepare.shift() ).asSingleton();
}
}
}
Код AS3:
package com.pentagames.libobingo
{
import com.pentagames.libobingo.controll.command.init.InitServiceSoundCommand;
import com.pentagames.libobingo.events.InitializationEvent;
import robotlegs.bender.extensions.eventCommandMap.api.IEventCommandMap;
import robotlegs.bender.framework.api.IConfig;
import robotlegs.bender.framework.api.IContext;
public class CommandConfig implements IConfig
{
[Inject]
public var context:IContext;
[Inject]
public var commandMap : IEventCommandMap;
public function configure():void
{
commandMap.map( InitializationEvent.ON_INITIAL_RESOURCES_LOADED, InitializationEvent)
.toCommand( InitServiceSoundCommand );
}
}
}
Соль в том, что мы создаем для
SoundService свой медиатор и тут же инициализируем их.
Это нужно для того, что-бы связку Событие_конкретный_Класс -> Команда,
заменить на Медиатор. Который будет обрабатывать всё что нам нужно, в одном месте, единожды инициализировашись
Код AS3:
package com.pentagames.libobingo.services
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class SoundService extends EventDispatcher
{
public function SoundService(target:IEventDispatcher=null)
{
super(target);
}
}
}
Код AS3:
package com.pentagames.libobingo.controll.command.init
{
import com.pentagames.libobingo.mediator.SoundMapMediator;
import com.pentagames.libobingo.services.SoundService;
import robotlegs.bender.extensions.commandCenter.api.ICommand;
import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap;
public class InitServiceSoundCommand implements ICommand
{
[Inject]
public var mediatorMap:IMediatorMap;
public function execute():void
{
mediatorMap.map( SoundService ).toMediator( SoundMapMediator );
mediatorMap.mediate( new SoundService() );
}
}
}
Медиатор подписываеться на управляющие события связанные со звуком и передает их уже на воспроизведение модели, сервису, т.д.
Код AS3:
package com.pentagames.libobingo.mediator
{
import com.pentagames.libobingo.model.SoundManager.SoundManager;
import com.pentagames.libobingo.model.SoundManager.SoundsCollection;
import com.pentagames.libobingo.model.events.SoundEvent;
import robotlegs.bender.bundles.mvcs.Mediator;
public class SoundMapMediator extends Mediator
{
public function SoundMapMediator()
{
super();
}
[Inject]
public var player:SoundManager; // непосредственный обработчик звука
public override function initialize():void {
// без типизации по класс_событиям
eventMap.mapListener( eventDispatcher, SoundEvent.PLAY, onSoundRequest);
}
protected function onSoundRequest(event:SoundEvent):void
{
player.play(event.soundID, event.channel, event.loop, event.callBack);
}
}
}
С этого момента стало возможно
Диспатчить события
SoundEvent.PLAY с параметрами, в медиаторах без лишних строчек кода
Инжектить непосредственно
SoundManager, для работы со звуком по статическому сценарию
Передавать во вью,
SoundService для работы со звуком с выдержанной инкапсуляцией.
Расширить
SoundMapMediator, который может отлавливать любое событие лишь по его идентификатору ( type ) вместо строгой типизации ИвентКлассов и связки Событие-Команда и так по каждому отдельному событию
Код AS3:
package com.pentagames.libobingo.mediator.gameScreenSupportClasses.inGameSupportClasses.lobyViewSupportClasses.wheelMenuSupportClasses
{
import com.pentagames.libobingo.model.SoundManager.SoundManager;
import com.pentagames.libobingo.model.SoundManager.SoundsCollection;
import com.pentagames.libobingo.model.events.SoundEvent;
import com.pentagames.libobingo.model.games.Dispatcher;
import robotlegs.bender.bundles.mvcs.Mediator;
import starling.events.TouchEvent;
public class WheelMenuItemMediator extends Mediator
{
[Inject]
public var view:WheelMenuItem;
[Inject]
public var dispatcher:Dispatcher;
public function WheelMenuItemMediator()
{
super();
}
override public function initialize():void{
view.addEventListener(TouchEvent.TOUCH, onTouch);
}
private function onTouch(e:TouchEvent):void {
dispatch( new SoundEvent(SoundEvent.PLAY, SoundsCollection.SFX_WHEEL_MOUSE_OVER_1,SoundManager.CHANNEL_SOUNDS));
}
}
}
В вашем случае, можно в медиаторе основной вьюшки, ловить события унаследованные от starling_event и пересылать нужные на обработку в псевдо_команду ( медиатор )