# State Machine with State per Entity [closed]

I have a generic state machine implementation like this:

public abstract class State<TOwner>
{
public virtual void OnEnter(TOwner owner) { ... }

public virtual void OnExit(TOwner owner) { ... }
}

public sealed class StateMachine<TOwner, TState>
where TState : State<TOwner>
{
public TState CurrentState { ... }
}


Usage looks a bit like this (more or less):

public abstract class SoldierState : State<Soldier>
{
public abstract void Update(Soldier owner, GameTime gameTime);
}

public class RestState : SoldierState
{
public static readonly RestState Instance = new RestState();

private RestState()
{
}

public override void Update(Soldier owner, GameTime gameTime) { ... }
}

public class Soldier
{
private readonly StateMachine<Soldier, SoldierState> state = ...;

public void Update(GameTime gameTime)
{
this.state.CurrentState.Update(this, gameTime);
}
}


Importantly, notice how my state classes are singletons. This means every soldier will share the same SoldierState instances.

This is fine until I need to store state per soldier. For example, suppose I want to ensure that soldiers remain in the rest state for a minimum of 10 seconds. That means that any soldier that enters the rest state needs to have an associated piece of data tracked for it.

I could just use a dictionary:

public class RestState : SoldierState
{
...

private readonly IDicionary<Soldier, TimeSpan> restTimes = ...;

public override void Update(Soldier owner, GameTime gameTime)
{
TimeSpan restTime;
restTimes.TryGetValue(owner, out restTime);
restTime += gameTime.Elapsed;

if (restTime > TimeSpan.FromSeconds(10))
{
soldier.State = FightingState.Instance;
restTimes.Remove(soldier);
}
else
{
restTimes[soldier] = restTime;
}
}
}


However, I'm concerned about the efficiency (or lack thereof) here. Is there a better way to achieve what I want? Would I be better off having state instances per entity instead of trying to use singletons?

• Quite probably you would be better with one per entity. It sounds like whatever requirement prompted you to create the singletons is no longer valid, therefore a refactor is called for. – Patrick Hughes Jul 14 '12 at 14:53
• Agree with Patrick, it seems silly to try to keep a global state for your soldiers, if you want them to be able to have different states. – MichaelHouse Jul 14 '12 at 15:48
• Fair point. The reason I went with singletons was to make it as simple as possible to change states (by assigning the singleton). By having one state per entity, I need to store references to both the state machine and to the individual states. Not likely a big problem, but something I was trying to avoid if possible. – me-- Jul 21 '12 at 7:56
• Moveover, those state instances will have to be exposed by my soldier so that other states can use them to switch states. eg. RestState above will need to do something like soldier.State = soldier.FightingState; Doing some refactoring now... – me-- Jul 21 '12 at 8:01