PDA

Просмотр полной версии : Алгоритмы Единичное реагирование на событие мыши.


iaf
26.08.2014, 21:00
Имеется Class1 и его наследник Class2.

Оба эти класса могут быть добавлены в список отображения в любой последовательности, любом количестве и любой степени вложенности из этих двух классов.

Class2 слушает событие мыши (свое или детей) и принимает определенный статус. Поскольку Class2 не знает какие у него дети (и дети детей) - все Class2 слушают событие мыши.

Задача: добиться того, чтобы первый попавшийся родитель Class2 (или сам Class2, если он был целью события) отработал метод (получал статус). А все следующие за ним выше - проигнорировали. При чем иметь статус одновременно может только один экземпляр Class2.

- останавливать эвент нельзя.
- подгонять Class1 под нужды Class2 нельзя. Не хочется городить в предке код, который ему не нужен.
- полностью заявить о полученном статусе ближайший Class2 может только в обработчике события. Никаких setinterval, timer, enterFrame etc

У меня есть несколько "костыльных" вариантов вроде: ближайший Class2 загоняет в internal переменную Class2.gotStatus = true, потом он и все последующие смотрят своих родителей, и если среди них больше нет экземпляра Class2 - устанавливают Class2.gotStatus = false.

Но, думается, есть разумный и простой вариант, которого я пока не вижу.

silin
26.08.2014, 23:42
if (event.target == event.currentTarget)
{
// обрабатываем
}

iaf
26.08.2014, 23:58
тогда уж
if (event.eventPhase === EventPhase.AT_TARGET)
{
// обрабатываем
}

дешевле на геттер.
Но не подходит. Экземпляры Class1 также могут быть целью события, а получить статус должен экземпляр Class2, стоящий выше (если он, конечно, вообще есть).

silin
27.08.2014, 00:25
>>Экземпляры Class1 также могут быть целью события, а получить статус должен экземпляр Class2

тогда остается только 'вручную всплыть' до ближайшего Class2
var targ:DisplayObject = event.target as DisplayObject;
while (targ != stage)
{
if (targ is Class2)
{
if (targ == event.currentTarget)
{

// обрабатываем
}
break;
}
targ = targ.parent;

}

iaf
27.08.2014, 01:07
if (targ == event.currentTarget)
честно говоря, не понял для чего идет эта проверка.

Но не суть. Видимо, предполагается прописать в Class1 (предке) ручное "всплытие" до Class2 (наследника). А это уже:
- подгонять Class1 под нужды Class2 нельзя. Не хочется городить в предке код, который ему не нужен.

Немного акцентирую. Все экземпляры Class2 должны слушать мышь, ибо находиться они могут на любом участке иерархии, а Class1 может быть как одним из детей экземпляра Class2, так и его родителем. Только один экземпляр Class2, ближайший к цели события, может быть в фокусе (иметь статус, который отбирается у предыдущего владельца).
Ключевая проблема: как-то "очевидно" заставить все, оставшиеся в цепи родителей, экземпляры Class2 не реагировать на всплывающий мышиный эвент (который уже отработал на нижестоящем Class2)

silin
27.08.2014, 01:21
не, все происходит в обработчике Class2
эта та же самая проверка, только вместо e.target (которым может быть Class1, например, или вообще Sprite) смотрим вверх по дисплейЛисту до первого Class2 , если он и есть подписант, то ему и карты в руки, а остальные получатели события не у дел

Nooob
27.08.2014, 01:24
я думаю нужно подписаться у всех Class2 на фазу захвата, последний кто принял это событие на фазе захвата будет первым кто получит событие на целевой фазе из всех Class2 и Class1 и дальше от этого прыгать. фаза захвата обратная фазе всплытия и отрабатывается первой

iaf
27.08.2014, 01:33
я думаю нужно подписаться у всех Class2 на фазу захвата
Хорошая мысль. Однако используется сторонний фреймворк, у которого фазы захвата нет.

не, все происходит в обработчике Class2
В сущности да - вариант. Пока на нем и остановлюсь, если не будет еще идей. Спасибо!