![]() |
|
|
![]() |
![]() |
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
Регистрация: May 2016
Сообщений: 25
|
![]() Я думаю, ни для кого не секрет, что событийная система содержит серьезный изъян - она не гарантирует распространение событий в той очередности, в которой они были испущены в коде.
var s:Sprite = new Sprite(); s.name = "Parent"; s.addEventListener(Event.ADDED, this._onAdded); var schSprite:Sprite = new Sprite(); sch.name = "Child"; sch.addEventListener(Event.ADDED, this._onChildAdded); s.addChild(sch); __________________________________ function _onAdded(e:Event):void { var s:Sprite = e.target as Sprite; trace(e.type, s.name); } function _onChildAdded(e:Event):void { s.removeEventListener(e.type, this._onChildAdded); var s:Sprite = e.target as Sprite; var s2:Sprite = new Sprite(); s2.name = "subChild"; s.addChild(s2); } //output: //added, subChild //added, Child Да, зная, что событийная модель несовершенна, можно городить кучу проверок или, там где возможно, заранее выстраивать операции особым образом. Но меня интересует возможен ли фикс этого? Создаю событийную систему для моделей. Прикинул варианты: 1) В функции "dispathEvent" событие добавляется в глобальную очередь, и продолжается распространение события первого в очереди. Цитата:
2) Вместо "dispatchEvent" использовать "addToDispatchQueue(event:Event, callback:Function)". Цитата:
4) Ваш вариант |
|
|||||
Я делал CommandManager, в котором просто есть стэк команд, без всяких событий... Получается, что и callback особо не нужен, так как команде просто передается экземпляр "собственника события" (в числе прочих необходимых) и на .exec производятся все необходимые манипуляции.
Вообще, события не очень люблю.. Стараюсь использовать только когда это реально оправданно преимуществами баблинга, например.
__________________
while(live()) { hope(); } |
|
|||||
Регистрация: Oct 2006
Сообщений: 2,281
|
Насколько я помню события приходят в том порядке, в котором добовлялись слушатели т.е. путаница может случиться только если у тебя added и removed имеют одинаковый type что маловероятно. Можно минимальный пример когда события приходят не в том порядке?
|
|
|||||
4 аргумент - priority:
https://help.adobe.com/en_US/FlashPl...ventListener() Обычно таких зависимых событий немного, этого вполне хватает.
__________________
Дети не должны знать о своих родителях |
|
|||||
Lorem ipsum
|
В приведенном примере события отправляются совершенно упорядоченно: от самого вложенного (первое) до самого наружного (последнее).
Единственное, что приходится разруливать (я делал это... никогда) — это обработка одного и того же события от одного и того же объекта разными слушателями. В этом случае поможет комментарий от Tails.
__________________
Поймай яблоко 2! |
|
|||||
Регистрация: May 2016
Сообщений: 25
|
@ZergMaster, без минималистического примера - сложно понять. Что именно гарантирует, что во время выполнения одного стэка команд, не будет выполнен промежуточный стэк команд?
Цитата:
А чем пример в первом посте не угодил? Есть родитель, который сперва получает событие добавленного "внука", а потом событие добавленного "сына". Да, родитель знает, что добавляет ребенка по addChild, но если в цепь добавить "деда", то у него поедет крыша, ведь сперва он узнает, что у него есть "правнук", а уже потом узнает, что есть "внук". Мне кажется - это не нормально. Цитата:
Если я сказал собеседнику две фразы, я ожидаю, что сперва он услышит первую фразу, а затем вторую. Однако событийная система такова, что к слушателю "фразы" прилетают рандомно. Это как читать книгу, предложения в которой перемешаны в случайном порядке. Приведу пример, есть контроллер, который создает зеркальную иерархию от существующей иерархии. Он слушает BaseModel. Казалось бы, по "added" он создает зеркало-"узел" и крепит его к зеркало-родителю, ссылка на которого есть у event.target.parent (модель-эталон). Но проблема в том, что у parent - может не быть этой ссылки на зеркало, ведь он еще сам не имеет зеркального узла, потому что внутри addChild был вызван еще один addChild (в обработчике события "added"). Таким образом, я должен, понимая, что событийная система имеет изъян, искать в цепи parent первую "отзеркаленную" модельку и выстраивать иерархию от нее. Это же вынуждает меня проверять, а не был ли event.target "отзеркален" в предыдущем обработчике. Более того, в контроллер может прилететь другое важное событие от модельки (которое было испущено в ее обработчике "added") тогда как она сама еще не имеет зеркало, что существенно. Я понимаю, что можно не испускать событий в обработчике "added" и не добавлять детей там же. Но речь не про самоограничения, а про работу событий так, как это должно быть с точки зрения здравого смысла. |
|
|||||
Цитата:
__________________
местонахождение |
|
|||||
Регистрация: Oct 2006
Сообщений: 2,281
|
Цитата:
mc.addEventListener(MouseEvent.CLICK,onClick1,false); mc.addEventListener(MouseEvent.CLICK,onClick2,false); function onClick1(e:MouseEvent):void { trace("handler 1"); } function onClick2(e:MouseEvent):void { trace("handler 2"); } handler 1 handler 2 НО mc.addEventListener(MouseEvent.CLICK,onClick2,false); mc.addEventListener(MouseEvent.CLICK,onClick1,false); function onClick1(e:MouseEvent):void { trace("handler 1"); } function onClick2(e:MouseEvent):void { trace("handler 2"); } handler 2 handler 1 Для разруливания таких ситуаций и нужен параметр priority: mc.addEventListener(MouseEvent.CLICK,onClick2,false,0); mc.addEventListener(MouseEvent.CLICK,onClick1,false,1); function onClick1(e:MouseEvent):void { trace("handler 1"); } function onClick2(e:MouseEvent):void { trace("handler 2"); } handler 1 handler 2 т.к. у onClick1 приоритет больше чем у onClick2 У тебя налицо непонимание event flow. UI события идут от корня(stage) до элемента их испустившего(capture phase),после этого событие начинает "всплывать",двигаясь от ребенка назад к корню(bubbling phase).По дефолту ты ловишь события в фазе всплытия потому у тебя и путаница.Если нужно ловить события в capture phase используй 3-ий параметр у addEventListener. |
|
|||||
Регистрация: May 2016
Сообщений: 25
|
Цитата:
Моя архитектура не хочет ничего того, что не естественно. Для простоты освоения программирования к нему нередко приводят параллели с реальностью. Вот и я хочу, чтобы моя первая сказанная фраза всегда была услышана первой, а не как придется. Акцентирую, я не утверждаю, что текущие события никуда не годятся. Я ищу вариант улучшения, если он возможен. @undefined, теряюсь, что сказать. Я знаю, как работает priority... Если вы потратите чуть больше времени, чем "беглый взгляд", на изучение кода в первом посте, а так же на пример с "дедом" и "правнуком"/"внуком" позже - вы поймете, что я спрашиваю кардинально о другом. |
|
|||||
Регистрация: Oct 2006
Сообщений: 2,281
|
Цитата:
|
![]() |
![]() |
Часовой пояс GMT +4, время: 22:00. |
|
« Предыдущая тема | Следующая тема » |
|
|