Всякие разные штуки сомнительной полезности сделанные в свободное от работы время.
Система сигнал-слот в AS3
Продолжительные попытки оптимизировать работу событий в AS3 привели к написанию этой небольшой библиотеки.
В чем заключаются отличия от штатного EventDispatcher и Event.
- Вызов колбека (хендлера, он же слот) не сопровождается созданием нового, зачастую не нужного объекта - события.
- Типы "событий" заранее извесны, никаких "непредвиденых событий" объекты диспатчить не могут. Аналогично, нельзя подписаться на несуществующее "событие".
- Колбеку можно задать типы и количество принимаемых параметров.
- Реализация аналогов target, currentTarget, stopPropagation, handled оставлена "на откуп" программисту использующему библиотеку т.е. захотите - добавьте.
- Аналог useCapture не возможен в силу специфики реализации.
Не стоит пытаться заменить нативные события, т.как это будет явно непродуктивно. Ну и не стоит использовать в небольших проектах, в которых количество вещаемых событий не на столько велико, чтобы повлиять на продуктивность. Возможно, не до конца идеально продумана реализация (на уровне интерфейса), так что возможны доработки.
Пример использования:
package signals { //{ imports import flash.display.Sprite; import org.wvxvws.signals.ISemaphore; import org.wvxvws.signals.SignalError; import org.wvxvws.signals.Signals; //} /** * TestAsteriscNamespace class. * @author wvxvw * @langVersion 3.0 * @playerVersion 10.0.32 */ public class SignalsExample extends Sprite implements ISemaphore { //-------------------------------------------------------------------------- // // Public properties // //-------------------------------------------------------------------------- public static const FOO:Vector.<Class> = new <Class>[int]; public static const BAR:Vector.<Class> = new <Class>[String, int]; /* INTERFACE org.wvxvws.signals.ISemaphore */ public function get signals():Signals { return this._signals; } //-------------------------------------------------------------------------- // // Protected properties // //-------------------------------------------------------------------------- protected var _signals:Signals; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- public function SignalsExample() { super(); this._signals = new Signals(this); this._signals.add(FOO, this.slotTest3); this._signals.add(BAR, this.slotTest); this._signals.add(BAR, this.slotTest2); this._signals.call(BAR, "Foo", 100); this._signals.call(FOO, 200); try { this._signals.call(FOO, "Foo", 100); } catch (error:SignalError) { // Attempting to call slot with wrong signature. trace(error.message); } } //-------------------------------------------------------------------------- // // Public methods // //-------------------------------------------------------------------------- /* INTERFACE org.wvxvws.signals.ISemaphore */ public function signalTypes():Vector.<Vector.<Class>> { return new <Vector.<Class>>[FOO, BAR]; } //-------------------------------------------------------------------------- // // Private methods // //-------------------------------------------------------------------------- private function slotTest(par0:String, par1:int):void { trace("slotTest called", par0, par1); } private function slotTest2(par0:String, par1:int):void { trace("slotTest2 called", par0, par1); } private function slotTest3(par1:int):void { trace("slotTest3 called", par1); } } }
http://code.google.com/p/e4xu/source...wvxvws/signals
EDIT: Немножко упростил и почистил АПИ.
Всего комментариев 61
Комментарии
07.02.2010 15:35 | |
07.02.2010 17:15 | |
Это просто короткая запись Vector.<T>([массив который нужно конвертнуть]); Так можно писать начиная со второй беты 4-го СДК.
|
07.02.2010 17:28 | |
07.02.2010 19:03 | |
http://bugs.adobe.com/jira/browse/ASC-3695
Это когда заимплементили. http://blog.flexexamples.com/2009/06...rol-in-flex-4/ Это пример с объяснением. |
09.04.2010 23:41 | |
А можно пример с разницей, пожалуйста - чет я недогоняю
|
10.04.2010 13:28 | |
Да, можно и пример:
http://code.google.com/p/hxhsl/sourc...atcher.as?r=65 |
16.04.2010 12:45 | |
Нашёл библиотеку от Robert Penner
http://wiki.github.com/robertpenner/as3-signals/ тут видео-туториал |
16.04.2010 16:59 | |
Да, есть такая, в тесте по ссылке выше именно она и используется, но есть еще много разных. Вот, самая простая:
http://github.com/stroncium/hx-signals Например. |
16.04.2010 17:52 | |
ага. вижу:
Цитата:
* EventDispatcer addEventListener (priority) 38
* EventDispatcer dispatchEvent 1 * Signals add (priority) 5 * Signals call 4 * DeluxeSignal add (priority) 170 * DeluxeSignal dispatch 1 и еще: имя метода signals.call - не логичнее ли было назвать dispatсh? Да и класс наверное Signal а не Signals. Конечно хозяин-барин.. это я так.. мимо проходил.. А вообще очень здорово. Как я понял - чтобы сигнализировать сигналы ( о-как!) не надо быть никаким eventDispatcher'om достаточно завести в классе этот сигнал.. очень подходит. Будем брать.. |
|
Обновил(-а) Котяра 16.04.2010 в 17:56
|
02.07.2010 00:21 | |
А как, например, обстоит дело с зависшими хэндлерами?
someMethod всё равно будет вызываться... Или в системе сигналов так лучше не делать? Хотя можно конечно делать так: Хотя с обычными событиями так же дела обстоят... |
|
Обновил(-а) Cybo 02.07.2010 в 00:49
|
02.07.2010 01:53 | |
Ну, собственно никаких изобретений в этом плане не было - все на совести пользователя, и подписка и отписка.
|
12.07.2010 16:15 | |
12.07.2010 17:23 | |
Про это уже есть в 7-м комментарии...
|
12.07.2010 17:29 | |
вот еще плюс тесты
http://cjcat.blogspot.com/2010/07/cj...framework.html |
12.07.2010 22:57 | |
Котяра, дык в том и проблема. я не смогу одним хендлером 20 сигналов разных споймать. что ещё хуже, мне надо знать сигнатуру каждого сигнала. ну и ещё куча проблем с target и т.д.
|
|
Обновил(-а) BlooDHounD 13.07.2010 в 00:23
|
12.07.2010 23:06 | |
BlooDHounD - это не плохо, это наоборот, желаемый еффект.
|
12.07.2010 23:39 | |
Открой вижуал студио 2005, создай в дизайнере 20 кнопок и подпишись ко всем на событие Click.
|
12.07.2010 23:45 | |
Ну вообще, да - таргет и куррент таргет - довольно полезные изобретения as3 (пруф?)
Ничто не мешает сделать базовые сигналы с ними, если так они нравятся. Как переделывать чужие - другой вопрос. в том же сишарпе таргет есть, только он более логично называется sender |
|
Обновил(-а) Котяра 13.07.2010 в 00:04
|
12.07.2010 23:51 | |
Котяра, поправь меня, если я не правильно понял твой код:
тут e - это объект на подобие MouseEvent в АС3, но без таргет, который передан отдельно? |
12.07.2010 23:54 | |
Обновил(-а) Котяра 13.07.2010 в 00:12
|
12.07.2010 23:55 | |
то есть никто кроме меня не замечает парадокса?
|
13.07.2010 00:03 | |
MouseEventArguments - просто обёртка для большого количества мышиных данных.
очень часто достаточно одного sender. |
13.07.2010 00:25 | |
wvxvw, забавно. так принято...
|
13.07.2010 00:25 | |
да, ничего сверхреволюционного нет, кроме основного аргумента:
Цитата:
Типы "событий" заранее известны, никаких "непредвиденых событий" объекты диспатчить не могут. Аналогично, нельзя подписаться на несуществующее "событие".
в ас2 были удобными onRelease, onMouseMove итп.. но проблема была с единчтвенностью хэндлера, делегацией хэндлеров и передачей в хэндлеры параметров. В сигналах эти проблемы решены. |
|
Обновил(-а) Котяра 13.07.2010 в 00:31
|
13.07.2010 00:36 | |
пнятно.
|
13.07.2010 00:37 | |
>> забавно. так принято...
Именно так, мне попадались проекты, которые эту схему впринципе не использовали. Как бы во фреймворке просто существует возможность объявить событие как событие - это позволяет самому не перегружать операторы += и -=, ну и вообще просто будет понятно незнакомому человеку, но это не догма. Когда ты оформляешь событие, ты создаешь делегата, который описывает, что ты будешь в слушателя передавать, и цикл раздающий событие. Это немного больше в плане самостоятельной реализации, чем в AS3, но с другой стороны - все равно делается по шаблону, так что никто об этом сильно не заморачивается. Что касается содержания аргументов (EventArgs) - у этого класса нет никаких свойств, свойства объявляют только наследники. Кстати, из интереснын вещей, можно оверлоадить [] у EventArgs: Код:
public object this[int i] { get { return realArguments[i]; } set { realArguments[i] = value; } } |
|
Обновил(-а) wvxvw 13.07.2010 в 00:44
|
13.07.2010 00:42 | |
ну еще один плюс - приватные события(сигналы)
|
13.07.2010 01:00 | |
wvxvw, ничего интересного в перегрузки операторов не замечаю. к тому же rest можно в сигналах сделать и без EventArgs, на сколько я понимаю.
Котяра, приватные события? |
13.07.2010 01:12 | |
Котяра, честно говоря для меня тут всё попахивает костыльным маразмом ) ты своими приватными сигналами только укрепляешь мою уверенность.
|
13.07.2010 02:21 | |
Ладно) Насорили изрядно уже нашим триалогом тут..
но еще чуток: Цитата:
мне в 90% случаев нужен target.
Цитата:
мне в 90% случаев нужно одним слушателем ловить много событий ( причём не обязательно одних и тех же )
кстати а как это с эвентами происходит? Цитата:
public function someEventListener(e:Event)?
Цитата:
. мне в 20 процентах случаев нужны приоритеты
Цитата:
и мне никогда не надо приватные события
Цитата:
единственный недостаток это необходимость описывать метаданными события.
Я не настаиваю, просто сигналы хорошая и зарекомендовавшая себя в с# идея. Для меня, как я уже повторяю в третий раз - главный недостаток применения сигналов в реальном проекте - необходимость поддержки двух систем событий. ЗЫ: вот еще "для почитать" http://flashblog.robertpenner.com/20...rned-from.html |
|
Обновил(-а) Котяра 13.07.2010 в 02:25
|
13.07.2010 02:57 | |
Цитата:
Котяра, с евентами кроме как евент придти ничего не может. а вот у сигналов может быть что угодно. неизвестно количество агрументов и их тип. неужели это так не ясно?
кто конкретно скажет какая сигнатура у func? только то что она принимает Эвент? А какой эвент? Маус,кастомный или еще какой? неизвестно. Это проблема АС3 а не конкретно сигналов. Да что такое эвент? по сути это пустой нетизированный объект с таргетом (как ты сам говорил).. Да и тот же ФД сгенерит хэндлер конкретного сигнала на раз (при написании соответствующего несложного плагина).. Цитата:
я не понимаю почему у тебя хэндлеры паблик.
Цитата:
событие внутри класса, ведь хэндлер всегда будет один
|
|
Обновил(-а) Котяра 13.07.2010 в 02:59
|
Последние записи от wvxvw
- Dired - текстовый проводник по файловой системе (29.06.2013)
- Навигация по HTML с WASD (09.06.2012)
- JavaScript, все не так плохо (07.06.2012)
- Что такое tarball и чем его пакуют (11.04.2012)
- Критика Presentation Model (18.02.2012)