Skip to content

Commit 60c1452

Browse files
committed
improved API
1 parent a3eabbd commit 60c1452

File tree

3 files changed

+157
-99
lines changed

3 files changed

+157
-99
lines changed

README.md

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,37 +82,38 @@ namespace fsm_cxx { namespace test {
8282
machine_t<my_state> m;
8383
using M = decltype(m);
8484

85+
// @formatter:off
8586
// states
86-
m.initial(my_state::Initial)
87-
.terminated(my_state::Terminated)
88-
.error(my_state::Error, [](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cerr << " .. <error> entering" << '\n'; })
89-
.state(
90-
my_state::Opened,
91-
[](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> entering" << '\n'; },
92-
[](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> exiting" << '\n'; })
93-
.state(
94-
my_state::Closed,
95-
[](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> entering" << '\n'; },
96-
[](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> exiting" << '\n'; });
87+
m.state().set(my_state::Initial).as_initial().build();
88+
m.state().set(my_state::Terminated).as_terminated().build();
89+
m.state().set(my_state::Error).as_error()
90+
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cerr << " .. <error> entering" << '\n'; })
91+
.build();
92+
m.state().set(my_state::Opened)
93+
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &) -> bool { return true; })
94+
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &p) -> bool { return p._ok; })
95+
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> entering" << '\n'; })
96+
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> exiting" << '\n'; })
97+
.build();
98+
m.state().set(my_state::Closed)
99+
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> entering" << '\n'; })
100+
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> exiting" << '\n'; })
101+
.build();
97102

98103
// transistions
99-
m.transition(my_state::Initial, begin{}, my_state::Closed);
100-
m.builder()
101-
.transition(my_state::Closed, open{}, my_state::Opened)
104+
m.transition().set(my_state::Initial, begin{}, my_state::Closed).build();
105+
m.transition()
106+
.set(my_state::Closed, open{}, my_state::Opened)
102107
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &p) -> bool { return p._ok; })
103108
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed -> opened> entering" << '\n'; })
104109
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed -> opened> exiting" << '\n'; })
105110
.build();
106-
m.transition(my_state::Opened, close{}, my_state::Closed)
107-
.transition(my_state::Closed, end{}, my_state::Terminated);
108-
m.transition(my_state::Opened,
109-
M::Transition{end{}, my_state::Terminated, nullptr,
110-
[](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <T><END>" << '\n'; },
111-
nullptr});
112-
113-
// guards
114-
m.add_guard(my_state::Opened, [](M::Event const &, M::Context &, M::State const &, M::Payload const &) -> bool { return true; });
115-
m.add_guard(my_state::Opened, [](M::Event const &, M::Context &, M::State const &, M::Payload const &p) -> bool { return p._ok; });
111+
m.transition().set(my_state::Opened, close{}, my_state::Closed).build()
112+
.transition().set(my_state::Closed, end{}, my_state::Terminated).build();
113+
m.transition().set(my_state::Opened, end{}, my_state::Terminated)
114+
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <T><END>" << '\n'; })
115+
.build();
116+
// @formatter:on
116117

117118
m.on_error([](Reason reason, M::State const &, M::Context &, M::Event const &, M::Payload const &) {
118119
std::cout << " Error: reason = " << reason << '\n';

include/fsm_cxx/fsm-sm.hh

Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -527,71 +527,125 @@ namespace fsm_cxx {
527527
using Guard = typename Transition::Guard;
528528

529529
public:
530-
machine_t &initial(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
530+
machine_t &reset() {
531+
_ctx.reset(_initial);
532+
return (*this);
533+
}
534+
535+
machine_t &on_transition(OnAction &&fn) {
536+
_on_action = fn;
537+
return (*this);
538+
}
539+
machine_t &on_error(OnErrorAction &&fn) {
540+
_on_error = fn;
541+
return (*this);
542+
}
543+
544+
protected:
545+
machine_t &initial_set(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
531546
_initial = st;
532547
_ctx.current(st);
533-
return state(st, std::move(entry_action), std::move(exit_action));
548+
return state_set(st, std::move(entry_action), std::move(exit_action));
534549
}
535-
machine_t &terminated(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
550+
machine_t &terminated_set(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
536551
_terminated = st;
537-
return state(st, std::move(entry_action), std::move(exit_action));
552+
return state_set(st, std::move(entry_action), std::move(exit_action));
538553
}
539-
machine_t &error(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
554+
machine_t &error_set(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
540555
_error = st;
541-
return state(st, std::move(entry_action), std::move(exit_action));
556+
return state_set(st, std::move(entry_action), std::move(exit_action));
542557
}
543558

544-
machine_t &state(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
559+
machine_t &state_set(S st, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
545560
Actions actions{std::move(entry_action), std::move(exit_action)};
546561
if (actions.valid())
547562
_state_actions.emplace(StateT{st}, std::move(actions));
548563
return (*this);
549564
}
550565

551566
template<typename _Callable, typename... _Args>
552-
machine_t &add_guard(State const &st, _Callable &&f, _Args &&...args) {
567+
machine_t &guard_add(State const &st, _Callable &&f, _Args &&...args) {
553568
_ctx.add_guard(st, std::forward<_Callable>(f), std::forward<_Args>(args)...);
554569
return (*this);
555570
}
556571

557-
machine_t &reset() {
558-
_ctx.reset(_initial);
559-
return (*this);
560-
}
561-
562572
template<typename Evt>
563-
machine_t &transition(S from, Evt const &, S to, Guard &&p = nullptr, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
573+
machine_t &transition_set(S from, Evt const &, S to, Guard &&p = nullptr, ActionT &&entry_action = nullptr, ActionT &&exit_action = nullptr) {
564574
auto event_name = std::string{fsm_cxx::debug::type_name<Evt>()};
565575
Transition t{event_name, to, std::move(p), std::move(entry_action), std::move(exit_action)};
566-
return transition(from, std::move(t));
576+
return transition_set(from, std::move(t));
567577
}
568-
machine_t &transition(S from, Transition &&trans) {
578+
machine_t &transition_set(S from, Transition &&trans) {
569579
State f{from};
570-
return transition(f, std::forward<Transition>(trans));
571-
}
572-
// machine_t &transition(S from, Transition const &trans) {
573-
// if (auto it = _trans_tbl.find(State{from}); it == _trans_tbl.end())
574-
// _trans_tbl.insert({State{from}, trans});
575-
// else
576-
// it->second.add(trans);
577-
// return (*this);
578-
// }
579-
machine_t &transition(State const &from, Transition &&trans) {
580+
return transition_set(f, std::forward<Transition>(trans));
581+
}
582+
machine_t &transition_set(State const &from, Transition &&trans) {
580583
if (auto it = _trans_tbl.find(from); it == _trans_tbl.end())
581584
_trans_tbl.emplace(from, std::move(trans));
582585
else
583586
it->second.add(std::forward<Transition>(trans));
584587
return (*this);
585588
}
586589

587-
machine_t &on_transition(OnAction &&fn) {
588-
_on_action = fn;
589-
return (*this);
590-
}
591-
machine_t &on_error(OnErrorAction &&fn) {
592-
_on_error = fn;
593-
return (*this);
594-
}
590+
public:
591+
class state_builder {
592+
machine_t &owner;
593+
S st{};
594+
std::vector<Guard> guard_fn{};
595+
Action entry_fn{nullptr};
596+
Action exit_fn{nullptr};
597+
bool initial_, terminated_, error_;
598+
599+
public:
600+
state_builder(machine_t &tt)
601+
: owner(tt) {}
602+
machine_t &build() {
603+
if (initial_) {
604+
return owner.initial_set(st, std::move(entry_fn), std::move(exit_fn));
605+
} else if (terminated_) {
606+
return owner.terminated_set(st, std::move(entry_fn), std::move(exit_fn));
607+
} else if (error_) {
608+
return owner.error_set(st, std::move(entry_fn), std::move(exit_fn));
609+
}
610+
for (auto &fn : guard_fn)
611+
owner.guard_add(st, fn);
612+
return owner.state_set(st, std::move(entry_fn), std::move(exit_fn));
613+
}
614+
state_builder &set(S s) {
615+
st = s;
616+
return (*this);
617+
}
618+
state_builder &as_initial() {
619+
initial_ = true;
620+
error_ = terminated_ = false;
621+
return (*this);
622+
}
623+
state_builder &as_terminated() {
624+
terminated_ = true;
625+
error_ = initial_ = false;
626+
return (*this);
627+
}
628+
state_builder &as_error() {
629+
error_ = true;
630+
initial_ = terminated_ = false;
631+
return (*this);
632+
}
633+
state_builder &guard(Guard &&fn) {
634+
guard_fn.emplace_back(fn);
635+
return (*this);
636+
}
637+
template<typename _Callable, typename... _Args>
638+
state_builder &entry_action(_Callable &&f, _Args &&...args) {
639+
entry_fn.update(f, args...);
640+
return (*this);
641+
}
642+
template<typename _Callable, typename... _Args>
643+
state_builder &exit_action(_Callable &&f, _Args &&...args) {
644+
exit_fn.update(f, args...);
645+
return (*this);
646+
}
647+
};
648+
state_builder state() { return state_builder(*this); }
595649

596650
public:
597651
class transition_builder {
@@ -606,10 +660,10 @@ namespace fsm_cxx {
606660
public:
607661
transition_builder(machine_t &tt)
608662
: owner(tt) {}
609-
void build() { owner.transition(from, Transition{event_name, to, std::move(guard_fn), std::move(entry_fn), std::move(exit_fn)}); }
663+
machine_t &build() { return owner.transition_set(from, Transition{event_name, to, std::move(guard_fn), std::move(entry_fn), std::move(exit_fn)}); }
610664
template<typename Evt,
611665
std::enable_if_t<std::is_base_of<Event, std::decay_t<Evt>>::value && !std::is_same<Evt, std::string>::value, bool> = true>
612-
transition_builder &transition(S from_, Evt const &, S to_) {
666+
transition_builder &set(S from_, Evt const &, S to_) {
613667
from = from_;
614668
event_name = std::string{fsm_cxx::debug::type_name<Evt>()};
615669
to = to_;
@@ -630,7 +684,7 @@ namespace fsm_cxx {
630684
return (*this);
631685
}
632686
};
633-
transition_builder builder() { return transition_builder(*this); }
687+
transition_builder transition() { return transition_builder(*this); }
634688

635689
public:
636690
template<typename Evt,

0 commit comments

Comments
 (0)