Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Гонки при создании "классовых" ENUM'ов (http://www.flasher.ru/forum/showthread.php?t=183207)

fljot 15.08.2012 11:58

Гонки при создании "классовых" ENUM'ов
 
Есть такой класс GestureState, по сути — ENUM:
Код AS3:

public class GestureState
{
        public static const IDLE:GestureState = new GestureState(1 << 0, "IDLE");
        public static const POSSIBLE:GestureState = new GestureState(1 << 1, "POSSIBLE");
        public static const RECOGNIZED:GestureState = new GestureState(1 << 2, "RECOGNIZED");
        public static const BEGAN:GestureState = new GestureState(1 << 3, "BEGAN");
        public static const CHANGED:GestureState = new GestureState(1 << 4, "CHANGED");
        public static const ENDED:GestureState = new GestureState(1 << 5, "ENDED");
        public static const CANCELLED:GestureState = new GestureState(1 << 6, "CANCELLED");
        public static const FAILED:GestureState = new GestureState(1 << 7, "FAILED");
 
        private static const endStatesBitMask:uint =
                GestureState.CANCELLED.toUint() |
                GestureState.RECOGNIZED.toUint() |
                GestureState.ENDED.toUint() |
                GestureState.FAILED.toUint();
 
        private static var allStatesInitialized:Boolean;
 
 
        private var value:uint;
        private var name:String;
        private var validTransitionsBitMask:uint;
 
        {
                _initClass();
        }
 
 
        public function GestureState(value:uint, name:String)
        {
                if (allStatesInitialized)
                {
                        throw new IllegalOperationError("You cannot create gesture states." +
                        "Use predefined constats like GestureState.RECOGNIZED");
                }
 
                this.value = value;
                this.name = name;
        }
 
 
        private static function _initClass():void
        {
                IDLE.setValidNextStates(POSSIBLE);
                POSSIBLE.setValidNextStates(RECOGNIZED, BEGAN, FAILED);
                RECOGNIZED.setValidNextStates(IDLE);
                BEGAN.setValidNextStates(CHANGED, ENDED, CANCELLED);
                CHANGED.setValidNextStates(CHANGED, ENDED, CANCELLED);
                ENDED.setValidNextStates(IDLE);
                FAILED.setValidNextStates(IDLE);
                CANCELLED.setValidNextStates(IDLE);
 
                allStatesInitialized = true;
        }
 
 
        public function toString():String
        {
                return "GestureState." + name;
        }
 
 
        public function toUint():uint
        {
                return value;
        }
 
 
        private function setValidNextStates(...states):void
        {
                var mask:uint;
                for each (var state:GestureState in states)
                {
                        mask = mask | state.value;
                }
                validTransitionsBitMask = mask;
        }
 
 
        gestouch_internal function canTransitionTo(state:GestureState):Boolean
        {
                return (validTransitionsBitMask & state.value) > 0;
        }
 
 
        gestouch_internal function get isEndState():Boolean
        {
                return (endStatesBitMask & value) > 0;
        }
}

Захотелось мне это сделать чуть-чуть покрасивее и попроизводительнее примерно таким образом:
Код AS3:

// GestureState.as
public static const IDLE:GestureState = new IdleGestureState(1 << 0);
 
// IdleGestureState.as
internal class IdleGestureState extends GestureState
{
        public function IdleGestureState(value:uint)
        {
                super(value, "IDLE");
        }
 
 
        override public function canTransitionTo(nextState:GestureState):Boolean
        {
                return nextState is PossibleGestureState;
        }
 
 
        // по необходимости
        override public function get isEndState():Boolean
        {
                return false;
        }
}

Но возникает RTE при попытке создания такого вот класса-наследника. Дело в том, что базовый класс GestureState на момент создания сабкласса ещё не совсем определён (т.к. сабкласс пытаемся создать для static поля базового).

Варианты решения:
1. public static var ...
2. public static function get ...
3. класс GestureStates, в котором в свою очередть прописаны константы.

Ни одно из решений не нравится. Может ещё есть какие-то трюки?

dimarik 16.08.2012 00:24

По сути все "трюки" регулируют очередность появления (упоминания) класса в рантайме.


Часовой пояс GMT +4, время: 11:29.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.