public ApplicationState(IDepartmentService departmentService, ISettingService settingService,
     ICacheService cacheService)
 {
     _screenState = new StateMachine<AppScreens, AppScreens>(() => ActiveAppScreen, state => ActiveAppScreen = state);
     _screenState.OnUnhandledTrigger(HandleTrigger);
     _departmentService = departmentService;
     _settingService = settingService;
     _cacheService = cacheService;
     CurrentTicketType = TicketType.Default;
 }
 public ApplicationState(IDepartmentService departmentService, ISettingService settingService,
     ICacheService cacheService, IExpressionService expressionService, INotificationService notificationService)
 {
     _screenState = new StateMachine<AppScreens, AppScreens>(() => ActiveAppScreen, state => ActiveAppScreen = state);
     _screenState.OnUnhandledTrigger(HandleTrigger);
     _departmentService = departmentService;
     _settingService = settingService;
     _cacheService = cacheService;
     _expressionService = expressionService;
     _notificationService = notificationService;
     SetCurrentDepartment(Department.Default);
     CurrentTicketType = TicketType.Default;
     _isLandscape = true;
 }
        public MainLogicProcessor()
        {
            VisionData = new VisionData();
            SensorData = new SensorData();
            LogicState = new LogicState();

            stateMachine = new StateMachine<State, Trigger>(State.Idle);

            stateMachine.OnUnhandledTrigger((state, trigger) => { });

            stateMachine.Configure(State.Idle)
                .Permit(Trigger.PoweredUp, State.Starting)
                .OnEntry(() => Commander.SetColors(Colors.Yellow));

            stateMachine.Configure(State.Starting)
                .Permit(Trigger.Finished, State.LookingForBall)
                .Permit(Trigger.BallCaught, State.FindingGoal)
                .OnEntry(() =>
                {
                    stopwatchTime = stopwatch.ElapsedMilliseconds;
                    SoundClipPlayer.PlayIntro();
                    Commander.SetColors(Colors.Cyan);
                });

            stateMachine.Configure(State.LookingForBall)
                .Permit(Trigger.CameraLockedOnBall, State.ClosingInOnBall)
                .Permit(Trigger.BallCaught, State.FindingGoal)
                .OnEntry(
                () =>
                {
                    Commander.SetColors(Colors.Blue);
                    stopwatchTime = stopwatch.ElapsedMilliseconds;
                });

            stateMachine.Configure(State.ClosingInOnBall)
                .Permit(Trigger.CameraLostBall, State.LookingForBall)
                .Permit(Trigger.BallCaught, State.FindingGoal)
                .Permit(Trigger.Timeout, State.LookingForBall)
                .OnEntry(() =>
                {
                    StartTimer(10000, Trigger.Timeout);
                    Commander.SetColors(Colors.Red);
                })
                .OnExit(StopTimer);

            stateMachine.Configure(State.FindingGoal)
                .Permit(Trigger.CoilgunLaunched, State.LookingForBall)
                .Permit(Trigger.BallLost, State.LookingForBall)
                .Permit(Trigger.Timeout, State.LookingForBall)
                .OnEntry(() =>
                {
                    LogicState.FindingGoal = true;
                    StartTimer(5000, LaunchBall);
                    Commander.SetColors(Colors.Magenta);
                })
                .OnExit(
                () =>
                {
                    LogicState.FindingGoal = false;
                    StopTimer();
                });

            stopwatch.Start();
        }
Beispiel #4
0
        /// <summary>
        ///     Main client thread.
        /// </summary>
        private void ClientThread()
        {
            _gameState.Reset();

            _connection = DotaGameConnection.CreateWith(_details);
            _handshake = new DotaHandshake(_details, _gameState, _connection);
            _signon = new DotaSignon(_gameState, _connection, _details);
            _game = new DotaGame(_gameState, _connection);
            _commandGenerator = new UserCmdGenerator(_gameState, _connection);

            foreach (var cont in Controllers)
                cont.Initialize(_details.SteamId, _gameState, _commandGenerator);

            long handshake_requested = 0;
            long handshake_giveup = new TimeSpan(0, 0, 0, 10).Ticks;

            // Map states in the StateMachine to handlers
            var metastates = new Dictionary<States, Metastates>() {
                { States.HANDSHAKE_REQUEST, Metastates.HANDSHAKE },
                { States.HANDSHAKE_CONNECT, Metastates.HANDSHAKE },
                { States.CONNECTED, Metastates.SIGNON },
                { States.LOADING, Metastates.SIGNON },
                { States.PRESPAWN, Metastates.SIGNON },
                { States.SPAWN, Metastates.SIGNON },
                { States.PLAY, Metastates.GAME },
            };

            var processors = new Dictionary<Metastates, IHandler>() {
                { Metastates.HANDSHAKE, _handshake },
                { Metastates.SIGNON, _signon },
                { Metastates.GAME, _game }
            };


            _stateMachine = new StateMachine<States, Events>(States.DISCONNECTED);
            //temporary shit
            _stateMachine.OnTransitioned(transition =>
            {
                if (transition.Source == transition.Destination) return;
                Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.SessionStateTransition(transition.Source, transition.Destination)));
            });

            _stateMachine.OnUnhandledTrigger((states, events) =>
            {
                Console.WriteLine("Unhandled trigger: " + events.ToString("G"));

            });

            var disconnected = new Action(() =>
            {
                if (_connection == null) return;
                Running = true;
                Stop();
            });

            _stateMachine.Configure(States.DISCONNECTED)
                .Ignore(Events.TICK)
                .Ignore(Events.DISCONNECTED)
                .OnEntry(disconnected)
                .Permit(Events.REQUEST_CONNECT, States.HANDSHAKE_REQUEST);
            _stateMachine.Configure(States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED)
                .OnEntry(() =>
                {
                    Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.HandshakeRejected(_handshake.rejected_reason)));
                    _stateMachine.Fire(Events.DISCONNECTED);
                });
            _stateMachine.Configure(States.HANDSHAKE_REQUEST)
                .OnEntry(() => handshake_requested = DateTime.Now.Ticks)
                .OnEntry(_handshake.RequestHandshake)
                .Ignore(Events.TICK)
                .Permit(Events.HANDSHAKE_CHALLENGE, States.HANDSHAKE_CONNECT)
                .Permit(Events.REJECTED, States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.HANDSHAKE_CONNECT)
                .OnEntry(_handshake.RespondHandshake)
                .Ignore(Events.TICK)
                .PermitReentry(Events.HANDSHAKE_CHALLENGE) // possibly re-enter?
                .Permit(Events.HANDSHAKE_COMPLETE, States.CONNECTED)
                .Permit(Events.REJECTED, States.HANDSHAKE_REJECTED)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.CONNECTED)
                .OnEntry(_signon.EnterConnected)
                .Ignore(Events.TICK)
                .Permit(Events.LOADING_START, States.LOADING)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.LOADING)
                .OnEntry(_signon.EnterNew)
                .Ignore(Events.TICK)
                .Permit(Events.CONNECTED, States.CONNECTED)
                .Permit(Events.PRESPAWN_START, States.PRESPAWN)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.PRESPAWN)
                .OnEntry(_signon.EnterPrespawn)
                .Ignore(Events.TICK)
                .Permit(Events.SPAWNED, States.SPAWN)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.SPAWN)
                .OnEntry(_signon.EnterSpawn)
                .Ignore(Events.TICK)
                .Permit(Events.BASELINE, States.PLAY)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);
            _stateMachine.Configure(States.PLAY)
                .OnEntryFrom(Events.BASELINE, () =>
                {
                    _game.EnterGame();
                    _commandGenerator.Reset();
                })
                .OnEntryFrom(Events.TICK, () =>
                {
                    _gameState.Update();
                    foreach(var cont in Controllers) cont.Tick();
                    _commandGenerator.Tick();
                    _gameState.Created.Clear();
                    _gameState.Deleted.Clear();
                })
                .PermitReentry(Events.TICK)
                .Permit(Events.DISCONNECTED, States.DISCONNECTED);

            _stateMachine.Fire(Events.REQUEST_CONNECT);

            long next_tick = DateTime.Now.Ticks;
            while (Running && _stateMachine.State != States.DISCONNECTED && _stateMachine.State != States.HANDSHAKE_REJECTED)
            {
                try
                {
                    if (next_tick > DateTime.Now.Ticks)
                    {
                        Thread.Sleep(1);
                        continue;
                    }

                    if (_stateMachine == null) break;

                    if (_stateMachine.State == States.HANDSHAKE_REQUEST &&
                        (DateTime.Now.Ticks - handshake_requested) > handshake_giveup)
                    {
                        _stateMachine.Fire(Events.DISCONNECTED);
                        continue;
                    }

                    if (_connection.state == DotaGameConnection.State.Closed)
                    {
                        _stateMachine.Fire(Events.DISCONNECTED);
                        continue;
                    }

                    if (_connection == null) break;

                    List<byte[]> outBand = _connection.GetOutOfBand();
                    List<DotaGameConnection.Message> inBand = _connection.GetInBand();

                    foreach (byte[] message in outBand)
                    {
                        Nullable<Events> e = processors[metastates[_stateMachine.State]].Handle(message);
                        if (e.HasValue)
                        {
                            _stateMachine.Fire(e.Value);
                        }
                    }

                    foreach (DotaGameConnection.Message message in inBand)
                    {
                        Nullable<Events> e = processors[metastates[_stateMachine.State]].Handle(message);
                        if (e.HasValue)
                        {
                            _stateMachine.Fire(e.Value);
                        }
                    }

                    _stateMachine.Fire(Events.TICK);

                    if (_gameState.TickInterval > 0)
                    {
                        next_tick += (uint)(_gameState.TickInterval * 1000 * 10000 /* ticks per ms */);
                    }
                    else
                    {
                        next_tick += 50 * 1000;
                    }
                    int remain = (int)(next_tick - DateTime.Now.Ticks) / 10000;
                    if (remain > 0)
                    {
                        Thread.Sleep(1);
                    }
                    else if (remain < 0)
                    {
                        next_tick = DateTime.Now.Ticks;
                    }
                }
                catch (Exception ex)
                {
                    Callback?.Invoke(this, new CallbackEventArgs(new DotaGameClient.LogMessage("Ignored error in session loop, " + ex.Message)));
                }
            }

            if (Running) Stop();
        }
 public SMWorkflowMachine()
 {
     stateMachine = new StateMachine<State, Trigger>(State.Idle);
       stateMachine.Configure(State.Idle)
     .OnEntry(() => { if (OnIdleEntry != null) OnIdleEntry(); })
     .OnExit(() => { if (OnIdleExit != null) OnIdleExit(); })
     .PermitIf(Trigger.Select, State.SelectDrink , () => { if (GuardClauseFromIdleToSelectDrinkUsingTriggerSelect != null) return GuardClauseFromIdleToSelectDrinkUsingTriggerSelect(); return true; } )
     .PermitIf(Trigger.Insert, State.CoinBox , () => { if (GuardClauseFromIdleToCoinBoxUsingTriggerInsert != null) return GuardClauseFromIdleToCoinBoxUsingTriggerInsert(); return true; } )
       ;
       stateMachine.Configure(State.SelectDrink)
     .OnEntry(() => { if (OnSelectDrinkEntry != null) OnSelectDrinkEntry(); })
     .OnExit(() => { if (OnSelectDrinkExit != null) OnSelectDrinkExit(); })
     .PermitIf(Trigger.SelectedDrink, State.SelectedDrink , () => { if (GuardClauseFromSelectDrinkToSelectedDrinkUsingTriggerSelectedDrink != null) return GuardClauseFromSelectDrinkToSelectedDrinkUsingTriggerSelectedDrink(); return true; } )
       ;
       stateMachine.Configure(State.CoinBox)
     .OnEntry(() => { if (OnCoinBoxEntry != null) OnCoinBoxEntry(); })
     .OnExit(() => { if (OnCoinBoxExit != null) OnCoinBoxExit(); })
     .PermitIf(Trigger.RefundMoney, State.MoneyRefunded , () => { if (GuardClauseFromCoinBoxToMoneyRefundedUsingTriggerRefundMoney != null) return GuardClauseFromCoinBoxToMoneyRefundedUsingTriggerRefundMoney(); return true; } )
     .PermitIf(Trigger.CheckMoney, State.ControlMoney , () => { if (GuardClauseFromCoinBoxToControlMoneyUsingTriggerCheckMoney != null) return GuardClauseFromCoinBoxToControlMoneyUsingTriggerCheckMoney(); return true; } )
       ;
       stateMachine.Configure(State.ControlMoney)
     .OnEntry(() => { if (OnControlMoneyEntry != null) OnControlMoneyEntry(); })
     .OnExit(() => { if (OnControlMoneyExit != null) OnControlMoneyExit(); })
     .PermitIf(Trigger.Rejected, State.CoinBox , () => { if (GuardClauseFromControlMoneyToCoinBoxUsingTriggerRejected != null) return GuardClauseFromControlMoneyToCoinBoxUsingTriggerRejected(); return true; } )
     .PermitIf(Trigger.EnoughMoney, State.ServingDrink , () => { if (GuardClauseFromControlMoneyToServingDrinkUsingTriggerEnoughMoney != null) return GuardClauseFromControlMoneyToServingDrinkUsingTriggerEnoughMoney(); return true; } )
       ;
       stateMachine.Configure(State.SelectedDrink)
     .OnEntry(() => { if (OnSelectedDrinkEntry != null) OnSelectedDrinkEntry(); })
     .OnExit(() => { if (OnSelectedDrinkExit != null) OnSelectedDrinkExit(); })
     .PermitIf(Trigger.DeSelectDrink, State.SelectDrink , () => { if (GuardClauseFromSelectedDrinkToSelectDrinkUsingTriggerDeSelectDrink != null) return GuardClauseFromSelectedDrinkToSelectDrinkUsingTriggerDeSelectDrink(); return true; } )
     .PermitIf(Trigger.FoundDrink, State.ServingDrink , () => { if (GuardClauseFromSelectedDrinkToServingDrinkUsingTriggerFoundDrink != null) return GuardClauseFromSelectedDrinkToServingDrinkUsingTriggerFoundDrink(); return true; } )
       ;
       stateMachine.Configure(State.ServingDrink)
     .OnEntry(() => { if (OnServingDrinkEntry != null) OnServingDrinkEntry(); })
     .OnExit(() => { if (OnServingDrinkExit != null) OnServingDrinkExit(); })
     .PermitIf(Trigger.TakeDrink, State.DrinkReady , () => { if (GuardClauseFromServingDrinkToDrinkReadyUsingTriggerTakeDrink != null) return GuardClauseFromServingDrinkToDrinkReadyUsingTriggerTakeDrink(); return true; } )
       ;
       stateMachine.Configure(State.DrinkReady)
     .OnEntry(() => { if (OnDrinkReadyEntry != null) OnDrinkReadyEntry(); })
     .OnExit(() => { if (OnDrinkReadyExit != null) OnDrinkReadyExit(); })
     .PermitIf(Trigger.TakeChange, State.MoneyRefunded , () => { if (GuardClauseFromDrinkReadyToMoneyRefundedUsingTriggerTakeChange != null) return GuardClauseFromDrinkReadyToMoneyRefundedUsingTriggerTakeChange(); return true; } )
       ;
       stateMachine.Configure(State.MoneyRefunded)
     .OnEntry(() => { if (OnMoneyRefundedEntry != null) OnMoneyRefundedEntry(); })
     .OnExit(() => { if (OnMoneyRefundedExit != null) OnMoneyRefundedExit(); })
     .PermitIf(Trigger.RefundMoney, State.Idle , () => { if (GuardClauseFromMoneyRefundedToIdleUsingTriggerRefundMoney != null) return GuardClauseFromMoneyRefundedToIdleUsingTriggerRefundMoney(); return true; } )
       ;
       stateMachine.OnUnhandledTrigger((state, trigger) => { if (OnUnhandledTrigger != null) OnUnhandledTrigger(state, trigger); });
 }