mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-15 09:31:45 +00:00
Add flatbuffers-based command format to SDK/plugin
This commit is contained in:
committed by
Dennis Klein
parent
ea9ad64664
commit
a53e95b5f6
44
fairmq/sdk/commands/CMakeLists.txt
Normal file
44
fairmq/sdk/commands/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
################################################################################
|
||||
# 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" #
|
||||
################################################################################
|
||||
|
||||
set(target Commands)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CommandsFormat.h
|
||||
COMMAND $<TARGET_FILE:flatbuffers::flatc> -c -o ${CMAKE_CURRENT_BINARY_DIR} CommandsFormat.fbs
|
||||
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/CommandsFormat_generated.h ${CMAKE_CURRENT_BINARY_DIR}/CommandsFormat.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_library(${target} Commands.cxx Commands.h ${CMAKE_CURRENT_BINARY_DIR}/CommandsFormat.h)
|
||||
add_library(FairMQ::${target} ALIAS ${target})
|
||||
|
||||
target_link_libraries(${target}
|
||||
PUBLIC
|
||||
StateMachine
|
||||
Tools
|
||||
|
||||
PRIVATE
|
||||
flatbuffers::flatbuffers
|
||||
)
|
||||
|
||||
target_include_directories(${target}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT ${PROJECT_EXPORT_SET}
|
||||
DESTINATION ${PROJECT_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
install(FILES Commands.h
|
||||
DESTINATION ${PROJECT_INSTALL_INCDIR}/sdk/commands
|
||||
)
|
403
fairmq/sdk/commands/Commands.cxx
Normal file
403
fairmq/sdk/commands/Commands.cxx
Normal file
@@ -0,0 +1,403 @@
|
||||
/********************************************************************************
|
||||
* 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 "Commands.h"
|
||||
|
||||
#include <fairmq/sdk/commands/CommandsFormat.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace fair {
|
||||
namespace mq {
|
||||
namespace sdk {
|
||||
namespace cmd {
|
||||
|
||||
array<Result, 2> fbResultToResult =
|
||||
{
|
||||
{
|
||||
Result::Ok,
|
||||
Result::Failure
|
||||
}
|
||||
};
|
||||
|
||||
array<FBResult, 2> resultToFBResult =
|
||||
{
|
||||
{
|
||||
FBResult::FBResult_Ok,
|
||||
FBResult::FBResult_Failure
|
||||
}
|
||||
};
|
||||
|
||||
array<string, 2> resultNames =
|
||||
{
|
||||
{
|
||||
"Ok",
|
||||
"Failure"
|
||||
}
|
||||
};
|
||||
|
||||
array<string, 17> typeNames =
|
||||
{
|
||||
{
|
||||
"CheckState",
|
||||
"ChangeState",
|
||||
"DumpConfig",
|
||||
"SubscribeToHeartbeats",
|
||||
"UnsubscribeFromHeartbeats",
|
||||
"SubscribeToStateChange",
|
||||
"UnsubscribeFromStateChange",
|
||||
"StateChangeExitingReceived",
|
||||
|
||||
"CurrentState",
|
||||
"TransitionStatus",
|
||||
"Config",
|
||||
"HeartbeatSubscription",
|
||||
"HeartbeatUnsubscription",
|
||||
"Heartbeat",
|
||||
"StateChangeSubscription",
|
||||
"StateChangeUnsubscription",
|
||||
"StateChange"
|
||||
}
|
||||
};
|
||||
|
||||
array<fair::mq::State, 15> fbStateToMQState =
|
||||
{
|
||||
{
|
||||
fair::mq::State::Ok,
|
||||
fair::mq::State::Error,
|
||||
fair::mq::State::Idle,
|
||||
fair::mq::State::InitializingDevice,
|
||||
fair::mq::State::Initialized,
|
||||
fair::mq::State::Binding,
|
||||
fair::mq::State::Bound,
|
||||
fair::mq::State::Connecting,
|
||||
fair::mq::State::DeviceReady,
|
||||
fair::mq::State::InitializingTask,
|
||||
fair::mq::State::Ready,
|
||||
fair::mq::State::Running,
|
||||
fair::mq::State::ResettingTask,
|
||||
fair::mq::State::ResettingDevice,
|
||||
fair::mq::State::Exiting
|
||||
}
|
||||
};
|
||||
|
||||
array<sdk::cmd::FBState, 15> mqStateToFBState =
|
||||
{
|
||||
{
|
||||
sdk::cmd::FBState_Ok,
|
||||
sdk::cmd::FBState_Error,
|
||||
sdk::cmd::FBState_Idle,
|
||||
sdk::cmd::FBState_InitializingDevice,
|
||||
sdk::cmd::FBState_Initialized,
|
||||
sdk::cmd::FBState_Binding,
|
||||
sdk::cmd::FBState_Bound,
|
||||
sdk::cmd::FBState_Connecting,
|
||||
sdk::cmd::FBState_DeviceReady,
|
||||
sdk::cmd::FBState_InitializingTask,
|
||||
sdk::cmd::FBState_Ready,
|
||||
sdk::cmd::FBState_Running,
|
||||
sdk::cmd::FBState_ResettingTask,
|
||||
sdk::cmd::FBState_ResettingDevice,
|
||||
sdk::cmd::FBState_Exiting
|
||||
}
|
||||
};
|
||||
|
||||
array<fair::mq::Transition, 12> fbTransitionToMQTransition =
|
||||
{
|
||||
{
|
||||
fair::mq::Transition::Auto,
|
||||
fair::mq::Transition::InitDevice,
|
||||
fair::mq::Transition::CompleteInit,
|
||||
fair::mq::Transition::Bind,
|
||||
fair::mq::Transition::Connect,
|
||||
fair::mq::Transition::InitTask,
|
||||
fair::mq::Transition::Run,
|
||||
fair::mq::Transition::Stop,
|
||||
fair::mq::Transition::ResetTask,
|
||||
fair::mq::Transition::ResetDevice,
|
||||
fair::mq::Transition::End,
|
||||
fair::mq::Transition::ErrorFound
|
||||
}
|
||||
};
|
||||
|
||||
array<sdk::cmd::FBTransition, 12> mqTransitionToFBTransition =
|
||||
{
|
||||
{
|
||||
sdk::cmd::FBTransition_Auto,
|
||||
sdk::cmd::FBTransition_InitDevice,
|
||||
sdk::cmd::FBTransition_CompleteInit,
|
||||
sdk::cmd::FBTransition_Bind,
|
||||
sdk::cmd::FBTransition_Connect,
|
||||
sdk::cmd::FBTransition_InitTask,
|
||||
sdk::cmd::FBTransition_Run,
|
||||
sdk::cmd::FBTransition_Stop,
|
||||
sdk::cmd::FBTransition_ResetTask,
|
||||
sdk::cmd::FBTransition_ResetDevice,
|
||||
sdk::cmd::FBTransition_End,
|
||||
sdk::cmd::FBTransition_ErrorFound
|
||||
}
|
||||
};
|
||||
|
||||
array<FBCmd, 17> typeToFBCmd =
|
||||
{
|
||||
{
|
||||
FBCmd::FBCmd_check_state,
|
||||
FBCmd::FBCmd_change_state,
|
||||
FBCmd::FBCmd_dump_config,
|
||||
FBCmd::FBCmd_subscribe_to_heartbeats,
|
||||
FBCmd::FBCmd_unsubscribe_from_heartbeats,
|
||||
FBCmd::FBCmd_subscribe_to_state_change,
|
||||
FBCmd::FBCmd_unsubscribe_from_state_change,
|
||||
FBCmd::FBCmd_state_change_exiting_received,
|
||||
FBCmd::FBCmd_current_state,
|
||||
FBCmd::FBCmd_transition_status,
|
||||
FBCmd::FBCmd_config,
|
||||
FBCmd::FBCmd_heartbeat_subscription,
|
||||
FBCmd::FBCmd_heartbeat_unsubscription,
|
||||
FBCmd::FBCmd_heartbeat,
|
||||
FBCmd::FBCmd_state_change_subscription,
|
||||
FBCmd::FBCmd_state_change_unsubscription,
|
||||
FBCmd::FBCmd_state_change
|
||||
}
|
||||
};
|
||||
|
||||
array<Type, 17> fbCmdToType =
|
||||
{
|
||||
{
|
||||
Type::check_state,
|
||||
Type::change_state,
|
||||
Type::dump_config,
|
||||
Type::subscribe_to_heartbeats,
|
||||
Type::unsubscribe_from_heartbeats,
|
||||
Type::subscribe_to_state_change,
|
||||
Type::unsubscribe_from_state_change,
|
||||
Type::state_change_exiting_received,
|
||||
Type::current_state,
|
||||
Type::transition_status,
|
||||
Type::config,
|
||||
Type::heartbeat_subscription,
|
||||
Type::heartbeat_unsubscription,
|
||||
Type::heartbeat,
|
||||
Type::state_change_subscription,
|
||||
Type::state_change_unsubscription,
|
||||
Type::state_change
|
||||
}
|
||||
};
|
||||
|
||||
fair::mq::State GetMQState(const FBState state) { return fbStateToMQState.at(state); }
|
||||
FBState GetFBState(const fair::mq::State state) { return mqStateToFBState.at(static_cast<int>(state)); }
|
||||
fair::mq::Transition GetMQTransition(const FBTransition transition) { return fbTransitionToMQTransition.at(transition); }
|
||||
FBTransition GetFBTransition(const fair::mq::Transition transition) { return mqTransitionToFBTransition.at(static_cast<int>(transition)); }
|
||||
|
||||
Result GetResult(const FBResult result) { return fbResultToResult.at(result); }
|
||||
FBResult GetFBResult(const Result result) { return resultToFBResult.at(static_cast<int>(result)); }
|
||||
string GetResultName(const Result result) { return resultNames.at(static_cast<int>(result)); }
|
||||
string GetTypeName(const Type type) { return typeNames.at(static_cast<int>(type)); }
|
||||
|
||||
FBCmd GetFBCmd(const Type type) { return typeToFBCmd.at(static_cast<int>(type)); }
|
||||
|
||||
string Cmds::Serialize() const
|
||||
{
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
vector<flatbuffers::Offset<FBCommand>> commandOffsets;
|
||||
|
||||
for (auto& cmd : fCmds) {
|
||||
flatbuffers::Offset<FBCommand> cmdOffset;
|
||||
unique_ptr<FBCommandBuilder> cmdBuilder; // delay the creation of the builder, because child strings need to be constructed first (which are conditional)
|
||||
|
||||
switch (cmd->GetType()) {
|
||||
case Type::check_state: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::change_state: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_transition(GetFBTransition(static_cast<ChangeState&>(*cmd).GetTransition()));
|
||||
}
|
||||
break;
|
||||
case Type::dump_config: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::subscribe_to_heartbeats: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::unsubscribe_from_heartbeats: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::subscribe_to_state_change: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::unsubscribe_from_state_change: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::state_change_exiting_received: {
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
}
|
||||
break;
|
||||
case Type::current_state: {
|
||||
auto deviceId = fbb.CreateString(static_cast<CurrentState&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_current_state(GetFBState(static_cast<CurrentState&>(*cmd).GetCurrentState()));
|
||||
}
|
||||
break;
|
||||
case Type::transition_status: {
|
||||
auto deviceId = fbb.CreateString(static_cast<TransitionStatus&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_result(GetFBResult(static_cast<TransitionStatus&>(*cmd).GetResult()));
|
||||
cmdBuilder->add_transition(GetFBTransition(static_cast<TransitionStatus&>(*cmd).GetTransition()));
|
||||
}
|
||||
break;
|
||||
case Type::config: {
|
||||
auto deviceId = fbb.CreateString(static_cast<Config&>(*cmd).GetDeviceId());
|
||||
auto config = fbb.CreateString(static_cast<Config&>(*cmd).GetConfig());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_config_string(config);
|
||||
}
|
||||
break;
|
||||
case Type::heartbeat_subscription: {
|
||||
auto deviceId = fbb.CreateString(static_cast<HeartbeatSubscription&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_result(GetFBResult(static_cast<HeartbeatSubscription&>(*cmd).GetResult()));
|
||||
}
|
||||
break;
|
||||
case Type::heartbeat_unsubscription: {
|
||||
auto deviceId = fbb.CreateString(static_cast<HeartbeatUnsubscription&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_result(GetFBResult(static_cast<HeartbeatUnsubscription&>(*cmd).GetResult()));
|
||||
}
|
||||
break;
|
||||
case Type::heartbeat: {
|
||||
auto deviceId = fbb.CreateString(static_cast<Heartbeat&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
}
|
||||
break;
|
||||
case Type::state_change_subscription: {
|
||||
auto deviceId = fbb.CreateString(static_cast<StateChangeSubscription&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_result(GetFBResult(static_cast<StateChangeSubscription&>(*cmd).GetResult()));
|
||||
}
|
||||
break;
|
||||
case Type::state_change_unsubscription: {
|
||||
auto deviceId = fbb.CreateString(static_cast<StateChangeUnsubscription&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_result(GetFBResult(static_cast<StateChangeUnsubscription&>(*cmd).GetResult()));
|
||||
}
|
||||
break;
|
||||
case Type::state_change: {
|
||||
auto deviceId = fbb.CreateString(static_cast<StateChange&>(*cmd).GetDeviceId());
|
||||
cmdBuilder = tools::make_unique<FBCommandBuilder>(fbb);
|
||||
cmdBuilder->add_device_id(deviceId);
|
||||
cmdBuilder->add_task_id(static_cast<StateChange&>(*cmd).GetTaskId());
|
||||
cmdBuilder->add_last_state(GetFBState(static_cast<StateChange&>(*cmd).GetLastState()));
|
||||
cmdBuilder->add_current_state(GetFBState(static_cast<StateChange&>(*cmd).GetCurrentState()));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw CommandFormatError("unrecognized command type given to fair::mq::cmd::Cmds::Serialize()");
|
||||
break;
|
||||
}
|
||||
|
||||
cmdBuilder->add_command_id(typeToFBCmd.at(static_cast<int>(cmd->GetType())));
|
||||
|
||||
cmdOffset = cmdBuilder->Finish();
|
||||
commandOffsets.push_back(cmdOffset);
|
||||
}
|
||||
|
||||
auto commands = fbb.CreateVector(commandOffsets);
|
||||
auto cmds = CreateFBCommands(fbb, commands);
|
||||
fbb.Finish(cmds);
|
||||
|
||||
return string(reinterpret_cast<char*>(fbb.GetBufferPointer()), fbb.GetSize());
|
||||
}
|
||||
|
||||
void Cmds::Deserialize(const string& str)
|
||||
{
|
||||
fCmds.clear();
|
||||
|
||||
auto cmds = cmd::GetFBCommands(const_cast<char*>(str.c_str()))->commands();
|
||||
|
||||
for (unsigned int i = 0; i < cmds->size(); ++i) {
|
||||
const fair::mq::sdk::cmd::FBCommand& cmdPtr = *(cmds->Get(i));
|
||||
switch (cmdPtr.command_id()) {
|
||||
case FBCmd_check_state:
|
||||
fCmds.emplace_back(make<CheckState>());
|
||||
break;
|
||||
case FBCmd_change_state:
|
||||
fCmds.emplace_back(make<ChangeState>(GetMQTransition(cmdPtr.transition())));
|
||||
break;
|
||||
case FBCmd_dump_config:
|
||||
fCmds.emplace_back(make<DumpConfig>());
|
||||
break;
|
||||
case FBCmd_subscribe_to_heartbeats:
|
||||
fCmds.emplace_back(make<SubscribeToHeartbeats>());
|
||||
break;
|
||||
case FBCmd_unsubscribe_from_heartbeats:
|
||||
fCmds.emplace_back(make<UnsubscribeFromHeartbeats>());
|
||||
break;
|
||||
case FBCmd_subscribe_to_state_change:
|
||||
fCmds.emplace_back(make<SubscribeToStateChange>());
|
||||
break;
|
||||
case FBCmd_unsubscribe_from_state_change:
|
||||
fCmds.emplace_back(make<UnsubscribeFromStateChange>());
|
||||
break;
|
||||
case FBCmd_state_change_exiting_received:
|
||||
fCmds.emplace_back(make<StateChangeExitingReceived>());
|
||||
break;
|
||||
case FBCmd_current_state:
|
||||
fCmds.emplace_back(make<CurrentState>(cmdPtr.device_id()->str(), GetMQState(cmdPtr.current_state())));
|
||||
break;
|
||||
case FBCmd_transition_status:
|
||||
fCmds.emplace_back(make<TransitionStatus>(cmdPtr.device_id()->str(), GetResult(cmdPtr.result()), GetMQTransition(cmdPtr.transition())));
|
||||
break;
|
||||
case FBCmd_config:
|
||||
fCmds.emplace_back(make<Config>(cmdPtr.device_id()->str(), cmdPtr.config_string()->str()));
|
||||
break;
|
||||
case FBCmd_heartbeat_subscription:
|
||||
fCmds.emplace_back(make<HeartbeatSubscription>(cmdPtr.device_id()->str(), GetResult(cmdPtr.result())));
|
||||
break;
|
||||
case FBCmd_heartbeat_unsubscription:
|
||||
fCmds.emplace_back(make<HeartbeatUnsubscription>(cmdPtr.device_id()->str(), GetResult(cmdPtr.result())));
|
||||
break;
|
||||
case FBCmd_heartbeat:
|
||||
fCmds.emplace_back(make<Heartbeat>(cmdPtr.device_id()->str()));
|
||||
break;
|
||||
case FBCmd_state_change_subscription:
|
||||
fCmds.emplace_back(make<StateChangeSubscription>(cmdPtr.device_id()->str(), GetResult(cmdPtr.result())));
|
||||
break;
|
||||
case FBCmd_state_change_unsubscription:
|
||||
fCmds.emplace_back(make<StateChangeUnsubscription>(cmdPtr.device_id()->str(), GetResult(cmdPtr.result())));
|
||||
break;
|
||||
case FBCmd_state_change:
|
||||
fCmds.emplace_back(make<StateChange>(cmdPtr.device_id()->str(), cmdPtr.task_id(), GetMQState(cmdPtr.last_state()), GetMQState(cmdPtr.current_state())));
|
||||
break;
|
||||
default:
|
||||
throw CommandFormatError("unrecognized command type given to fair::mq::cmd::Cmds::Deserialize()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace sdk
|
||||
} // namespace mq
|
||||
} // namespace fair
|
356
fairmq/sdk/commands/Commands.h
Normal file
356
fairmq/sdk/commands/Commands.h
Normal file
@@ -0,0 +1,356 @@
|
||||
/********************************************************************************
|
||||
* Copyright (C) 2017 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 FAIR_MQ_SDK_COMMANDFACTORY
|
||||
#define FAIR_MQ_SDK_COMMANDFACTORY
|
||||
|
||||
#include <fairmq/States.h>
|
||||
#include <fairmq/Tools.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
{
|
||||
namespace sdk
|
||||
{
|
||||
namespace cmd
|
||||
{
|
||||
|
||||
enum class Result : int {
|
||||
Ok,
|
||||
Failure
|
||||
};
|
||||
|
||||
enum class Type : int
|
||||
{
|
||||
check_state, // args: { }
|
||||
change_state, // args: { transition }
|
||||
dump_config, // args: { }
|
||||
subscribe_to_heartbeats, // args: { }
|
||||
unsubscribe_from_heartbeats, // args: { }
|
||||
subscribe_to_state_change, // args: { }
|
||||
unsubscribe_from_state_change, // args: { }
|
||||
state_change_exiting_received, // args: { }
|
||||
|
||||
current_state, // args: { device_id, current_state }
|
||||
transition_status, // args: { device_id, Result, transition }
|
||||
config, // args: { device_id, config_string }
|
||||
heartbeat_subscription, // args: { device_id, Result }
|
||||
heartbeat_unsubscription, // args: { device_id, Result }
|
||||
heartbeat, // args: { device_id }
|
||||
state_change_subscription, // args: { device_id, Result }
|
||||
state_change_unsubscription, // args: { device_id, Result }
|
||||
state_change // args: { device_id, task_id, last_state, current_state }
|
||||
};
|
||||
|
||||
struct Cmd
|
||||
{
|
||||
explicit Cmd(const Type type) : fType(type) {}
|
||||
|
||||
Type GetType() const { return fType; }
|
||||
|
||||
private:
|
||||
Type fType;
|
||||
};
|
||||
|
||||
struct CheckState : Cmd
|
||||
{
|
||||
explicit CheckState() : Cmd(Type::check_state) {}
|
||||
};
|
||||
|
||||
struct ChangeState : Cmd
|
||||
{
|
||||
explicit ChangeState(Transition transition)
|
||||
: Cmd(Type::change_state)
|
||||
, fTransition(transition)
|
||||
{}
|
||||
|
||||
Transition GetTransition() const { return fTransition; }
|
||||
void SetTransition(Transition transition) { fTransition = transition; }
|
||||
|
||||
private:
|
||||
Transition fTransition;
|
||||
};
|
||||
|
||||
struct DumpConfig : Cmd
|
||||
{
|
||||
explicit DumpConfig() : Cmd(Type::dump_config) {}
|
||||
};
|
||||
|
||||
struct SubscribeToHeartbeats : Cmd
|
||||
{
|
||||
explicit SubscribeToHeartbeats() : Cmd(Type::subscribe_to_heartbeats) {}
|
||||
};
|
||||
|
||||
struct UnsubscribeFromHeartbeats : Cmd
|
||||
{
|
||||
explicit UnsubscribeFromHeartbeats() : Cmd(Type::unsubscribe_from_heartbeats) {}
|
||||
};
|
||||
|
||||
struct SubscribeToStateChange : Cmd
|
||||
{
|
||||
explicit SubscribeToStateChange() : Cmd(Type::subscribe_to_state_change) {}
|
||||
};
|
||||
|
||||
struct UnsubscribeFromStateChange : Cmd
|
||||
{
|
||||
explicit UnsubscribeFromStateChange() : Cmd(Type::unsubscribe_from_state_change) {}
|
||||
};
|
||||
|
||||
struct StateChangeExitingReceived : Cmd
|
||||
{
|
||||
explicit StateChangeExitingReceived() : Cmd(Type::state_change_exiting_received) {}
|
||||
};
|
||||
|
||||
struct CurrentState : Cmd
|
||||
{
|
||||
explicit CurrentState(const std::string& id, State currentState)
|
||||
: Cmd(Type::current_state)
|
||||
, fDeviceId(id)
|
||||
, fCurrentState(currentState)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
fair::mq::State GetCurrentState() const { return fCurrentState; }
|
||||
void SetCurrentState(fair::mq::State state) { fCurrentState = state; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
fair::mq::State fCurrentState;
|
||||
};
|
||||
|
||||
struct TransitionStatus : Cmd
|
||||
{
|
||||
explicit TransitionStatus(const std::string& id, Result result, Transition transition)
|
||||
: Cmd(Type::transition_status)
|
||||
, fDeviceId(id)
|
||||
, fResult(result)
|
||||
, fTransition(transition)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
Result GetResult() const { return fResult; }
|
||||
void SetResult(Result result) { fResult = result; }
|
||||
Transition GetTransition() const { return fTransition; }
|
||||
void SetTransition(Transition transition) { fTransition = transition; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
Result fResult;
|
||||
Transition fTransition;
|
||||
};
|
||||
|
||||
struct Config : Cmd
|
||||
{
|
||||
explicit Config(const std::string& id, const std::string& config)
|
||||
: Cmd(Type::config)
|
||||
, fDeviceId(id)
|
||||
, fConfig(config)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
std::string GetConfig() const { return fConfig; }
|
||||
void SetConfig(const std::string& config) { fConfig = config; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
std::string fConfig;
|
||||
};
|
||||
|
||||
struct HeartbeatSubscription : Cmd
|
||||
{
|
||||
explicit HeartbeatSubscription(const std::string& id, Result result)
|
||||
: Cmd(Type::heartbeat_subscription)
|
||||
, fDeviceId(id)
|
||||
, fResult(result)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
Result GetResult() const { return fResult; }
|
||||
void SetResult(Result result) { fResult = result; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
Result fResult;
|
||||
};
|
||||
|
||||
struct HeartbeatUnsubscription : Cmd
|
||||
{
|
||||
explicit HeartbeatUnsubscription(const std::string& id, Result result)
|
||||
: Cmd(Type::heartbeat_unsubscription)
|
||||
, fDeviceId(id)
|
||||
, fResult(result)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
Result GetResult() const { return fResult; }
|
||||
void SetResult(Result result) { fResult = result; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
Result fResult;
|
||||
};
|
||||
|
||||
struct Heartbeat : Cmd
|
||||
{
|
||||
explicit Heartbeat(const std::string& id)
|
||||
: Cmd(Type::heartbeat)
|
||||
, fDeviceId(id)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
};
|
||||
|
||||
struct StateChangeSubscription : Cmd
|
||||
{
|
||||
explicit StateChangeSubscription(const std::string& id, Result result)
|
||||
: Cmd(Type::state_change_subscription)
|
||||
, fDeviceId(id)
|
||||
, fResult(result)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
Result GetResult() const { return fResult; }
|
||||
void SetResult(Result result) { fResult = result; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
Result fResult;
|
||||
};
|
||||
|
||||
struct StateChangeUnsubscription : Cmd
|
||||
{
|
||||
explicit StateChangeUnsubscription(const std::string& id, Result result)
|
||||
: Cmd(Type::state_change_unsubscription)
|
||||
, fDeviceId(id)
|
||||
, fResult(result)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
Result GetResult() const { return fResult; }
|
||||
void SetResult(Result result) { fResult = result; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
Result fResult;
|
||||
};
|
||||
|
||||
struct StateChange : Cmd
|
||||
{
|
||||
explicit StateChange(const std::string& deviceId, uint64_t taskId, State lastState, State currentState)
|
||||
: Cmd(Type::state_change)
|
||||
, fDeviceId(deviceId)
|
||||
, fTaskId(taskId)
|
||||
, fLastState(lastState)
|
||||
, fCurrentState(currentState)
|
||||
{}
|
||||
|
||||
std::string GetDeviceId() const { return fDeviceId; }
|
||||
void SetDeviceId(const std::string& deviceId) { fDeviceId = deviceId; }
|
||||
uint64_t GetTaskId() const { return fTaskId; }
|
||||
void SetTaskId(uint64_t taskId) { fTaskId = taskId; }
|
||||
fair::mq::State GetLastState() const { return fLastState; }
|
||||
void SetLastState(fair::mq::State state) { fLastState = state; }
|
||||
fair::mq::State GetCurrentState() const { return fCurrentState; }
|
||||
void SetCurrentState(fair::mq::State state) { fCurrentState = state; }
|
||||
|
||||
private:
|
||||
std::string fDeviceId;
|
||||
uint64_t fTaskId;
|
||||
fair::mq::State fLastState;
|
||||
fair::mq::State fCurrentState;
|
||||
};
|
||||
|
||||
template<typename C, typename... Args>
|
||||
std::unique_ptr<Cmd> make(Args&&... args)
|
||||
{
|
||||
return fair::mq::tools::make_unique<C>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
struct Cmds
|
||||
{
|
||||
using container = std::vector<std::unique_ptr<Cmd>>;
|
||||
struct CommandFormatError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||
|
||||
explicit Cmds() {}
|
||||
|
||||
template<typename... Rest>
|
||||
explicit Cmds(std::unique_ptr<Cmd>&& first, Rest&&... rest)
|
||||
{
|
||||
Unpack(std::forward<std::unique_ptr<Cmd>&&>(first), std::forward<Rest>(rest)...);
|
||||
}
|
||||
|
||||
|
||||
void Add(std::unique_ptr<Cmd>&& cmd) { fCmds.emplace_back(std::move(cmd)); }
|
||||
|
||||
template<typename C, typename... Args>
|
||||
void Add(Args&&... args)
|
||||
{
|
||||
static_assert(std::is_base_of<Cmd, C>::value, "Only types derived from fair::mq::cmd::Cmd are allowed");
|
||||
Add(make<C>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
Cmd& At(size_t i) { return *(fCmds.at(i)); }
|
||||
|
||||
size_t Size() { return fCmds.size(); }
|
||||
void Reset() { fCmds.clear(); }
|
||||
|
||||
std::string Serialize() const;
|
||||
void Deserialize(const std::string&);
|
||||
|
||||
private:
|
||||
container fCmds;
|
||||
|
||||
void Unpack() {}
|
||||
|
||||
template <class... Rest>
|
||||
void Unpack(std::unique_ptr<Cmd>&& first, Rest&&... rest)
|
||||
{
|
||||
fCmds.emplace_back(std::move(first));
|
||||
Unpack(std::forward<Rest>(rest)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using iterator = container::iterator;
|
||||
using const_iterator = container::const_iterator;
|
||||
|
||||
auto begin() -> decltype(fCmds.begin()) { return fCmds.begin(); }
|
||||
auto end() -> decltype(fCmds.end()) { return fCmds.end(); }
|
||||
auto cbegin() -> decltype(fCmds.cbegin()) { return fCmds.cbegin(); }
|
||||
auto cend() -> decltype(fCmds.cend()) { return fCmds.cend(); }
|
||||
};
|
||||
|
||||
std::string GetResultName(const Result result);
|
||||
std::string GetTypeName(const Type type);
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Result& result) { return os << GetResultName(result); }
|
||||
inline std::ostream& operator<<(std::ostream& os, const Type& type) { return os << GetTypeName(type); }
|
||||
|
||||
} /* namespace cmd */
|
||||
} /* namespace sdk */
|
||||
} /* namespace mq */
|
||||
} /* namespace fair */
|
||||
|
||||
#endif /* FAIR_MQ_SDK_COMMANDFACTORY */
|
79
fairmq/sdk/commands/CommandsFormat.fbs
Normal file
79
fairmq/sdk/commands/CommandsFormat.fbs
Normal file
@@ -0,0 +1,79 @@
|
||||
namespace fair.mq.sdk.cmd;
|
||||
|
||||
enum FBResult:byte {
|
||||
Ok,
|
||||
Failure
|
||||
}
|
||||
|
||||
enum FBState:byte {
|
||||
Ok,
|
||||
Error,
|
||||
Idle,
|
||||
InitializingDevice,
|
||||
Initialized,
|
||||
Binding,
|
||||
Bound,
|
||||
Connecting,
|
||||
DeviceReady,
|
||||
InitializingTask,
|
||||
Ready,
|
||||
Running,
|
||||
ResettingTask,
|
||||
ResettingDevice,
|
||||
Exiting
|
||||
}
|
||||
|
||||
enum FBTransition:byte {
|
||||
Auto,
|
||||
InitDevice,
|
||||
CompleteInit,
|
||||
Bind,
|
||||
Connect,
|
||||
InitTask,
|
||||
Run,
|
||||
Stop,
|
||||
ResetTask,
|
||||
ResetDevice,
|
||||
End,
|
||||
ErrorFound
|
||||
}
|
||||
|
||||
enum FBCmd:byte {
|
||||
check_state, // args: { }
|
||||
change_state, // args: { transition }
|
||||
dump_config, // args: { }
|
||||
subscribe_to_heartbeats, // args: { }
|
||||
unsubscribe_from_heartbeats, // args: { }
|
||||
subscribe_to_state_change, // args: { }
|
||||
unsubscribe_from_state_change, // args: { }
|
||||
state_change_exiting_received, // args: { }
|
||||
|
||||
current_state, // args: { device_id, current_state }
|
||||
transition_status, // args: { device_id, Result, transition }
|
||||
config, // args: { device_id, config_string }
|
||||
heartbeat_subscription, // args: { device_id, Result }
|
||||
heartbeat_unsubscription, // args: { device_id, Result }
|
||||
heartbeat, // args: { device_id }
|
||||
state_change_subscription, // args: { device_id, Result }
|
||||
state_change_unsubscription, // args: { device_id, Result }
|
||||
state_change // args: { device_id, task_id, last_state, current_state }
|
||||
}
|
||||
|
||||
table FBCommand {
|
||||
command_id:FBCmd;
|
||||
device_id:string;
|
||||
task_id:uint64;
|
||||
state:FBState;
|
||||
transition:FBTransition;
|
||||
result:FBResult;
|
||||
config_string:string;
|
||||
last_state:FBState;
|
||||
current_state:FBState;
|
||||
debug:string;
|
||||
}
|
||||
|
||||
table FBCommands {
|
||||
commands:[FBCommand];
|
||||
}
|
||||
|
||||
root_type FBCommands;
|
Reference in New Issue
Block a user