public IState <SynchroGazerStatus> Update(SynchroGazerStatus source)
        {
            if (!source.IsUserPresent)
            {
                source.RaiseBlinkAction(BlinkActionTypes.None);
                return(new NotPresentState());
            }

            if (ShouldGoToDefaultState(source))
            {
                source.RaiseBlinkAction(BlinkActionTypes.None);
                return(new DefaultState());
            }

            bool blinkCheckNeeded = UpdateBlinkCount(source);

            if (blinkCheckNeeded &&
                StateMachineUtils.GetWinkCount(_blinks) >= GetCommandBlinkCount(source))
            {
                //NOTE: BlinkActionより先にFixを解除することが絶対に必要。
                //理由: マウスが視点アイコンと干渉するのを防ぐ為。
                source.FixDisplayPosition = false;
                source.RaiseBlinkAction(BlinkActionType);
                return(new CommandEndState());
            }

            return(this);
        }
        public IState <SynchroGazerStatus> Update(SynchroGazerStatus source)
        {
            if (!source.IsUserPresent)
            {
                return(new NotPresentState());
            }

            UpdateWinkTime(source);
            bool blinkCountUpdated = UpdateBlinkCount(source);

            _lastTimestamp = source.TimeStamp;

            if (_leftWinkCountMillisec > WinkThreashold)
            {
                return(new LeftWinkState());
            }
            else if (_rightWinkCountMillisec > WinkThreashold)
            {
                return(new RightWinkState());
            }
            else if (
                blinkCountUpdated &&
                StateMachineUtils.GetWinkCount(_leftBlinks) >= CommandBlinkCount &&
                StateMachineUtils.GetWinkCount(_rightBlinks) >= CommandBlinkCount
                )
            {
                _leftBlinks.Clear();
                _rightBlinks.Clear();

                source.RaiseBlinkAction(BlinkActionTypes.Blink);
            }

            return(this);
        }
        private bool UpdateBlinkCount(SynchroGazerStatus source)
        {
            if (_eyeOpened == GetTargetEyeOpened(source))
            {
                return(false);
            }

            _eyeOpened = GetTargetEyeOpened(source);

            _blinks.Enqueue(new BlinkToggleData(
                                source.DisplayX,
                                source.DisplayY,
                                source.TimeStamp,
                                _eyeOpened
                                ));

            StateMachineUtils.RefreshBlinkToggleQueue(
                _blinks, source.TimeStamp, GetBlinkDuration(source)
                );
            return(true);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Queueに新規にデータが投げ込まれたらtrue</returns>
        private bool UpdateBlinkCount(SynchroGazerStatus source)
        {
            bool result = false;

            if (_leftEyeOpened != source.LeftEyeOpened)
            {
                _leftEyeOpened = source.LeftEyeOpened;

                _leftBlinks.Enqueue(new BlinkToggleData(
                                        source.DisplayX,
                                        source.DisplayY,
                                        source.TimeStamp,
                                        source.LeftEyeOpened
                                        ));
                result = true;
            }

            if (_rightEyeOpened != source.RightEyeOpened)
            {
                _rightEyeOpened = source.RightEyeOpened;

                _rightBlinks.Enqueue(new BlinkToggleData(
                                         source.DisplayX,
                                         source.DisplayY,
                                         source.TimeStamp,
                                         source.RightEyeOpened
                                         ));
                result = true;
            }

            if (result)
            {
                StateMachineUtils.RefreshBlinkToggleQueue(_leftBlinks, source.TimeStamp, BlinkDuration);
                StateMachineUtils.RefreshBlinkToggleQueue(_rightBlinks, source.TimeStamp, BlinkDuration);
            }

            return(result);
        }