Skip to content

Commit

Permalink
1.8.0 (#33)
Browse files Browse the repository at this point in the history
+ sprinkled noexcept everywhere
+ added support for pointer and reference contexts
+ added version info
^ updated .natvis
^ improved TaskListT<>
  • Loading branch information
andrew-gresyk authored Jan 15, 2021
1 parent f0632bf commit bb14a93
Show file tree
Hide file tree
Showing 92 changed files with 5,320 additions and 3,866 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Header-only heriarchical FSM framework in C++11, with fully statically-defined s

## Feature Highlights

- Permissive **[MIT License](https://github.com/andrew-gresyk/FFSM2/blob/master/LICENSE)**
- Permissive **[MIT License](https://github.com/andrew-gresyk/HFSM2/blob/master/LICENSE)**
- Written in widely-supported modern(ish) C++11
- Header-only
- Convenient, minimal boilerplate
Expand Down
18 changes: 9 additions & 9 deletions examples/advanced_event_handling/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// HFSM (hierarchical state machine for games and interactive applications)
// HFSM2 (hierarchical state machine for games and interactive applications)
// Created by Andrew Gresyk
//
// Event handling example
Expand Down Expand Up @@ -94,7 +94,7 @@ struct Reactive
: FSM::State
{
// handle a single event type - TransitionEvent
void react(const TransitionEvent&, FullControl& control) {
void react(const TransitionEvent&, FullControl& control) noexcept {
std::cout << " Reactive: reacting to TransitionEvent\n";

control.changeTo<Target>();
Expand All @@ -118,12 +118,12 @@ struct ConcreteHandler
: FSM::State
{
// handle two event types - PrimaryEvent
void react(const PrimaryEvent&, FullControl&) {
void react(const PrimaryEvent&, FullControl&) noexcept {
std::cout << " ConcreteHandler: reacting to PrimaryEvent\n";
}

// and SecondaryEvent
void react(const SecondaryEvent&, FullControl&) {
void react(const SecondaryEvent&, FullControl&) noexcept {
std::cout << " ConcreteHandler: reacting to SecondaryEvent\n";
}

Expand All @@ -138,7 +138,7 @@ struct TemplateHandler
{
// handle all possible event types
template <typename TEvent>
void react(const TEvent&, FullControl&) {
void react(const TEvent&, FullControl&) noexcept {
std::cout << " TemplateHandler: reacting to TEvent\n";
}
};
Expand All @@ -151,14 +151,14 @@ struct EnableIfHandler
// use std::enable_if to build more complex conditional event handling
template <typename TEvent>
typename std::enable_if<std::is_class<TEvent>::value>::type
react(const TEvent&, FullControl&) {
react(const TEvent&, FullControl&) noexcept {
std::cout << " EnableIfHandler: reacting to a <class event>\n";
}

// but remember to cover all the remaining cases
template <typename TEvent>
typename std::enable_if<!std::is_class<TEvent>::value>::type
react(const TEvent&, FullControl&) {
react(const TEvent&, FullControl&) noexcept {
std::cout << " EnableIfHandler: reacting to a <non-class event>\n";
}
};
Expand All @@ -168,15 +168,15 @@ struct EnableIfHandler
struct Target
: FSM::State
{
void enter(Control&) {
void enter(Control&) noexcept {
std::cout << " changed to Target\n";
}
};

////////////////////////////////////////////////////////////////////////////////

int
main() {
main() noexcept {
FSM::Instance machine;

std::cout << "sending PrimaryEvent:\n";
Expand Down
45 changes: 23 additions & 22 deletions examples/basic_audio_player/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// HFSM (hierarchical state machine for games and interactive applications)
// HFSM2 (hierarchical state machine for games and interactive applications)
// Created by Andrew Gresyk
//
// An HFSM2 port of https://gist.github.com/martinmoene/797b1923f9c6c1ae355bb2d6870be25e
Expand Down Expand Up @@ -64,7 +64,7 @@ static_assert(FSM::stateId<Paused>() == 3, "");
struct Logger
: M::LoggerInterface
{
static const char* stateName(const StateID stateId) {
static const char* stateName(const StateID stateId) noexcept {
switch (stateId) {
case 1:
return "Idle";
Expand All @@ -81,7 +81,7 @@ struct Logger
void recordTransition(Context& /*context*/,
const StateID origin,
const TransitionType /*transition*/,
const StateID target) override
const StateID target) noexcept override
{
std::cout << stateName(origin) << " -> " << stateName(target) << "\n";
}
Expand All @@ -94,7 +94,7 @@ struct Base
: FSM::State
{
template <typename Event>
void react(const Event&, FullControl&) {
void react(const Event&, FullControl&) noexcept {
std::cout << "[unsupported transition]\n";
}
};
Expand All @@ -105,7 +105,7 @@ struct Idle
{
using Base::react;

void react(const Play& event, FullControl& control) {
void react(const Play& event, FullControl& control) noexcept {
control.context() = event.title;
control.changeTo<Playing>();
}
Expand All @@ -116,11 +116,11 @@ struct Playing
{
using Base::react;

void react(const Pause&, FullControl& control) {
void react(const Pause&, FullControl& control) noexcept {
control.changeTo<Paused>();
}

void react(const Stop&, FullControl& control) {
void react(const Stop&, FullControl& control) noexcept {
control.changeTo<Idle>();
}
};
Expand All @@ -130,39 +130,40 @@ struct Paused
{
using Base::react;

void react(const Resume&, FullControl& control) {
void react(const Resume&, FullControl& control) noexcept {
control.changeTo<Playing>();
}

void react(const Stop&, FullControl& control) {
void react(const Stop&, FullControl& control) noexcept {
control.changeTo<Idle>();
}
};

//------------------------------------------------------------------------------

int main() {
int
main() noexcept {
// construct everything
Context title;
Logger logger;
FSM::Instance machine(title, &logger);

// do the work :)
machine.react(Play{"any"});
machine.react(Stop{});
machine.react(Play{"any"}); // Idle -> Playing
machine.react(Stop{}); // Playing -> Idle

machine.react(Play{"optional"});
machine.react(Pause{});
machine.react(Stop{});
machine.react(Play{"optional"}); // Idle -> Playing
machine.react(Pause{}); // Playing -> Paused
machine.react(Stop{}); // Paused -> Idle

machine.react(Play{"variant"});
machine.react(Pause{}); //-V760
machine.react(Resume{});
machine.react(Stop{});
machine.react(Play{"variant"}); // Idle -> Playing
machine.react(Pause{}); //-V760 // Playing -> Paused
machine.react(Resume{}); // Paused -> Playing
machine.react(Stop{}); // Playing -> Idle

machine.react(Pause{});
machine.react(Resume{});
machine.react(Stop{});
machine.react(Pause{}); // [unsupported transition]
machine.react(Resume{}); // [unsupported transition]
machine.react(Stop{}); // [unsupported transition]

return 0;
}
Expand Down
26 changes: 13 additions & 13 deletions examples/basic_traffic_light/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// HFSM (hierarchical state machine for games and interactive applications)
// HFSM2 (hierarchical state machine for games and interactive applications)
// Created by Andrew Gresyk
//
// Traffic light example:
Expand Down Expand Up @@ -42,7 +42,7 @@

// data shared between FSM states and outside code
struct Context {
unsigned cycleCount;
unsigned cycleCount = 0;
};

// convenience typedef
Expand Down Expand Up @@ -110,7 +110,7 @@ struct On
: FSM::State // necessary boilerplate!
{
// called on state entry
void enter(Control& control) {
void enter(Control& control) noexcept {
control.context().cycleCount = 0;
std::cout << "On" << std::endl;
}
Expand All @@ -122,13 +122,13 @@ struct On
struct Red
: FSM::State
{
void enter(Control& control) {
void enter(Control& control) noexcept {
++control.context().cycleCount;
std::cout << " Red" << std::endl;
}

// state can initiate transitions to _any_ other state
void update(FullControl& control) {
void update(FullControl& control) noexcept {
// multiple transitions can be initiated, can be useful in a hierarchy
if (control.context().cycleCount > 3)
control.changeTo<Off>();
Expand All @@ -142,11 +142,11 @@ struct Red
struct YellowDownwards
: FSM::State
{
void enter(Control&) {
void enter(Control&) noexcept {
std::cout << " Yellow v" << std::endl;
}

void update(FullControl& control) {
void update(FullControl& control) noexcept {
control.changeTo<Green>();
}
};
Expand All @@ -156,11 +156,11 @@ struct YellowDownwards
struct YellowUpwards
: FSM::State
{
void enter(Control&) {
void enter(Control&) noexcept {
std::cout << " Yellow ^" << std::endl;
}

void update(FullControl& control) {
void update(FullControl& control) noexcept {
control.changeTo<Red>();
}
};
Expand All @@ -170,11 +170,11 @@ struct YellowUpwards
struct Green
: FSM::State
{
void enter(Control&) {
void enter(Control&) noexcept {
std::cout << " Green" << std::endl;
}

void update(FullControl& control) {
void update(FullControl& control) noexcept {
control.changeTo<YellowUpwards>();
}
};
Expand All @@ -185,15 +185,15 @@ struct Green
struct Off
: FSM::State
{
void enter(Control&) {
void enter(Control&) noexcept {
std::cout << "Off" << std::endl;
}
};

////////////////////////////////////////////////////////////////////////////////

int
main() {
main() noexcept {
// shared data storage instance
Context context;

Expand Down
39 changes: 20 additions & 19 deletions examples/debug_logger_interface/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// HFSM (hierarchical state machine for games and interactive applications)
// HFSM2 (hierarchical state machine for games and interactive applications)
// Created by Andrew Gresyk
//
// Attachable logger example:
Expand Down Expand Up @@ -90,7 +90,7 @@ struct Logger
{
void recordMethod(Context& /*context*/,
const hfsm2::StateID /*origin*/,
const Method method) override
const Method method) noexcept override
{
std::cout //<< hfsm2::stateName(origin) << "::"
<< hfsm2::methodName(method) << "()\n";
Expand All @@ -99,7 +99,7 @@ struct Logger
void recordTransition(Context& /*context*/,
const hfsm2::StateID /*origin*/,
const TransitionType transitionType,
const hfsm2::StateID /*target*/) override
const hfsm2::StateID /*target*/) noexcept override
{
std::cout //<< hfsm2::stateName(origin) << ": "
<< hfsm2::transitionName(transitionType) << "<"
Expand All @@ -115,12 +115,12 @@ struct Top
: FSM::State // necessary boilerplate!
{
// all state methods:
void entryGuard(GuardControl&) {} // not going to be called in this example
void enter(Control&) {}
void update(FullControl&) {}
void entryGuard(GuardControl&) noexcept {} // not going to be called in this example
void enter(Control&) noexcept {}
void update(FullControl&) noexcept {}
template <typename TEvent>
void react(const TEvent&, FullControl&) {}
void exit(Control&) {}
void react(const TEvent&, FullControl&) noexcept {}
void exit(Control&) noexcept {}
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand All @@ -130,12 +130,12 @@ struct From
: FSM::State
{
// all state methods:
void entryGuard(GuardControl&) {} // not going to be called in this example
void enter(Control&) {}
void update(FullControl&) {}
void entryGuard(GuardControl&) noexcept {} // not going to be called in this example
void enter(Control&) noexcept {}
void update(FullControl&) noexcept {}
template <typename TEvent>
void react(const TEvent&, FullControl& control) { control.changeTo<To>(); }
void exit(Control&) {}
void react(const TEvent&, FullControl& control) noexcept { control.changeTo<To>(); }
void exit(Control&) noexcept {}
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand All @@ -145,17 +145,18 @@ struct To
: FSM::State
{
// all state methods:
void entryGuard(GuardControl&) {}
void enter(Control&) {}
void update(FullControl&) {}
void entryGuard(GuardControl&) noexcept {}
void enter(Control&) noexcept {}
void update(FullControl&) noexcept {}
template <typename TEvent>
void react(const TEvent&, FullControl&) {} // not going to be called in this example
void exit(Control&) {}
void react(const TEvent&, FullControl&) noexcept {} // not going to be called in this example
void exit(Control&) noexcept {}
};

////////////////////////////////////////////////////////////////////////////////

int main() {
int
main() noexcept {
{
// logger
Logger logger;
Expand Down
Loading

0 comments on commit bb14a93

Please sign in to comment.