Показать сообщение отдельно
Старый 14.06.2018, 02:37
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 16  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
robotR2D2, Ну ты же сам написал, что события распространяются "абы как". А сейчас пишешь, что они распространяются так, как попадают в стек. Это же не "абы как". Мне самому во многом не нравится флешевская событийная модель. Преимущественно из-за строковых типов событий и также по той причине, что ты здесь описал. Но это не изъян, просто это сделано так, как сделано. Всем не угодишь. Вот то, что в OpenFl, который ты привел, события будут вызываться по разному в зависимости от таргета - вот это изъян. А во флеше все предсказуемо и логично. То, что оно работает не так, как тебе надо, не значит, что оно работает плохо.

По существу могу сказать, что в свое время я реализовывал фичу с упорядоченным распространением событий через очередь. Ничего более толкового придумать тогда не смог, да и работает вроде бы не плохо.

Код на Haxe:

Код AS3:
    public function dispatch(event:EVENT) {
        if (_isDispatching) {
            _queue.push(event);
        }
        else {
            _isDispatching = true;
            while (event != null) {
 
                var next = _head;
 
                while (next != null) {
                    var listener = next.listener;
                    next = next.next;
 
                    if(listener.enabled) {
                        switch (listener.comparisonMethod) {
                            case ListenerFlags : if ((event.bitmask & listener.bitmask) == listener.bitmask) listener.handler(event);
                            case EventFlags : if ((event.bitmask & listener.bitmask) == event.bitmask) listener.handler(event);
                            case AnyFlags : if ((event.bitmask & listener.bitmask) > 0) listener.handler(event);
                        }
                    }
 
                    if (listener.isDestroyed) removeListener(listener);
                }
 
                event = _queue.shift();
            }
            _isDispatching = false;
        }
    }
 
    public function dispatchChain(chain:Array<EVENT>) {
        for (event in chain) _queue.push(event);
        if (!_isDispatching) dispatch(_queue.shift());
    }