Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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?

share|improve this question
4  
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
1  
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. –  Byte56 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
add comment

closed as too localized by Sean Middleditch, Tetrad Mar 13 '13 at 16:37

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

Browse other questions tagged or ask your own question.