我是有限状态机的新手,我正在尝试理解我是否应该使用层次化的状态机,或者坚持用最简单的方式来建模我的问题的平面结构。
我有一个“分析器”,它可以停止,分析输入,分析输出,分析输入和输出,或清除。我有一些分析器状态在
enum
打电话
analyzer_states
以及在
analyzer_transitions
.
我可以使用一个层次化的状态机来更简单地建模吗?
或者是FSM没有帮助解决这个问题?
#include <iostream>
#include <cstdlib>
#include <string>
#include "fsm.h"
enum class analyzer_transitions
{
start_input,
start_output,
clear,
stop_input,
stop_output,
resume
};
enum class analyzer_states
{
analyzing_both,
analyzing_input,
analyzing_output,
clearing_both,
clearing_input,
clearing_output,
stopped,
};
inline auto output(std::string s)
{
return [s]()
{
std::cout << s << std::endl;
};
}
int main()
{
fsm<analyzer_states, analyzer_transitions> machine{ analyzer_states::stopped };
machine.add(
analyzer_states::stopped, analyzer_transitions::start_input, analyzer_states::analyzing_input,
output("-> analyzing_input"));
machine.add(
analyzer_states::stopped, analyzer_transitions::start_output, analyzer_states::analyzing_output,
output("-> analyzing_output"));
machine.add(
analyzer_states::analyzing_input, analyzer_transitions::stop_input, analyzer_states::stopped,
output("-> stopped"));
machine.add(
analyzer_states::analyzing_output, analyzer_transitions::stop_output, analyzer_states::stopped,
output("-> stopped"));
machine.add(
analyzer_states::analyzing_both, analyzer_transitions::stop_input, analyzer_states::analyzing_output,
output("-> analyzing_output"));
machine.add(
analyzer_states::analyzing_both, analyzer_transitions::stop_output, analyzer_states::analyzing_input,
output("-> analyzing_input"));
machine.add(
analyzer_states::analyzing_input, analyzer_transitions::start_output, analyzer_states::analyzing_both,
output("-> analyzing_both"));
machine.add(
analyzer_states::analyzing_output, analyzer_transitions::start_input, analyzer_states::analyzing_both,
output("-> analyzing_both"));
machine.add(
analyzer_states::analyzing_input, analyzer_transitions::clear, analyzer_states::clearing_input,
output("-> clearing_input"));
machine.add(
analyzer_states::analyzing_output, analyzer_transitions::clear, analyzer_states::clearing_output,
output("-> clearing_output"));
machine.add(
analyzer_states::analyzing_both, analyzer_transitions::clear, analyzer_states::clearing_both,
output("-> clearing_both"));
machine.add(
analyzer_states::clearing_input, analyzer_transitions::resume, analyzer_states::analyzing_input,
output("-> analyzing_input"));
machine.add(
analyzer_states::clearing_output, analyzer_transitions::resume, analyzer_states::analyzing_output,
output("-> analyzing_output"));
machine.add(
analyzer_states::clearing_both, analyzer_transitions::resume, analyzer_states::analyzing_both,
output("-> analyzing_both"));
machine.to(analyzer_transitions::start_input);
machine.to(analyzer_transitions::start_output);
machine.to(analyzer_transitions::stop_input);
machine.to(analyzer_transitions::clear);
machine.to(analyzer_transitions::resume);
std::cout << "Done...";
std::getchar();
return EXIT_SUCCESS;
}
-> analyzing_input
-> analyzing_both
-> analyzing_output
-> clearing_output
-> analyzing_output
fsm.h:高度
#include <map>
#include <functional>
#include <atomic>
template <typename State, typename Transition>
class fsm
{
using handler_t = std::function<void()>;
class from_t
{
Transition transition_;
State state_;
public:
from_t(Transition transition, State state) :
transition_{ transition },
state_{ state }
{
}
bool operator<(const from_t& other) const
{
if (transition_ < other.transition_)
{
return true;
}
else if (transition_ > other.transition_)
{
return false;
}
else
{
return state_ < other.state_;
}
}
};
class to_t
{
State state_;
handler_t handler_;
public:
to_t(State state, handler_t handler) :
state_{ state },
handler_{ handler }
{
}
State state() const { return state_; }
void operator()() const { handler_(); }
};
std::map<from_t, to_t> transitions_;
std::atomic<State> state_;
public:
fsm(State initial_state) :
state_{ initial_state }
{
}
void add(State from, Transition transition, State to, handler_t handler)
{
transitions_.insert({ { transition, from }, { to, handler } });
}
void add(State from, Transition transition, State to)
{
add(transition, to, from, [] {});
}
bool to(Transition transition)
{
auto found = transitions_.find({ transition, state_ });
if (found != transitions_.end())
{
auto& to = found->second;
state_ = to.state();
to();
return true;
}
else
{
return false;
}
}
};