mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
Extract States & Transitions to own header, use in plugins
This commit is contained in:
parent
8bb6a9518a
commit
4487b81de8
|
@ -28,7 +28,6 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||||
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
DESTINATION ${PROJECT_INSTALL_INCDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# Tools #
|
# Tools #
|
||||||
#########
|
#########
|
||||||
|
@ -92,10 +91,12 @@ if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||||
|
|
||||||
set(FSM_PUBLIC_HEADER_FILES
|
set(FSM_PUBLIC_HEADER_FILES
|
||||||
StateMachine.h
|
StateMachine.h
|
||||||
|
States.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FSM_SOURCE_FILES
|
set(FSM_SOURCE_FILES
|
||||||
StateMachine.cxx
|
StateMachine.cxx
|
||||||
|
States.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(${target}
|
add_library(${target}
|
||||||
|
|
|
@ -491,7 +491,7 @@ class FairMQDevice
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
|
bool ChangeState(const fair::mq::Transition transition) { return fStateMachine.ChangeState(transition); }
|
||||||
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::StateMachine::GetTransition(transition)); }
|
bool ChangeState(const std::string& transition) { return fStateMachine.ChangeState(fair::mq::GetTransition(transition)); }
|
||||||
|
|
||||||
bool ChangeState(const int transition) __attribute__((deprecated("Use ChangeState(const fair::mq::Transition transition).")));
|
bool ChangeState(const int transition) __attribute__((deprecated("Use ChangeState(const fair::mq::Transition transition).")));
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ class FairMQDevice
|
||||||
|
|
||||||
fair::mq::State WaitForNextState();
|
fair::mq::State WaitForNextState();
|
||||||
void WaitForState(fair::mq::State state);
|
void WaitForState(fair::mq::State state);
|
||||||
void WaitForState(const std::string& state) { WaitForState(fair::mq::StateMachine::GetState(state)); }
|
void WaitForState(const std::string& state) { WaitForState(fair::mq::GetState(state)); }
|
||||||
|
|
||||||
void TransitionTo(const fair::mq::State state);
|
void TransitionTo(const fair::mq::State state);
|
||||||
|
|
||||||
|
@ -519,8 +519,8 @@ class FairMQDevice
|
||||||
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
fair::mq::State GetCurrentState() const { return fStateMachine.GetCurrentState(); }
|
||||||
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
std::string GetCurrentStateName() const { return fStateMachine.GetCurrentStateName(); }
|
||||||
|
|
||||||
static std::string GetStateName(const fair::mq::State state) { return fair::mq::StateMachine::GetStateName(state); }
|
static std::string GetStateName(const fair::mq::State state) { return fair::mq::GetStateName(state); }
|
||||||
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::StateMachine::GetTransitionName(transition); }
|
static std::string GetTransitionName(const fair::mq::Transition transition) { return fair::mq::GetTransitionName(transition); }
|
||||||
|
|
||||||
struct DeviceStateError : std::runtime_error { using std::runtime_error::runtime_error; };
|
struct DeviceStateError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
|
||||||
|
|
|
@ -11,135 +11,20 @@
|
||||||
using namespace fair::mq;
|
using namespace fair::mq;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const unordered_map<string, PluginServices::DeviceState> PluginServices::fkDeviceStateStrMap = {
|
|
||||||
{"OK", DeviceState::Ok},
|
|
||||||
{"ERROR", DeviceState::Error},
|
|
||||||
{"IDLE", DeviceState::Idle},
|
|
||||||
{"INITIALIZING DEVICE", DeviceState::InitializingDevice},
|
|
||||||
{"INITIALIZED", DeviceState::Initialized},
|
|
||||||
{"BINDING", DeviceState::Binding},
|
|
||||||
{"BOUND", DeviceState::Bound},
|
|
||||||
{"CONNECTING", DeviceState::Connecting},
|
|
||||||
{"DEVICE READY", DeviceState::DeviceReady},
|
|
||||||
{"INITIALIZING TASK", DeviceState::InitializingTask},
|
|
||||||
{"READY", DeviceState::Ready},
|
|
||||||
{"RUNNING", DeviceState::Running},
|
|
||||||
{"RESETTING TASK", DeviceState::ResettingTask},
|
|
||||||
{"RESETTING DEVICE", DeviceState::ResettingDevice},
|
|
||||||
{"EXITING", DeviceState::Exiting}
|
|
||||||
};
|
|
||||||
const unordered_map<PluginServices::DeviceState, string, tools::HashEnum<PluginServices::DeviceState>> PluginServices::fkStrDeviceStateMap = {
|
|
||||||
{DeviceState::Ok, "OK"},
|
|
||||||
{DeviceState::Error, "ERROR"},
|
|
||||||
{DeviceState::Idle, "IDLE"},
|
|
||||||
{DeviceState::InitializingDevice, "INITIALIZING DEVICE"},
|
|
||||||
{DeviceState::Initialized, "INITIALIZED"},
|
|
||||||
{DeviceState::Binding, "BINDING"},
|
|
||||||
{DeviceState::Bound, "BOUND"},
|
|
||||||
{DeviceState::Connecting, "CONNECTING"},
|
|
||||||
{DeviceState::DeviceReady, "DEVICE READY"},
|
|
||||||
{DeviceState::InitializingTask, "INITIALIZING TASK"},
|
|
||||||
{DeviceState::Ready, "READY"},
|
|
||||||
{DeviceState::Running, "RUNNING"},
|
|
||||||
{DeviceState::ResettingTask, "RESETTING TASK"},
|
|
||||||
{DeviceState::ResettingDevice, "RESETTING DEVICE"},
|
|
||||||
{DeviceState::Exiting, "EXITING"}
|
|
||||||
};
|
|
||||||
const unordered_map<string, PluginServices::DeviceStateTransition> PluginServices::fkDeviceStateTransitionStrMap = {
|
|
||||||
{"AUTO", DeviceStateTransition::Auto},
|
|
||||||
{"INIT DEVICE", DeviceStateTransition::InitDevice},
|
|
||||||
{"COMPLETE INIT", DeviceStateTransition::CompleteInit},
|
|
||||||
{"BIND", DeviceStateTransition::Bind},
|
|
||||||
{"CONNECT", DeviceStateTransition::Connect},
|
|
||||||
{"INIT TASK", DeviceStateTransition::InitTask},
|
|
||||||
{"RUN", DeviceStateTransition::Run},
|
|
||||||
{"STOP", DeviceStateTransition::Stop},
|
|
||||||
{"RESET TASK", DeviceStateTransition::ResetTask},
|
|
||||||
{"RESET DEVICE", DeviceStateTransition::ResetDevice},
|
|
||||||
{"END", DeviceStateTransition::End},
|
|
||||||
{"ERROR FOUND", DeviceStateTransition::ErrorFound},
|
|
||||||
};
|
|
||||||
const unordered_map<PluginServices::DeviceStateTransition, string, tools::HashEnum<PluginServices::DeviceStateTransition>> PluginServices::fkStrDeviceStateTransitionMap = {
|
|
||||||
{DeviceStateTransition::Auto, "Auto"},
|
|
||||||
{DeviceStateTransition::InitDevice, "INIT DEVICE"},
|
|
||||||
{DeviceStateTransition::CompleteInit, "COMPLETE INIT"},
|
|
||||||
{DeviceStateTransition::Bind, "BIND"},
|
|
||||||
{DeviceStateTransition::Connect, "CONNECT"},
|
|
||||||
{DeviceStateTransition::InitTask, "INIT TASK"},
|
|
||||||
{DeviceStateTransition::Run, "RUN"},
|
|
||||||
{DeviceStateTransition::Stop, "STOP"},
|
|
||||||
{DeviceStateTransition::ResetTask, "RESET TASK"},
|
|
||||||
{DeviceStateTransition::ResetDevice, "RESET DEVICE"},
|
|
||||||
{DeviceStateTransition::End, "END"},
|
|
||||||
{DeviceStateTransition::ErrorFound, "ERROR FOUND"},
|
|
||||||
};
|
|
||||||
const unordered_map<State, PluginServices::DeviceState, tools::HashEnum<State>> PluginServices::fkDeviceStateMap = {
|
|
||||||
{State::Ok, DeviceState::Ok},
|
|
||||||
{State::Error, DeviceState::Error},
|
|
||||||
{State::Idle, DeviceState::Idle},
|
|
||||||
{State::InitializingDevice, DeviceState::InitializingDevice},
|
|
||||||
{State::Initialized, DeviceState::Initialized},
|
|
||||||
{State::Binding, DeviceState::Binding},
|
|
||||||
{State::Bound, DeviceState::Bound},
|
|
||||||
{State::Connecting, DeviceState::Connecting},
|
|
||||||
{State::DeviceReady, DeviceState::DeviceReady},
|
|
||||||
{State::InitializingTask, DeviceState::InitializingTask},
|
|
||||||
{State::Ready, DeviceState::Ready},
|
|
||||||
{State::Running, DeviceState::Running},
|
|
||||||
{State::ResettingTask, DeviceState::ResettingTask},
|
|
||||||
{State::ResettingDevice, DeviceState::ResettingDevice},
|
|
||||||
{State::Exiting, DeviceState::Exiting}
|
|
||||||
};
|
|
||||||
const unordered_map<PluginServices::DeviceState, State> PluginServices::fkStateMap = {
|
|
||||||
{DeviceState::Ok, State::Ok},
|
|
||||||
{DeviceState::Error, State::Error},
|
|
||||||
{DeviceState::Idle, State::Idle},
|
|
||||||
{DeviceState::InitializingDevice, State::InitializingDevice},
|
|
||||||
{DeviceState::Initialized, State::Initialized},
|
|
||||||
{DeviceState::Binding, State::Binding},
|
|
||||||
{DeviceState::Bound, State::Bound},
|
|
||||||
{DeviceState::Connecting, State::Connecting},
|
|
||||||
{DeviceState::DeviceReady, State::DeviceReady},
|
|
||||||
{DeviceState::InitializingTask, State::InitializingTask},
|
|
||||||
{DeviceState::Ready, State::Ready},
|
|
||||||
{DeviceState::Running, State::Running},
|
|
||||||
{DeviceState::ResettingTask, State::ResettingTask},
|
|
||||||
{DeviceState::ResettingDevice, State::ResettingDevice},
|
|
||||||
{DeviceState::Exiting, State::Exiting}
|
|
||||||
};
|
|
||||||
const unordered_map<PluginServices::DeviceStateTransition, Transition, tools::HashEnum<PluginServices::DeviceStateTransition>> PluginServices::fkDeviceStateTransitionMap = {
|
|
||||||
{DeviceStateTransition::Auto, Transition::Auto},
|
|
||||||
{DeviceStateTransition::InitDevice, Transition::InitDevice},
|
|
||||||
{DeviceStateTransition::CompleteInit, Transition::CompleteInit},
|
|
||||||
{DeviceStateTransition::Bind, Transition::Bind},
|
|
||||||
{DeviceStateTransition::Connect, Transition::Connect},
|
|
||||||
{DeviceStateTransition::InitTask, Transition::InitTask},
|
|
||||||
{DeviceStateTransition::Run, Transition::Run},
|
|
||||||
{DeviceStateTransition::Stop, Transition::Stop},
|
|
||||||
{DeviceStateTransition::ResetTask, Transition::ResetTask},
|
|
||||||
{DeviceStateTransition::ResetDevice, Transition::ResetDevice},
|
|
||||||
{DeviceStateTransition::End, Transition::End},
|
|
||||||
{DeviceStateTransition::ErrorFound, Transition::ErrorFound}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto PluginServices::ChangeDeviceState(const string& controller, const DeviceStateTransition next) -> bool
|
auto PluginServices::ChangeDeviceState(const string& controller, const DeviceStateTransition next) -> bool
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock{fDeviceControllerMutex};
|
lock_guard<mutex> lock{fDeviceControllerMutex};
|
||||||
|
|
||||||
if (!fDeviceController) fDeviceController = controller;
|
if (!fDeviceController) fDeviceController = controller;
|
||||||
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (fDeviceController == controller) {
|
if (fDeviceController == controller) {
|
||||||
result = fDevice.ChangeState(fkDeviceStateTransitionMap.at(next));
|
return fDevice.ChangeState(next);
|
||||||
} else {
|
} else {
|
||||||
throw DeviceControlError{tools::ToString(
|
throw DeviceControlError{tools::ToString(
|
||||||
"Plugin '", controller, "' is not allowed to change device states. ",
|
"Plugin '", controller, "' is not allowed to change device states. ",
|
||||||
"Currently, plugin '", *fDeviceController, "' has taken control."
|
"Currently, plugin '", *fDeviceController, "' has taken control."
|
||||||
)};
|
)};
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginServices::TransitionDeviceStateTo(const std::string& controller, DeviceState state)
|
void PluginServices::TransitionDeviceStateTo(const std::string& controller, DeviceState state)
|
||||||
|
@ -149,7 +34,7 @@ void PluginServices::TransitionDeviceStateTo(const std::string& controller, Devi
|
||||||
if (!fDeviceController) fDeviceController = controller;
|
if (!fDeviceController) fDeviceController = controller;
|
||||||
|
|
||||||
if (fDeviceController == controller) {
|
if (fDeviceController == controller) {
|
||||||
fDevice.TransitionTo(fkStateMap.at(state));
|
fDevice.TransitionTo(state);
|
||||||
} else {
|
} else {
|
||||||
throw DeviceControlError{tools::ToString(
|
throw DeviceControlError{tools::ToString(
|
||||||
"Plugin '", controller, "' is not allowed to change device states. ",
|
"Plugin '", controller, "' is not allowed to change device states. ",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define FAIR_MQ_PLUGINSERVICES_H
|
#define FAIR_MQ_PLUGINSERVICES_H
|
||||||
|
|
||||||
#include <fairmq/Tools.h>
|
#include <fairmq/Tools.h>
|
||||||
|
#include <fairmq/States.h>
|
||||||
#include <FairMQDevice.h>
|
#include <FairMQDevice.h>
|
||||||
#include <fairmq/ProgOptions.h>
|
#include <fairmq/ProgOptions.h>
|
||||||
#include <fairmq/Properties.h>
|
#include <fairmq/Properties.h>
|
||||||
|
@ -58,41 +59,8 @@ class PluginServices
|
||||||
PluginServices(const PluginServices&) = delete;
|
PluginServices(const PluginServices&) = delete;
|
||||||
PluginServices operator=(const PluginServices&) = delete;
|
PluginServices operator=(const PluginServices&) = delete;
|
||||||
|
|
||||||
/// See https://github.com/FairRootGroup/FairRoot/blob/dev/fairmq/docs/Device.md#13-state-machine
|
using DeviceState = fair::mq::State;
|
||||||
enum class DeviceState : int
|
using DeviceStateTransition = fair::mq::Transition;
|
||||||
{
|
|
||||||
Ok,
|
|
||||||
Error,
|
|
||||||
Idle,
|
|
||||||
InitializingDevice,
|
|
||||||
Initialized,
|
|
||||||
Binding,
|
|
||||||
Bound,
|
|
||||||
Connecting,
|
|
||||||
DeviceReady,
|
|
||||||
InitializingTask,
|
|
||||||
Ready,
|
|
||||||
Running,
|
|
||||||
ResettingTask,
|
|
||||||
ResettingDevice,
|
|
||||||
Exiting
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class DeviceStateTransition : int // transition event between DeviceStates
|
|
||||||
{
|
|
||||||
Auto,
|
|
||||||
InitDevice,
|
|
||||||
CompleteInit,
|
|
||||||
Bind,
|
|
||||||
Connect,
|
|
||||||
InitTask,
|
|
||||||
Run,
|
|
||||||
Stop,
|
|
||||||
ResetTask,
|
|
||||||
ResetDevice,
|
|
||||||
End,
|
|
||||||
ErrorFound
|
|
||||||
};
|
|
||||||
|
|
||||||
// Control API
|
// Control API
|
||||||
|
|
||||||
|
@ -100,29 +68,26 @@ class PluginServices
|
||||||
/// @param state to convert
|
/// @param state to convert
|
||||||
/// @return DeviceState enum entry
|
/// @return DeviceState enum entry
|
||||||
/// @throw std::out_of_range if a string cannot be resolved to a DeviceState
|
/// @throw std::out_of_range if a string cannot be resolved to a DeviceState
|
||||||
static auto ToDeviceState(const std::string& state) -> DeviceState { return fkDeviceStateStrMap.at(state); }
|
static auto ToDeviceState(const std::string& state) -> DeviceState { return GetState(state); }
|
||||||
|
|
||||||
/// @brief Convert string to DeviceStateTransition
|
/// @brief Convert string to DeviceStateTransition
|
||||||
/// @param transition to convert
|
/// @param transition to convert
|
||||||
/// @return DeviceStateTransition enum entry
|
/// @return DeviceStateTransition enum entry
|
||||||
/// @throw std::out_of_range if a string cannot be resolved to a DeviceStateTransition
|
/// @throw std::out_of_range if a string cannot be resolved to a DeviceStateTransition
|
||||||
static auto ToDeviceStateTransition(const std::string& transition) -> DeviceStateTransition { return fkDeviceStateTransitionStrMap.at(transition); }
|
static auto ToDeviceStateTransition(const std::string& transition) -> DeviceStateTransition { return GetTransition(transition); }
|
||||||
|
|
||||||
/// @brief Convert DeviceState to string
|
/// @brief Convert DeviceState to string
|
||||||
/// @param state to convert
|
/// @param state to convert
|
||||||
/// @return string representation of DeviceState enum entry
|
/// @return string representation of DeviceState enum entry
|
||||||
static auto ToStr(DeviceState state) -> std::string { return fkStrDeviceStateMap.at(state); }
|
static auto ToStr(DeviceState state) -> std::string { return GetStateName(state); }
|
||||||
|
|
||||||
/// @brief Convert DeviceStateTransition to string
|
/// @brief Convert DeviceStateTransition to string
|
||||||
/// @param transition to convert
|
/// @param transition to convert
|
||||||
/// @return string representation of DeviceStateTransition enum entry
|
/// @return string representation of DeviceStateTransition enum entry
|
||||||
static auto ToStr(DeviceStateTransition transition) -> std::string { return fkStrDeviceStateTransitionMap.at(transition); }
|
static auto ToStr(DeviceStateTransition transition) -> std::string { return GetTransitionName(transition); }
|
||||||
|
|
||||||
friend auto operator<<(std::ostream& os, const DeviceState& state) -> std::ostream& { return os << ToStr(state); }
|
|
||||||
friend auto operator<<(std::ostream& os, const DeviceStateTransition& transition) -> std::ostream& { return os << ToStr(transition); }
|
|
||||||
|
|
||||||
/// @return current device state
|
/// @return current device state
|
||||||
auto GetCurrentDeviceState() const -> DeviceState { return fkDeviceStateMap.at(static_cast<fair::mq::State>(fDevice.GetCurrentState())); }
|
auto GetCurrentDeviceState() const -> DeviceState { return fDevice.GetCurrentState(); }
|
||||||
|
|
||||||
/// @brief Become device controller
|
/// @brief Become device controller
|
||||||
/// @param controller id
|
/// @param controller id
|
||||||
|
@ -171,7 +136,7 @@ class PluginServices
|
||||||
auto SubscribeToDeviceStateChange(const std::string& subscriber, std::function<void(DeviceState /*newState*/)> callback) -> void
|
auto SubscribeToDeviceStateChange(const std::string& subscriber, std::function<void(DeviceState /*newState*/)> callback) -> void
|
||||||
{
|
{
|
||||||
fDevice.SubscribeToStateChange(subscriber, [&,callback](fair::mq::State newState){
|
fDevice.SubscribeToStateChange(subscriber, [&,callback](fair::mq::State newState){
|
||||||
callback(fkDeviceStateMap.at(newState));
|
callback(newState);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,14 +275,6 @@ class PluginServices
|
||||||
/// @brief Decreases logging verbosity, or sets it to highest if it is already lowest
|
/// @brief Decreases logging verbosity, or sets it to highest if it is already lowest
|
||||||
auto CycleLogVerbosityDown() -> void { Logger::CycleVerbosityDown(); }
|
auto CycleLogVerbosityDown() -> void { Logger::CycleVerbosityDown(); }
|
||||||
|
|
||||||
static const std::unordered_map<std::string, DeviceState> fkDeviceStateStrMap;
|
|
||||||
static const std::unordered_map<DeviceState, std::string, tools::HashEnum<DeviceState>> fkStrDeviceStateMap;
|
|
||||||
static const std::unordered_map<std::string, DeviceStateTransition> fkDeviceStateTransitionStrMap;
|
|
||||||
static const std::unordered_map<DeviceStateTransition, std::string, tools::HashEnum<DeviceStateTransition>> fkStrDeviceStateTransitionMap;
|
|
||||||
static const std::unordered_map<fair::mq::State, DeviceState, tools::HashEnum<fair::mq::State>> fkDeviceStateMap;
|
|
||||||
static const std::unordered_map<DeviceState, fair::mq::State> fkStateMap;
|
|
||||||
static const std::unordered_map<DeviceStateTransition, fair::mq::Transition, tools::HashEnum<DeviceStateTransition>> fkDeviceStateTransitionMap;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fair::mq::ProgOptions& fConfig;
|
fair::mq::ProgOptions& fConfig;
|
||||||
FairMQDevice& fDevice;
|
FairMQDevice& fDevice;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* copied verbatim in the file "LICENSE" *
|
* copied verbatim in the file "LICENSE" *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include "StateMachine.h"
|
#include <fairmq/StateMachine.h>
|
||||||
#include <fairmq/Tools.h>
|
#include <fairmq/Tools.h>
|
||||||
|
|
||||||
// Increase maximum number of boost::msm states (default is 10)
|
// Increase maximum number of boost::msm states (default is 10)
|
||||||
|
@ -25,10 +25,8 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <array>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost::msm;
|
using namespace boost::msm;
|
||||||
|
@ -76,80 +74,6 @@ struct RESET_DEVICE_E { static string Name() { return "RESET_DEVICE"; } static
|
||||||
struct END_E { static string Name() { return "END"; } static Transition Type() { return Transition::End; } };
|
struct END_E { static string Name() { return "END"; } static Transition Type() { return Transition::End; } };
|
||||||
struct ERROR_FOUND_E { static string Name() { return "ERROR_FOUND"; } static Transition Type() { return Transition::ErrorFound; } };
|
struct ERROR_FOUND_E { static string Name() { return "ERROR_FOUND"; } static Transition Type() { return Transition::ErrorFound; } };
|
||||||
|
|
||||||
static array<string, 15> stateNames =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"OK",
|
|
||||||
"Error",
|
|
||||||
"IDLE",
|
|
||||||
"INITIALIZING_DEVICE",
|
|
||||||
"INITIALIZED",
|
|
||||||
"BINDING",
|
|
||||||
"BOUND",
|
|
||||||
"CONNECTING",
|
|
||||||
"DEVICE_READY",
|
|
||||||
"INITIALIZING_TASK",
|
|
||||||
"READY",
|
|
||||||
"RUNNING",
|
|
||||||
"RESETTING_TASK",
|
|
||||||
"RESETTING_DEVICE",
|
|
||||||
"EXITING"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static array<string, 12> transitionNames =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"AUTO",
|
|
||||||
"INIT_DEVICE",
|
|
||||||
"COMPLETE_INIT",
|
|
||||||
"BIND",
|
|
||||||
"CONNECT",
|
|
||||||
"INIT_TASK",
|
|
||||||
"RUN",
|
|
||||||
"STOP",
|
|
||||||
"RESET_TASK",
|
|
||||||
"RESET_DEVICE",
|
|
||||||
"END",
|
|
||||||
"ERROR_FOUND"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static map<string, State> stateNumbers =
|
|
||||||
{
|
|
||||||
{ "OK", State::Ok },
|
|
||||||
{ "Error", State::Error },
|
|
||||||
{ "IDLE", State::Idle },
|
|
||||||
{ "INITIALIZING_DEVICE", State::InitializingDevice },
|
|
||||||
{ "INITIALIZED", State::Initialized },
|
|
||||||
{ "BINDING", State::Binding },
|
|
||||||
{ "BOUND", State::Bound },
|
|
||||||
{ "CONNECTING", State::Connecting },
|
|
||||||
{ "DEVICE_READY", State::DeviceReady },
|
|
||||||
{ "INITIALIZING_TASK", State::InitializingTask },
|
|
||||||
{ "READY", State::Ready },
|
|
||||||
{ "RUNNING", State::Running },
|
|
||||||
{ "RESETTING_TASK", State::ResettingTask },
|
|
||||||
{ "RESETTING_DEVICE", State::ResettingDevice },
|
|
||||||
{ "EXITING", State::Exiting }
|
|
||||||
};
|
|
||||||
|
|
||||||
static map<string, Transition> transitionNumbers =
|
|
||||||
{
|
|
||||||
{ "AUTO", Transition::Auto },
|
|
||||||
{ "INIT_DEVICE", Transition::InitDevice },
|
|
||||||
{ "COMPLETE_INIT", Transition::CompleteInit },
|
|
||||||
{ "BIND", Transition::Bind },
|
|
||||||
{ "CONNECT", Transition::Connect },
|
|
||||||
{ "INIT_TASK", Transition::InitTask },
|
|
||||||
{ "RUN", Transition::Run },
|
|
||||||
{ "STOP", Transition::Stop },
|
|
||||||
{ "RESET_TASK", Transition::ResetTask },
|
|
||||||
{ "RESET_DEVICE", Transition::ResetDevice },
|
|
||||||
{ "END", Transition::End },
|
|
||||||
{ "ERROR_FOUND", Transition::ErrorFound }
|
|
||||||
};
|
|
||||||
|
|
||||||
// defining the boost MSM state machine
|
// defining the boost MSM state machine
|
||||||
struct Machine_ : public state_machine_def<Machine_>
|
struct Machine_ : public state_machine_def<Machine_>
|
||||||
{
|
{
|
||||||
|
@ -369,7 +293,7 @@ try {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(state) << "Transition " << transitionNames.at(static_cast<int>(transition)) << " incoming, but another state transition is already ongoing.";
|
LOG(state) << "Transition " << GetTransitionName(transition) << " incoming, but another state transition is already ongoing.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (exception& e) {
|
} catch (exception& e) {
|
||||||
|
@ -461,9 +385,3 @@ void StateMachine::ProcessWork()
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string StateMachine::GetStateName(const State state) { return stateNames.at(static_cast<int>(state)); }
|
|
||||||
string StateMachine::GetTransitionName(const Transition transition) { return transitionNames.at(static_cast<int>(transition)); }
|
|
||||||
State StateMachine::GetState(const string& state) { return stateNumbers.at(state); }
|
|
||||||
Transition StateMachine::GetTransition(const string& transition) { return transitionNumbers.at(transition); }
|
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,13 @@
|
||||||
#ifndef FAIRMQSTATEMACHINE_H_
|
#ifndef FAIRMQSTATEMACHINE_H_
|
||||||
#define FAIRMQSTATEMACHINE_H_
|
#define FAIRMQSTATEMACHINE_H_
|
||||||
|
|
||||||
|
#include <fairmq/States.h>
|
||||||
|
|
||||||
#include <fairlogger/Logger.h>
|
#include <fairlogger/Logger.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <condition_variable>
|
|
||||||
#include <ostream>
|
|
||||||
#include <queue>
|
|
||||||
#include <mutex>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace fair
|
namespace fair
|
||||||
|
@ -25,41 +23,6 @@ namespace fair
|
||||||
namespace mq
|
namespace mq
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class State : int
|
|
||||||
{
|
|
||||||
Ok,
|
|
||||||
Error,
|
|
||||||
Idle,
|
|
||||||
InitializingDevice,
|
|
||||||
Initialized,
|
|
||||||
Binding,
|
|
||||||
Bound,
|
|
||||||
Connecting,
|
|
||||||
DeviceReady,
|
|
||||||
InitializingTask,
|
|
||||||
Ready,
|
|
||||||
Running,
|
|
||||||
ResettingTask,
|
|
||||||
ResettingDevice,
|
|
||||||
Exiting
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Transition : int
|
|
||||||
{
|
|
||||||
Auto,
|
|
||||||
InitDevice,
|
|
||||||
CompleteInit,
|
|
||||||
Bind,
|
|
||||||
Connect,
|
|
||||||
InitTask,
|
|
||||||
Run,
|
|
||||||
Stop,
|
|
||||||
ResetTask,
|
|
||||||
ResetDevice,
|
|
||||||
End,
|
|
||||||
ErrorFound
|
|
||||||
};
|
|
||||||
|
|
||||||
class StateMachine
|
class StateMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -89,20 +52,12 @@ class StateMachine
|
||||||
|
|
||||||
void ProcessWork();
|
void ProcessWork();
|
||||||
|
|
||||||
static std::string GetStateName(const State);
|
|
||||||
static std::string GetTransitionName(const Transition);
|
|
||||||
static State GetState(const std::string& state);
|
|
||||||
static Transition GetTransition(const std::string& transition);
|
|
||||||
|
|
||||||
struct ErrorStateException : std::runtime_error { using std::runtime_error::runtime_error; };
|
struct ErrorStateException : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<void> fFsm;
|
std::shared_ptr<void> fFsm;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const State& state) { return os << StateMachine::GetStateName(state); }
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const Transition& transition) { return os << StateMachine::GetTransitionName(transition); }
|
|
||||||
|
|
||||||
} // namespace mq
|
} // namespace mq
|
||||||
} // namespace fair
|
} // namespace fair
|
||||||
|
|
||||||
|
|
116
fairmq/States.cxx
Normal file
116
fairmq/States.cxx
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include <fairmq/States.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
|
||||||
|
array<string, 15> stateNames =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"OK",
|
||||||
|
"ERROR",
|
||||||
|
"IDLE",
|
||||||
|
"INITIALIZING DEVICE",
|
||||||
|
"INITIALIZED",
|
||||||
|
"BINDING",
|
||||||
|
"BOUND",
|
||||||
|
"CONNECTING",
|
||||||
|
"DEVICE READY",
|
||||||
|
"INITIALIZING TASK",
|
||||||
|
"READY",
|
||||||
|
"RUNNING",
|
||||||
|
"RESETTING TASK",
|
||||||
|
"RESETTING DEVICE",
|
||||||
|
"EXITING"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
unordered_map<string, State> states =
|
||||||
|
{
|
||||||
|
{ "OK", State::Ok },
|
||||||
|
{ "ERROR", State::Error },
|
||||||
|
{ "IDLE", State::Idle },
|
||||||
|
{ "INITIALIZING DEVICE", State::InitializingDevice },
|
||||||
|
{ "INITIALIZED", State::Initialized },
|
||||||
|
{ "BINDING", State::Binding },
|
||||||
|
{ "BOUND", State::Bound },
|
||||||
|
{ "CONNECTING", State::Connecting },
|
||||||
|
{ "DEVICE READY", State::DeviceReady },
|
||||||
|
{ "INITIALIZING TASK", State::InitializingTask },
|
||||||
|
{ "READY", State::Ready },
|
||||||
|
{ "RUNNING", State::Running },
|
||||||
|
{ "RESETTING TASK", State::ResettingTask },
|
||||||
|
{ "RESETTING DEVICE", State::ResettingDevice },
|
||||||
|
{ "EXITING", State::Exiting }
|
||||||
|
};
|
||||||
|
|
||||||
|
array<string, 12> transitionNames =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"AUTO",
|
||||||
|
"INIT DEVICE",
|
||||||
|
"COMPLETE INIT",
|
||||||
|
"BIND",
|
||||||
|
"CONNECT",
|
||||||
|
"INIT TASK",
|
||||||
|
"RUN",
|
||||||
|
"STOP",
|
||||||
|
"RESET TASK",
|
||||||
|
"RESET DEVICE",
|
||||||
|
"END",
|
||||||
|
"ERROR FOUND"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
unordered_map<string, Transition> transitions =
|
||||||
|
{
|
||||||
|
{ "AUTO", Transition::Auto },
|
||||||
|
{ "INIT DEVICE", Transition::InitDevice },
|
||||||
|
{ "COMPLETE INIT", Transition::CompleteInit },
|
||||||
|
{ "BIND", Transition::Bind },
|
||||||
|
{ "CONNECT", Transition::Connect },
|
||||||
|
{ "INIT TASK", Transition::InitTask },
|
||||||
|
{ "RUN", Transition::Run },
|
||||||
|
{ "STOP", Transition::Stop },
|
||||||
|
{ "RESET TASK", Transition::ResetTask },
|
||||||
|
{ "RESET DEVICE", Transition::ResetDevice },
|
||||||
|
{ "END", Transition::End },
|
||||||
|
{ "ERROR FOUND", Transition::ErrorFound }
|
||||||
|
};
|
||||||
|
|
||||||
|
string GetStateName(const State state)
|
||||||
|
{
|
||||||
|
return stateNames.at(static_cast<int>(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetTransitionName(const Transition transition)
|
||||||
|
{
|
||||||
|
return transitionNames.at(static_cast<int>(transition));
|
||||||
|
}
|
||||||
|
|
||||||
|
State GetState(const string& state)
|
||||||
|
{
|
||||||
|
return states.at(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transition GetTransition(const string& transition)
|
||||||
|
{
|
||||||
|
return transitions.at(transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mq
|
||||||
|
} // namespace fair
|
66
fairmq/States.h
Normal file
66
fairmq/States.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
|
* *
|
||||||
|
* This software is distributed under the terms of the *
|
||||||
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
* copied verbatim in the file "LICENSE" *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FAIRMQSTATES_H_
|
||||||
|
#define FAIRMQSTATES_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace fair
|
||||||
|
{
|
||||||
|
namespace mq
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class State : int
|
||||||
|
{
|
||||||
|
Ok,
|
||||||
|
Error,
|
||||||
|
Idle,
|
||||||
|
InitializingDevice,
|
||||||
|
Initialized,
|
||||||
|
Binding,
|
||||||
|
Bound,
|
||||||
|
Connecting,
|
||||||
|
DeviceReady,
|
||||||
|
InitializingTask,
|
||||||
|
Ready,
|
||||||
|
Running,
|
||||||
|
ResettingTask,
|
||||||
|
ResettingDevice,
|
||||||
|
Exiting
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Transition : int
|
||||||
|
{
|
||||||
|
Auto,
|
||||||
|
InitDevice,
|
||||||
|
CompleteInit,
|
||||||
|
Bind,
|
||||||
|
Connect,
|
||||||
|
InitTask,
|
||||||
|
Run,
|
||||||
|
Stop,
|
||||||
|
ResetTask,
|
||||||
|
ResetDevice,
|
||||||
|
End,
|
||||||
|
ErrorFound
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetStateName(const State);
|
||||||
|
std::string GetTransitionName(const Transition);
|
||||||
|
State GetState(const std::string& state);
|
||||||
|
Transition GetTransition(const std::string& transition);
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const State& state) { return os << GetStateName(state); }
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Transition& transition) { return os << GetTransitionName(transition); }
|
||||||
|
|
||||||
|
} // namespace mq
|
||||||
|
} // namespace fair
|
||||||
|
|
||||||
|
#endif /* FAIRMQSTATES_H_ */
|
Loading…
Reference in New Issue
Block a user