Показать сообщение отдельно
Старый 01.06.2008, 17:16
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 15  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Цитата:
Сообщение от 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 с названием этого самого класса.
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 02.06.2008 в 14:11.