Цитата:
Сообщение от Denis Davidov
Как то так? чем EventDispatcher лучше чем то, что Вы описали?
|
EventDispatcher лучше тем, что не диктует как называть функцию слушателя, т.е. на событие можно подписать сколько угодно разных функций, пусть они даже являются методами одного и того же объекта. А события в свою очередь можно унифицировать, и не путаться в их названиях (т.е. пример, я хочу, чтобы клип А слушал онРесайз от клипа Б, в случае с АсБроадкастером мне нужно будет разослать всем подписчикам сообщение и это сообщение будет именем вызываемого метода т.е. если у меня в клипе А уже есть функция онРесайз, то ее все равно вызовут (а я могу даже не знать/не помнить, что клип Б будет высылать клипу А это событие или случайно назвать свою функцию так же, как и высылаемое событие - более вероятная ситуация).
Конечно, есть флешевский EventDispatcher (mх.utils.EventDispatcher), но я пользуюсь своим. Вот, мб пригодиться =) Я не претендую на непогрешимость, и возможно мое творение не лучее решение, но, пока что работает и я доволен:

Код:
/**
* ...
* @author wvxvw
*/
import events.Event;
class events.EventDispatcher
{
private var _eventListeners:Array;
public function EventDispatcher()
{
_eventListeners = [];
}
public function addEventListener(evt:String, fn:Function, ob:Object):Void
{
_eventListeners.push( { e:evt, f:fn, o:ob } );
}
public function removeEventListener(evt:String, fn:Function, ob:Object):Function
{
var i:Number = 0;
var l:Number = _eventListeners.length;
var obj:Object;
for (i = 0; i < l; i++)
{
obj = _eventListeners[i];
if (obj.e != _eventListeners[i].e) continue;
if (obj.f != _eventListeners[i].f) continue;
if (obj.o != _eventListeners[i].o) continue;
return _eventListeners.splice(i, 1)[0].f;
}
}
public function dispatchEvent(evt:Event):Void
{
var i:Number = 0;
var l:Number = _eventListeners.length;
var obj:Object;
for (i = 0; i < l; i++)
{
if (evt.type != _eventListeners[i].e) continue;
evt.target = this;
_eventListeners[i].f.apply(_eventListeners[i].o, [evt.clone()]);
}
delete evt;
}
}
соответственно, наш класс, который собирается вещать события должен наследоваться от этого класса (если нужно наследоватьця от чего-то другого - прийдеться создавать в классе переменную типа ЕвентДиспатчер... понимаю, что не удобно, но опять же, писал для себя, мне не нужно было =)

Код:
/**
* ...
* @author wvxvw
*/
import utils.Utils
class events.Event
{
private var _target:Object = null;
private var _type:String = 'default';
public var className:String = 'Event';
public function Event(s:String)
{
if (s) _type = s;
}
public function clone():Event
{
var evt:Event = new Event(_type);
evt.target = _target;
return evt;
}
//------- get/set ------------//
public function set target(o:Object):Void
{
if (_target == null) _target = o;
}
public function get target():Object
{
return _target;
}
public function set type(s:String):Void
{
return;
}
public function get type():String
{
return _type;
}
public function toString():String
{
return Utils.formatToString(this, 'target', 'type');
}
}
соответственно, класс события, остальные события наследуются от этого.

Код:
/**
* ...
* @author wvxvw
*/
class utils.Utils
{
private static var CLASS_NAME:String = 'className';
public static function formatToString(o:Object):String
{
var i:Number = 1;
var l:Number = arguments.length;
var r_str:String = '[' + o[CLASS_NAME] + ' ';
for (i = 1; i < l; i++)
{
r_str += arguments[i] + '=' + o[arguments[i]] + ' ';
}
return r_str + ']';
}
public static function formatToStyle(o:Object):String
{
var skip:Array = arguments.slice(1, arguments.length);
var i:Number = skip.length;
var needSkip:Boolean = false;
var s:String;
var r_str:String = o[CLASS_NAME] + ' {';
for (s in o)
{
if (o[s] instanceof Function) continue;
if (s == CLASS_NAME) continue;
while (i--)
{
if (s == skip[i])
{
needSkip = true;
break;
}
}
i = skip.length;
if (needSkip) continue;
r_str += s + ':' + o[s] + '; ';
}
return r_str + '}';
}
}
это просто утилита для упрощения дебагинга, не обязательно ее использовать =) чтобы она работала, как задумано, в каждом классе должна быть переменная className типа String с названием этого самого класса.