How to handle states.

Started by
1 comment, last by SeanMiddleditch 9 years, 8 months ago

I've been writing an 2D engine and the problem came to mind of how to handle states. I was wondering what people would think of this solution.

The base state isn't removable and the link is just a header with comments on the purpose of each function.

https://gist.github.com/Joshhua5/072371448382abbcee94

Advertisement

I think the "setRender" and "setInitialize" could be "render" and "initialize". I typically reserve "set" for methods that set the value of a variable (like "setX"). Also I think you will want to make methods that can be overridden in a child class virtual IE: "virtual void update();".

I personally like to have a class for each state (Like MainMenuScreen, ect), although it looks like you are involving Lua scripting so perhaps you are handling that there.

Just my two cents though, there are many different ways of doing things :).

You'll typically want states to also handle messages (assuming you use messages in your game, which you probably will at some point).

Once you have messages you also don't need to special-case render (what does that mean, anyway? camera setup? scene submission? pre-culled object submission? post-processing?) or even update.

I'm a fan of state stacks, but your implementation has some safety issues since your Lua functions are char* (lifetime issues). It's also concerning that `active` is a public variable. The `set*` naming is also weird.

Using a collection of function pointers makes some sense, though typically you'd apply a bit more C++ here and just use an interface and inheritance, e.g.

// Interface that all game states must implement
class IGameState {public:virtual ~IGameState() = default;
  virtual void OnUpdate() = 0;
  virtual void OnRender() = 0;
};

// a game state backed by a script
class ScriptedGameState final : public IGameState {
  LuaState& _lua;
  LuaFunction _update;
  LuaFunction _render;

public:
  ScriptGameState(LuaState& lua, LuaFunction update, LuaFunction render) :
    _lua(lua), _update(update), _render(render) {}

  void OnUpdate() override { _lua.Invoke(_update); }
  void OnRender() override { _lua.Invoke(_render); }
};

// example native/non-script game state
class NativeMainMenu final : public IGameState {
public:
  void OnUpdate() override { whatever(); }
  void OnRender() override { stuff(); }
};

using GameStateStack = std::vector<std::unique_ptr<IGameState>>;

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement