Skip to content

Outline

Antonio Maiorano edited this page Nov 3, 2015 · 31 revisions

Outline

Chapter 1 - Getting Started

  • (DONE) About HSM
  • (DONE) Benefits of HSM
  • (DONE) License
  • (DONE) Installation
    • Build Environment
    • Configuration
    • RTTI
  • (DONE) Tools
    • plotHsm

Chapter 2 - The Basics

  • (DONE) Introduction

    • In this chapter, we'll learn the basics of how to use the HSM library to implement simple state machines.
    • We'll only see flat state machines, not hierarchical just yet
  • (DONE) The Simplest State Machine

  • (DONE) States and Transitions

  • (DONE) Improving Readability

    • nesting states in a struct
  • (DONE) State OnEnter/OnExit

    • OnEnter/OnExit vs Constructor/Destructor
  • (DONE) ProcessStateTransitions

    • stateMachine.ProcessStateTransitions() will call GetTransition on the current state and process the returned transition until there are no more state changes.
    • example: call ProcessStateTransitions(), change a variable, call ProcessStateTransitions() again
    • realtime (e.g. games): call ProcessStateTransitions() every frame (state of world may change each frame)
    • event-based (e.g. UI): on event, change state and call ProcessStateTransitions()
    • note: this function's job is to return a transition, not to execute state-specific logic. In other words, there should be no side-effects (variable changes) in running this function. Instead, use the Update function (covered next).
  • (DONE) UpdateStates

    • right now, we know that a state can perform an action in OnEnter/OnExit
    • sometimes you want your states to do something while they're the current state, say every frame in a game
    • for this, there's UpdateStates which simply calls Update on the current state
    • should be called right after ProcessStateTransitions so that only the current valid state runs its update logic
    • example
    • is only a convenience
    • configurable parameter list
  • (DONE) Ownership

    • StateMachine instance may optionally have an owner
    • typically, owner is the instance of the class that aggregates the StateMachine instance
    • States derive from hsm::StateWithOwner instead of hsm::State
    • Advantage: access (public) members from Owner
      • 'friend struct States' trick to access private members of Owner
  • (DONE) Storing Data

    • As we saw, you can store data on the Owner. This data persists across state changes.
    • You can also store data in states, which only lasts as long as the state does.
  • Summary

Chapter 3 - The H in HSM

  • (DONE) Introduction

  • (DONE) Why Use Hierarchical State Machines?

  • (DONE) Drawing HSMs

  • (DONE) Inner and Outer States

  • (DONE) The State Stack

  • (DONE) InnerEntry Transitions

    • example
  • (DONE) Inner Transitions

    • example
    • don't do it :)
  • (DONE) State Stack Queries

    • IsInState, IsInInnerState, etc.
  • (DONE) ProcessStateTransitions Revisited

    • the StateMachine class manages a stack of states
      • this is what makes it hierarchical
      • explicit: you can query the state stack
      • implicit: state stack is modified only via transitions
      • the algorithm
  • (DONE) UpdateStates Revisited

    • calls Update on states from outermost to innermost
  • Summary

Chapter 4 - Advanced Techniques

  • (DONE) Introduction

  • (DONE) StateValue

  • (DONE) StateArgs

  • (DONE) Storing Data on Cluster Root State

  • (DONE) Restarting states

    • sibling transition to self
  • (DONE) Selector states

    • good for choosing first state (stand vs falling)
    • good for when sibling states can make sibling transitions to every other state with the same conditions - you "ping-pong" to the selector state
  • (DONE) Done States

  • (DONE) Share functions via base states

    • Starting with StateWithOwner, but also for any set of states
  • (DONE) Deferred transitions

    • storing Transitions to later return them in GetTransition
  • (DONE) Reusable states

    • Made possible with StateArgs + Deferred transitions
  • (DONE) Sharing States

    • Sharing states with unrelated owners (templated)
    • Sharing states with related owners (StateWithOwner)
  • (DONE) Sharing State Machines (State Overrides)

  • (DONE) Parallel HSMs

    • single HSM solves problem of being in many interdependent states
    • but what about being in many independent, but related, states at the same time?
  • Summary

Chapter 5 - Best Practices

  • (DONE) Introduction

  • (DONE) Prefer InnerEntry + Sibling to Inner

  • (DONE) Scope data as "deeply" as possible: state, outer state, then owner

  • (DONE) Clean up in cluster's outermost state's OnExit

  • (DONE) Avoid state stack queries outside of states

    • Prefer having states drive actions (via StateValue for e.g.) over using IsInState outside the state machine.
    • Less coupled; easier to rename states; easier to reuse states.
  • (DONE) Make each state machine update count

    • Do as much as possible within a single ProcessStateTransitions (within a single frame, rather than over multiple frames)
      • Use transient 'Done' states instead of setting bools
  • Prefer inner states over inheriting states

    • talk about the two orthogonal axes: state stack vs inheritance chain. Confusing to mix both. Can be simpler to use the state stack: don't worry about forgetting to chain virtual overrides, for example.
    • prefer to put reusable functions in inherited (base) state classes, but call these functions from the state class itself
  • Handle RAII using StateValue, RAII classes as state data members, or OnEnter/OnExit

    • use enable/disable physics as example
    • talk about ref-counting problem, that using StateValue can solve, if delaying the enable/disable is possible
    • RAII classes are just useful to avoid having to add OnEnter/OnExit, exactly like how they can be used to avoid having to add constructor/destructor
  • Summary