├── .travis.yml
├── LICENSE
├── README.md
├── demo1.cc
├── demo2.cc
├── fsm.cpp
└── fsm.hpp
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 |
3 | compiler:
4 | - clang
5 | - gcc
6 |
7 | install:
8 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.pre.sh | bash -x
9 |
10 | script:
11 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.build.sh | bash -x
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 r-lyeh (https://github.com/r-lyeh)
2 |
3 | This software is provided 'as-is', without any express or implied
4 | warranty. In no event will the authors be held liable for any damages
5 | arising from the use of this software.
6 |
7 | Permission is granted to anyone to use this software for any purpose,
8 | including commercial applications, and to alter it and redistribute it
9 | freely, subject to the following restrictions:
10 |
11 | 1. The origin of this software must not be misrepresented; you must not
12 | claim that you wrote the original software. If you use this software
13 | in a product, an acknowledgment in the product documentation would be
14 | appreciated but is not required.
15 | 2. Altered source versions must be plainly marked as such, and must not be
16 | misrepresented as being the original software.
17 | 3. This notice may not be removed or altered from any source distribution.
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | fsm
2 | ===
3 |
4 | FSM is a lightweight finite-state machine class. Both Hierarchical FSM and simple FSM implementations are provided.
5 |
6 | ### Features
7 | - [x] Expressive. Basic usage around `on(state,trigger) -> do lambda` expression.
8 | - [x] Tiny, cross-platform, stand-alone, header-only.
9 | - [x] ZLIB/libPNG licensed.
10 |
11 | ### Links
12 | [Finite-State Machines: Theory and Implementation](http://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867)
13 |
14 | ### Showcase
15 | ```c++
16 | // basic hfsm sample
17 |
18 | #include
19 | #include "fsm.hpp"
20 |
21 | // custom states (gerunds) and actions (infinitives)
22 |
23 | enum {
24 | walking = 'WALK',
25 | defending = 'DEFN',
26 |
27 | tick = 'tick',
28 | };
29 |
30 | struct ant_t {
31 | fsm::stack fsm;
32 | int health, distance, flow;
33 |
34 | ant_t() : health(0), distance(0), flow(1) {
35 | // define fsm transitions: on(state,trigger) -> do lambda
36 | fsm.on(walking, 'init') = [&]( const fsm::args &args ) {
37 | std::cout << "initializing" << std::endl;
38 | };
39 | fsm.on(walking, 'quit') = [&]( const fsm::args &args ) {
40 | std::cout << "exiting" << std::endl;
41 | };
42 | fsm.on(walking, 'push') = [&]( const fsm::args &args ) {
43 | std::cout << "pushing current task." << std::endl;
44 | };
45 | fsm.on(walking, 'back') = [&]( const fsm::args &args ) {
46 | std::cout << "back from another task. remaining distance: " << distance << std::endl;
47 | };
48 | fsm.on(walking, tick) = [&]( const fsm::args &args ) {
49 | std::cout << "\r" << "\\|/-"[ distance % 4 ] << " walking " << (flow > 0 ? "-->" : "<--") << " ";
50 | distance += flow;
51 | if( 1000 == distance ) {
52 | std::cout << "at food!" << std::endl;
53 | flow = -flow;
54 | }
55 | if( -1000 == distance ) {
56 | std::cout << "at home!" << std::endl;
57 | flow = -flow;
58 | }
59 | };
60 | fsm.on(defending, 'init') = [&]( const fsm::args &args ) {
61 | health = 1000;
62 | std::cout << "somebody is attacking me! he has " << health << " health points" << std::endl;
63 | };
64 | fsm.on(defending, tick) = [&]( const fsm::args &args ) {
65 | std::cout << "\r" << "\\|/-$"[ health % 4 ] << " health: (" << health << ") ";
66 | --health;
67 | if( health < 0 ) {
68 | std::cout << std::endl;
69 | fsm.pop();
70 | }
71 | };
72 |
73 | // set initial fsm state
74 | fsm.set( walking );
75 | }
76 | };
77 |
78 | int main() {
79 | ant_t ant;
80 | for(int i = 0; i < 12000; ++i) {
81 | if( 0 == rand() % 10000 ) {
82 | ant.fsm.push(defending);
83 | }
84 | ant.fsm.command(tick);
85 | }
86 | }
87 | ```
88 |
89 | ### Changelog
90 | - v1.0.0 (2015/11/29): Code revisited to use fourcc integers (much faster); clean ups suggested by Chang Qian
91 | - v0.0.0 (2014/02/15): Initial version
92 |
--------------------------------------------------------------------------------
/demo1.cc:
--------------------------------------------------------------------------------
1 | #define FSM_BUILD_SAMPLE1
2 | #include "fsm.hpp"
3 |
4 |
--------------------------------------------------------------------------------
/demo2.cc:
--------------------------------------------------------------------------------
1 | #define FSM_BUILD_SAMPLE2
2 | #include "fsm.hpp"
3 |
4 |
--------------------------------------------------------------------------------
/fsm.cpp:
--------------------------------------------------------------------------------
1 | #include "fsm.hpp"
2 |
--------------------------------------------------------------------------------
/fsm.hpp:
--------------------------------------------------------------------------------
1 | // Simple FSM/HFSM class
2 | // - rlyeh [2011..2015], zlib/libpng licensed.
3 |
4 | // [ref] http://en.wikipedia.org/wiki/Finite-state_machine
5 | // [todo] GOAP? behavior trees?
6 | // [todo] counters
7 | // [note] common actions are 'init', 'quit', 'push', 'back' (integers)
8 | // - init and quit are called everytime a state is created or destroyed.
9 | // - push and back are called everytime a state is paused or resumed. Ie, when pushing and popping the stack tree.
10 | // [note] on child states (tree of fsm's):
11 | // - actions are handled to the most inner active state in the decision tree
12 | // - unhandled actions are delegated to the parent state handler until handled or discarded by root state
13 |
14 | #pragma once
15 |
16 | #define FSM_VERSION "1.0.0" /* (2015/11/29) Code revisited to use fourcc integers (much faster); clean ups suggested by Chang Qian
17 | #define FSM_VERSION "0.0.0" // (2014/02/15) Initial version */
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include