Simple Event Controller
Запись от f.g.programmer размещена 05.01.2011 в 15:32
Обновил(-а) f.g.programmer 07.01.2011 в 00:42 (добавил применимость)
Обновил(-а) f.g.programmer 07.01.2011 в 00:42 (добавил применимость)
Simple Event Controller
Класс для упрощения работы с подпиской-отпиской обработчиков событий.
Пример использования
// создание объекта управляющего обработчиками, обычно в конструкторе _sec = new SEC(); // добавление обработчиков _sec.add(obj1, “event1”, event1Handler); _sec.add(obj1, “event2”, event2Handler); _sec.add(obj2, “event1”, event1Handler); _sec.add(obj2, “event2”, event2Handler); // добавление обработчика с дополнительными параметрами _sec.add(obj1, “event3”, Action.create(event3Handler, 42, “lev”)); private function event3Handler(e:Event, param1:int, param2:String):void { } // удаление конкретного обработчика _sec.remove(obj1, “event1”, event1Handler); // удаление всех обработчиков obj1, включая с дополнительными параметрами _sec.remove(obj1); // удаление всех обработчиков _sec.remove();
Применимость
1. Для упрощения отписки с защитой от дурака
т.е. вместо
url_loader.removeEventListener(IOErrorEvent.IO_ERROR, oErrorHandler); url_loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); url_loader.removeEventListener(ProgressEvent.PROGRESS, progressHandler); url_loader.removeEventListener(Event.COMPLETE, completeHandler);
// подписка _sec.add(url_loader, IOErrorEvent.IO_ERROR, oErrorHandler); _sec.add(url_loader, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); _sec.add(url_loader, ProgressEvent.PROGRESS, progressHandler); _sec.add(url_loader, Event.COMPLETE, completeHandler); // отписка _sec.remove(url_loader); // или, если контроль осуществляется только над одним объектом _sec.remove();
в процессе работы обработчики одного события могут меняться, т.е. в разных частях класса при разных условиях могут вызываться такие строки
// в одном месте button1.addEventListener(Mouse.CLICK, clickHandler1); button2.addEventListener(Mouse.CLICK, clickHandler2); // в другом месте button1.addEventListener(Mouse.CLICK, clickHandler2); button2.addEventListener(Mouse.CLICK, clickHandler1);
button1.removeEventListener (Mouse.CLICK, clickHandler1); button2.removeEventListener (Mouse.CLICK, clickHandler2); button1.removeEventListener (Mouse.CLICK, clickHandler2); button2.removeEventListener (Mouse.CLICK, clickHandler1);
// подписка _sec.add(button1, Mouse.CLICK, clickHandler1); _sec.add(button2, Mouse.CLICK, clickHandler2); _sec.add(button1, Mouse.CLICK, clickHandler2); _sec.add(button2, Mouse.CLICK, clickHandler1); // отписка _sec.remove();
пример, FD проект
Файл SEC.as
package { import flash.events.IEventDispatcher; import Action; public class SEC { private var _records:Vector.<SECRecord>; public function SEC() { _records = new Vector.<SECRecord>(); } /// добавление public function add(obj:IEventDispatcher, type:String, listener:Function, useCapture:Boolean = false, priority:int = 0):void { var rs:Vector.<SECRecord> = _records .filter(Action.create(isObject, obj)) .filter(Action.create(isType, type)) .filter(Action.create(isListener, listener)) .filter(Action.create(isUseCapture, useCapture)); if (rs.length == 0) { _records.push(new SECRecord(obj, type, listener, useCapture)); obj.addEventListener(type, listener, useCapture, priority, false); } } /// удаление public function remove(obj:IEventDispatcher = null, type:String = null, listener:Function = null, useCapture:* = undefined):void { var rs:Vector.<SECRecord> = _records.slice(); if (obj) { rs = rs.filter(Action.create(isObject, obj)); if (type) { rs = rs.filter(Action.create(isType, type)); if (listener != null) { rs = rs.filter(Action.create(isListener, listener)); if (useCapture is Boolean) { rs = rs.filter(Action.create(isUseCapture, useCapture as Boolean)); } } } } for each(var record:SECRecord in rs) { _records.splice(_records.indexOf(record), 1); record.obj.removeEventListener(record.type, record.listener, record.useCapture); } } private function isObject(item:SECRecord, index:int, vector:Vector.<SECRecord>, obj:IEventDispatcher):Boolean { return item.obj === obj; } private function isType(item:SECRecord, index:int, vector:Vector.<SECRecord>, type:String):Boolean { return item.type === type; } private function isListener(item:SECRecord, index:int, vector:Vector.<SECRecord>, listener:Function):Boolean { return item.listener === listener; } private function isUseCapture(item:SECRecord, index:int, vector:Vector.<SECRecord>, useCapture:Boolean):Boolean { return item.useCapture === useCapture; } } } import flash.events.IEventDispatcher; class SECRecord { public var obj:IEventDispatcher; public var type:String; public var listener:Function; public var useCapture:Boolean; public function SECRecord(obj:IEventDispatcher, type:String, listener:Function, useCapture:Boolean) { this.obj = obj; this.type = type; this.listener = listener; this.useCapture = useCapture; } }
Файл Action.as
package { public class Action { /// создание функуии с меньшим количеством параметров или без, подстановка в том же порядке в конец public static function create(fun:Function, ...params):Function { return new Action(fun, params).call; } private var _fun:Function; private var _args:Array; public function Action(fun:Function, args:Array) { _fun = fun; _args = (args) ? args.slice() : []; } public function call(...args):* { return _fun.apply(null, args.concat(_args)); } } }
Всего комментариев 13
Комментарии
05.01.2011 19:24 | |
Вот интересно. Те кто каждый день задаються вопросом "а как передать параметры в слушатель?", смогут понять этот код?)
А вообще, код весьма не плохой) |
05.01.2011 20:29 | |
И как долго писался код?
|
06.01.2011 01:57 | |
по-моему это пятое колесо.
|
06.01.2011 03:51 | |
дуализм: "чистый ооп" / "да задолбали эти абстракции - лучше сделать как быстрее".
Выбор программиста (не кодера) - по конкретной задаче. Кодер должен выбирать ООП. Дао сложен, и понять себя программистом, но не кодером есть дао. ps считаю себя на пути к дао, но никак не познавшим)))) |
|
Обновил(-а) Котяра 06.01.2011 в 03:55
|
06.01.2011 12:36 | |
Мне не нравится, что на каждое добавление/удаление надо гарантированно 4 раза обойти этот вектор. А он может быть не маленький.
|
06.01.2011 16:25 | |
Недурно.
|
06.01.2011 20:25 | |
Не нужно.
|
Последние записи от f.g.programmer
- Simple Event Controller (05.01.2011)
- Event (16.10.2010)
- ActionScript 3.0. Правила именования. (25.09.2010)