Wiki

Clone wiki

HaveBoxStates / Documentation

Home - News - Documentation

Documentation

License

HaveBoxStates is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Versions

HaveBoxStates is versioned after following convention:

Major.Minor.Build

A change in:

  • Major: Covers breaking changes, unbreaking changes, bugfixes and optimizations
  • Minor: Unbreaking changes, bugfixes and optimizations
  • Build: Bugfixes and optimizations

Getting HaveBoxStates

HaveBoxStates can be downloaded from Nuget:

https://www.nuget.org/packages/HaveBoxStates/

Or

https://bitbucket.org/Have/haveboxstates/downloads

Using HaveBoxStates

First of all, HaveBoxStates has a buildin state called Stop. When the ever the state machine has to stop, go to the Stop state.

Creating states

You need 2 things for creating a state:

  1. Inherit from the IState interface
  2. Add the mehtod: public void ExecuteState(IStateMachine statemachine) or public void ExecuteState(IStateMachine statemachine, <Some type> <parameter name>). These methods are NOT overrides to the interface. There is no compile-time check for whether these methods exists.

2 examples taken from the concept app:

#!CSharpLexer

using GameStateMachineConcept.Dtos;
using HaveBoxStates;

namespace GameStateMachineConcept.States
{
    public class Init : IState
    {
        public void ExecuteState(IStateMachine statemachine)
        {
            statemachine.SetNextStateTo<PlayGame>(new PlayerContext{ Points = 0, Lives = 3, });
        }
    }

    public class Scores : IState
    {
        public void ExecuteState(IStateMachine statemachine, GameContext GameContext)
        {
            GameContext.PlayerContext.Points += GameContext.GainedPoints;

            if (GameContext.PlayerContext.Lives == 0)
            {
                statemachine.SetNextStateTo<Stop>();
            }
            else
            {
                statemachine.SetNextStateTo<PlayGame>(GameContext.PlayerContext);
            }
        }
    }
}

You can use dependency injection on your states, like:

#!CSharpLexer

using GameStateMachineConcept.Dtos;
using GameStateMachineConcept.GameEngine;
using HaveBoxStates;

namespace GameStateMachineConcept.States
{
    public class PlayGame : IState
    {
        private IGameEngine _gameEngine;

        public PlayGame(IGameEngine gameEngine)
        {
            _gameEngine = gameEngine;
        }

        public void ExecuteState(IStateMachine statemachine, PlayerContext playerContext)
        {
            var gameContext = new GameContext { PlayerContext = playerContext, GainedPoints = 0, };

            _gameEngine.Play(gameContext);

            statemachine.SetNextStateTo<Scores>(gameContext);
        }
    }
}

Bootstrap it all, like:

#!CSharpLexer

using GameStateMachineConcept.GameEngine;
using GameStateMachineConcept.States;
using HaveBox;
using HaveBoxStates;
using HaveBoxStates.ContainerAdaptors;

namespace GameStateMachineConcept
{
    public class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            container.Configure(config =>
            {
                config.For<IGameEngine>().Use<GameEngine.GameEngine>();
                config.For<Init>().Use<Init>();
                config.For<PlayGame>().Use<PlayGame>();
                config.For<Scores>().Use<Scores>();
            });

            var stateMachine = new StateMachine(new HaveBoxAdaptor(container));
            stateMachine.StartStateMachinesAtState<Init>();
        }
    }
}

If you would like to write a adaptor, for the IoC container you use:

#!CSharpLexer

using HaveBox;

namespace HaveBoxStates.ContainerAdaptors
{
    public class HaveBoxAdaptor : IContainerAdaptor
    {
        private IContainer _container;

        public HaveBoxAdaptor(IContainer container)
        {
            _container = container;
        }

        public T GetInstance<T>()
        {
            return _container.GetInstance<T>();
        }

        public void AddState<T>()
        {
            _container.Configure(config => config.For<T>().Use<T>());
        }
    }
}

Updated