Exemplo n.º 1
0
            /// <summary>
            /// Key input hander for this state
            /// </summary>
            /// <param name="keyCode">Key code</param>
            /// <param name="press">Key is pressed or not</param>
            /// <param name="result">Output of this state</param>
            /// <param name="currentTime">Current time</param>
            /// <returns>Next state</returns>
            public override State Handle(int keyCode, bool press, List <int> result, long currentTime)
            {
                if (press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key pressed. Go to Oyayubi Key state.
                    _lsOrRs        = (keyCode == _lsKeyCode) ? _lsKeyCode : _rsKeyCode;
                    _timeLsOrRsKey = currentTime;
                    return(StateLsOrRs.Instance());
                }
                else if (!press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key released. Can ignore
                    return(Instance());
                }
                else if (press)
                {
                    // Char Key pressed. Go to Char state.
                    _keyCode     = keyCode;
                    _timeCharKey = currentTime;
                    return(StateChar.Instance());
                }
                else if (!press)
                {
                    // Char Key released. Can ignore.
                    return(Instance());
                }

                // Unknown
                return(null);
            }
Exemplo n.º 2
0
 /// <summary>
 /// Get instance
 /// </summary>
 /// <returns>Instance</returns>
 public static State Instance()
 {
     if (_instance == null)
     {
         _instance = new StateChar();
     }
     return(_instance);
 }
Exemplo n.º 3
0
            /// <summary>
            /// Key input hander for this state
            /// </summary>
            /// <param name="keyCode">Key code</param>
            /// <param name="press">Key is pressed or not</param>
            /// <param name="result">Output of this state</param>
            /// <param name="currentTime">Current time</param>
            /// <returns>Next state</returns>
            public override State Handle(int keyCode, bool press, List <int> result, long currentTime)
            {
                if (press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    if (keyCode == _lsOrRs)
                    {
                        // The same Oyayubi Key pressed. Can ignore
                        return(StateLsOrRs.Instance());
                    }

                    // Opposite Oyayubi Key pressed
                    // No rule -> Update Oyayubi Key

                    int oldOfs = keyCode;
                    keyCode = _lsOrRs;

                    _lsOrRs        = (oldOfs == _lsKeyCode) ? _lsKeyCode : _rsKeyCode;
                    _timeLsOrRsKey = currentTime;
                    return(StateLsOrRs.Instance());
                }
                else if (!press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key released

                    // Back to initial state
                    keyCode = _lsOrRs;
                    return(StateNone.Instance());
                }
                else if (press)
                {
                    // Char key pressed

                    _timeCharKey = currentTime;
                    _keyCode     = keyCode;

                    if (_timeCharKey - _timeLsOrRsKey > _threshold)
                    {
                        // Rule 1-1'. Oyayubi ON -> Timeout

                        keyCode = _lsOrRs;

                        // Go to Char Key state
                        return(StateChar.Instance());
                    }

                    // Rule 2-1. Oyayubi ON + Char ON -> Char with Oyayubi
                    return(StateLsOrRsWithChar.Instance());
                }
                else if (!press)
                {
                    // Char Key released. Can ignore
                    return(StateLsOrRs.Instance());
                }

                // Unknown
                return(null);
            }
Exemplo n.º 4
0
        private Token GetChar()
        {
            StateChar state = StateChar.START;
            Char      c     = '\0';

            Next();
            var    invalidChars             = new HashSet <Char>("\'\n");
            string escapeChars              = @"abfnrtv'""\";
            string correspondingEscapeChars = "\a\b\f\n\r\t\v\'\"\\";
            Token  result = null;
            int    length = 0;

            while (true)
            {
                switch (state)
                {
                case StateChar.START:
                    c = Next();
                    switch (c)
                    {
                    case '\\':
                        state = StateChar.S;
                        break;

                    default:
                        if (invalidChars.Contains(c))
                        {
                            state = StateChar.FAILED;
                        }
                        else
                        {
                            state = StateChar.C;
                        }
                        break;
                    }

                    break;

                case StateChar.C:
                    result = Token.GetCharToken(c, lexemeBegin, length + 2);
                    c      = Next();
                    if (c == '\'')
                    {
                        state = StateChar.FINISH;
                    }
                    else
                    {
                        state = StateChar.FAILED;
                    }
                    break;

                case StateChar.S:
                    c = Next();
                    if (escapeChars.Contains(c))
                    {
                        c     = correspondingEscapeChars[escapeChars.IndexOf(c)];
                        state = StateChar.C;
                    }
                    else
                    {
                        state = StateChar.FAILED;
                    }
                    break;

                case StateChar.FINISH:
                    return(result);

                case StateChar.FAILED:
                    ErrorMessage.Add($"Character Parse failed when meeting '{c}'. ");
                    return(Token.GetErrorToken(lexemeBegin, length + 1));
                }
                length++;
            }
        }
Exemplo n.º 5
0
            /// <summary>
            /// Key input hander for this state
            /// </summary>
            /// <param name="keyCode">Key code</param>
            /// <param name="press">Key is pressed or not</param>
            /// <param name="result">Output of this state</param>
            /// <param name="currentTime">Current time</param>
            /// <returns>Next state</returns>
            public override State Handle(int keyCode, bool press, List <int> result, long currentTime)
            {
                if (press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    if (keyCode == _lsOrRs)
                    {
                        // The same Oyayubi Key pressed. Can ignore
                        return(StateLsOrRsWithChar.Instance());
                    }

                    // Opposite Oyayubi Key pressed
                    // (Char Key with Oyayubi Key1) + (Oyayubi Key2)

                    // Either of:
                    // Rule 2-1. Oyayubi ON + Charl ON -> Char with Oyayubi
                    // Rule 2-2. Char ON + Oyayubi ON -> Char with Oyayubi

                    // Set Oyayubi Key flag to Char Key
                    int oldOfs = keyCode;
                    keyCode  = _keyCode;
                    keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                    result.Add(keyCode);

                    // Go to Oyayubi Key2 state
                    _lsOrRs        = (oldOfs == _lsKeyCode) ? _lsKeyCode : _rsKeyCode;
                    _timeLsOrRsKey = currentTime;
                    return(StateLsOrRs.Instance());
                }
                else if (!press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key released

                    // Either of:
                    // Rule 2-1. Oyayubi ON + Charl ON -> Char with Oyayubi
                    // Rule 2-2. Char ON + Oyayubi ON -> Char with Oyayubi

                    // Set Oyayubi Key flag to Char Key
                    keyCode  = _keyCode;
                    keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                    result.Add(keyCode);

                    // Back to initial state
                    return(StateNone.Instance());
                }
                else if (press)
                {
                    // Char Key pressed

                    if (_timeLsOrRsKey < _timeCharKey)
                    {
                        // (Oyayubi Key with Char Key1) + (Char Key2)

                        // Rule 2-1. Oyayubi ON + Charl ON -> Char with Oyayubi
                        // Set Oyayubi Key flag to Char Key1
                        int tmp = keyCode;
                        keyCode  = _keyCode;
                        keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                        result.Add(keyCode);

                        _timeCharKey = currentTime;
                        _keyCode     = tmp;

                        // Go to Char Key2 state
                        return(StateChar.Instance());
                    }
                    else
                    {
                        long time = currentTime;
                        if (time - _timeLsOrRsKey > _threshold)
                        {
                            // Rule 1-1'. Oyayubi ON -> Timeout (with Char Key2)

                            // Set Oyayubi Key flag to Char Key1
                            int tmp = keyCode;
                            keyCode  = _keyCode;
                            keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                            result.Add(keyCode);

                            _timeCharKey = currentTime;
                            _keyCode     = tmp;

                            // Go to Char Key2 state
                            return(StateChar.Instance());
                        }

                        // Rule 3-1. Char1 ON + Oyayubi ON + Char2 ON
                        // We have to determine which Char Key the Oyayubi Key is attached to.

                        if (_timeLsOrRsKey - _timeCharKey <= time - _timeLsOrRsKey)
                        {
                            // Rule 3-1a. If (t(Oyayubi) - T(Char1)) <= (t(Char2) - T(Oyayubi)), Char1 with Oyayubi

                            // Set Oyayubi Key flag to Char Key1
                            int tmp = keyCode;
                            keyCode  = _keyCode;
                            keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                            result.Add(keyCode);

                            _timeCharKey = currentTime;
                            _keyCode     = tmp;

                            // Go to Char Key2 state
                            return(StateChar.Instance());
                        }
                        else
                        {
                            // Rule 3-1b. If (t(Oyayubi) - T(Char1)) > (t(Char2) - T(Oyayubi)), Char2 with Oyayubi

                            // Do not set Oyayubi Key flag to Char Key1
                            int tmp = keyCode;
                            keyCode = _keyCode;
                            result.Add(keyCode);

                            // Go to Char Key2 with Oyayubi Key state
                            _timeCharKey = time;
                            _keyCode     = tmp;
                            return(StateLsOrRsWithChar.Instance());
                        }
                    }
                }
                else if (!press)
                {
                    // Char Key released

                    if (keyCode != _keyCode)
                    {
                        // Unrelated Char released. Can ignore
                        return(StateLsOrRsWithChar.Instance());
                    }

                    // Either of:
                    // Rule 2-1. Oyayubi ON + Charl ON -> Char with Oyayubi
                    // Rule 2-2. Char ON + Oyayubi ON -> Char with Oyayubi

                    // Set Oyayubi Key flag to Char Key
                    keyCode  = _keyCode;
                    keyCode |= (int)(_lsOrRs == _lsKeyCode ? WTKeyCode.Custom1 : WTKeyCode.Custom2);
                    result.Add(keyCode);

                    // Back to initial state
                    return(StateNone.Instance());
                }

                // Unknown
                return(null);
            }
Exemplo n.º 6
0
            /// <summary>
            /// Key input hander for this state
            /// </summary>
            /// <param name="keyCode">Key code</param>
            /// <param name="press">Key is pressed or not</param>
            /// <param name="result">Output of this state</param>
            /// <param name="currentTime">Current time</param>
            /// <returns>Next state</returns>
            public override State Handle(int keyCode, bool press, List <int> result, long currentTime)
            {
                if (press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key pressed.
                    _timeLsOrRsKey = currentTime;
                    if (_timeLsOrRsKey - _timeCharKey > _threshold)
                    {
                        // Rule 1-1. Char ON -> Timeout

                        // Process Char Key
                        int oldOfs = keyCode;
                        keyCode = _keyCode;
                        result.Add(keyCode);

                        // Go to Oyayubi Key state
                        _lsOrRs        = (oldOfs == _lsKeyCode) ? _lsKeyCode : _rsKeyCode;
                        _timeLsOrRsKey = currentTime;
                        return(StateLsOrRs.Instance());
                    }

                    // Rule 2-2. Char ON + Oyayubi ON -> Char with Oyayubi
                    _lsOrRs = (keyCode == _lsKeyCode) ? _lsKeyCode : _rsKeyCode;
                    return(StateLsOrRsWithChar.Instance());
                }
                else if (!press && (keyCode == _rsKeyCode || keyCode == _lsKeyCode))
                {
                    // Oyayubi Key released. Can ignore
                    return(StateChar.Instance());
                }
                else if (press)
                {
                    if (keyCode == _keyCode)
                    {
                        // The same Char Key pressed. Can ignore
                        return(StateChar.Instance());
                    }

                    // Rule 1-3. Char1 ON -> Char2 ON -> Char1

                    // Process Char Key1
                    int tmp = keyCode;
                    keyCode = _keyCode;
                    result.Add(keyCode);

                    // Char Key2 pressed. Go to Char state.
                    _timeCharKey = currentTime;
                    _keyCode     = tmp;
                    return(StateChar.Instance());
                }
                else if (!press)
                {
                    if (keyCode != _keyCode)
                    {
                        // Unrelated Char released. Can ignore
                        return(StateChar.Instance());
                    }

                    // Rule 1-2. Char ON -> Char OFF -> Char

                    // Process Char Key
                    keyCode = _keyCode;
                    result.Add(keyCode);

                    // Back to initial state
                    return(StateNone.Instance());
                }

                // Unknown
                return(null);
            }
        public void LoadSpec(string specStr)
        {
            AddAction(new State(0, '0'), new Action(0, '0', Direction.R));

            int    pos = 0, oldPos = 0;
            uint   currState = 0;
            char   currInput = '1';
            string spec      = specStr + "110";          // "110" removed for 'optimization', so

            // add it back
            while (pos < spec.Length)
            {
                var dir = Direction.Undef;
                int dirPos = 0x7FFFFFFF, matchLen = 0;

                // find first direction
                Match match = _stopRegex.Match(spec, pos);
                if (match.Success)
                {
                    dir      = Direction.Stop;
                    dirPos   = match.Index;
                    matchLen = match.Length;
                }
                match = _leftRegex.Match(spec, pos);
                if (match.Success && match.Index < dirPos)
                {
                    dir      = Direction.L;
                    dirPos   = match.Index;
                    matchLen = match.Length;
                }
                match = _rightRegex.Match(spec, pos);
                if (match.Success && match.Index < dirPos)
                {
                    dir      = Direction.R;
                    dirPos   = match.Index;
                    matchLen = match.Length;
                }

                if (dir == Direction.Undef)
                {
                    throw new SpecLoadException(spec.Substring(pos, 20));
                }

                pos = dirPos;
                StateChar sc = GetStateAndChar(spec.Substring(oldPos, pos - oldPos));

                var s = new State(currState, currInput);
                var a = new Action(sc.State, sc.C, dir);

                AddAction(s, a);

                pos      += matchLen;
                oldPos    = pos;
                currInput = (currInput == '0' ? '1' : '0');
                if (currInput == '0')
                {
                    currState++;
                }
            }

            _specLoaded = true;
        }