(C) Eskil Heyn Olsen 1995-2008. This is an example of usage of a finite state machine API I wrote. The goal of the API was to ensure that code put focus on the FSM transition table, thereby helping the code to be self-documenting rather than risking a state machine implemented via the usual jumble of integers/enums indicating type, followed by if statements scattered all over the place. As an additional bonus, the API would generate post-script files of the FSMs for documentation purposes. The final API was quite different in many ways (ie. allowed for events being PODs), but the final version is not copyrighted by my, hence I can only show an early example of usage. typedef statemachines::traits my_fsm_traits; class simple_fsm : public statemachines::statemachine { public: class generic_event : public event_t {}; class one_event : public event_t { public: one_event (std::string msg) : m_message (msg) {} std::string m_message; }; class loop_event : public event_t {}; class failure_event : public event_t {}; simple_fsm () { *this << graphviz_t ("test_graph") << begin_t (initial_state) //------------------------+---------------+-------------+---------------------------+--------------------- // Event From-State To-State Action Description << edge_t (initial_state, one_state, &simple_fsm::action, "we got a 1") << edge_t (initial_state, fail_state) << edge_t (initial_state, loop_1_state, "got a loop event") << edge_t (one_state, loop_2_state, &simple_fsm::loop_2_action, "got a loop event") << edge_t (loop_1_state, loop_2_state, &simple_fsm::loop_2_action) << edge_t (loop_2_state, loop_1_state, "do a loop") << edge_t (fail_state, end_state) << edge_t (one_state, end_state, &simple_fsm::end_action, "") << edge_t (loop_1_state, end_state, &simple_fsm::end_action, "generic") << edge_t (loop_2_state, end_state, &simple_fsm::end_action, "generic"); //------------------------+---------------+-------------+---------------------------+--------------------- } void action (const one_event &foo) { std::cout << (boost::format ("action for one_event : %1%\n") % foo.m_message).str (); m_count ++; } void end_action (const generic_event &foo) { std::cout << "reached the end of the line\n"; m_count ++; } void loop_2_action (const loop_event &foo) { std::cout << "loop\n"; prepost_event (new loop_event); m_count ++; } void run (const std::string &name) { m_count = 0; // exercise it a bit post_event (new one_event ("hello world!")); post_event (new loop_event); post_event (new loop_event); post_event (new generic_event); while (handle_event ()) { } assert (m_count == 4); save_to_postscript (name); } private: int m_count; };