Skip to content
/ fsmlite Public

Lightweight finite state machine framework for C++17

License

Notifications You must be signed in to change notification settings

tkem/fsmlite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fsmlite CI build status Documentation build status Test coverage License

fsmlite is a lightweight finite state machine framework for C++17. It is based on concepts first presented by David Abrahams and Aleksey Gurtovoy in C++ Template Metaprogramming, with additional ideas taken liberally from Boost's Meta State Machine (MSM), and slightly "modernized" to make use of features more recently introduced to the C++ standard.

The canonical CD player example (with CD-Text and auto-play support!) therefore looks somewhat like this:

#include "fsmlite.h"

#include <string>

class player: public fsmlite::fsm<player> {
    // grant base class access to private transition_table
    friend class fsmlite::fsm<player>;

    std::string cd_title;
    bool autoplay = false;

public:
    enum states { Stopped, Open, Empty, Playing, Paused };

    player(state_type init_state = Empty) : fsm(init_state) { }

    void set_autoplay(bool f) { autoplay = f; }

    bool is_autoplay() const { return autoplay; }

    const std::string& get_cd_title() const { return cd_title; }

    struct play {};
    struct open_close {};
    struct cd_detected {
        std::string title;
        bool bad() const { return title.empty(); }
    };
    struct stop {};
    struct pause {};

private:
    void start_playback();
    void start_autoplay(const cd_detected& cd);
    void open_drawer();
    void close_drawer();
    void store_cd_info(const cd_detected& cd);
    void stop_playback();
    void pause_playback();
    void resume_playback();
    void stop_and_open();

private:
    using m = player;  // for brevity

    using transition_table = table<
//       Start    Event        Target   Action              Guard (optional)
//  ----+--------+------------+--------+-------------------+-----------------+-
    row< Stopped, play,        Playing, &m::start_playback                    >,
    row< Stopped, open_close,  Open,    &m::open_drawer                       >,
    row< Open,    open_close,  Empty,   &m::close_drawer                      >,
    row< Empty,   open_close,  Open,    &m::open_drawer                       >,
    row< Empty,   cd_detected, Open,    &m::open_drawer,    &cd_detected::bad >,
    row< Empty,   cd_detected, Playing, &m::start_autoplay, &m::is_autoplay   >,
    row< Empty,   cd_detected, Stopped, &m::store_cd_info   /* fallback */    >,
    row< Playing, stop,        Stopped, &m::stop_playback                     >,
    row< Playing, pause,       Paused,  &m::pause_playback                    >,
    row< Playing, open_close,  Open,    &m::stop_and_open                     >,
    row< Paused,  play,        Playing, &m::resume_playback                   >,
    row< Paused,  stop,        Stopped, &m::stop_playback                     >,
    row< Paused,  open_close,  Open,    &m::stop_and_open                     >
//  ----+--------+------------+--------+-------------------+-----------------+-
    >;
};

player p;                                       // p.current_state() == player::Empty
p.process_event(player::open_close());          // p.current_state() == player::Open
p.process_event(player::open_close());          // p.current_state() == player::Empty
p.process_event(player::cd_detected{"Help!"});  // p.current_state() == player::Stopped
p.process_event(player::play());                // p.current_state() == player::Playing
p.process_event(player::pause());               // p.current_state() == player::Paused

Basic Documentation is available, but please also have a look at the unit tests for example usage.

License

Copyright (c) 2015-2025 Thomas Kemmer

Licensed under the MIT License (MIT).

About

Lightweight finite state machine framework for C++17

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project

  •