From faa309556fb5776c58f85876f17dbefce1d62978 Mon Sep 17 00:00:00 2001 From: Dennis Klein Date: Tue, 23 Aug 2022 20:10:20 +0200 Subject: [PATCH] feat(examples): Add new example with custom controller plugin (statically compiled in) --- examples/CMakeLists.txt | 3 +- examples/custom-controller/CMakeLists.txt | 20 +++++ examples/custom-controller/MyController.h | 97 +++++++++++++++++++++++ examples/custom-controller/MyDevice.h | 21 +++++ examples/custom-controller/main.cxx | 46 +++++++++++ 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 examples/custom-controller/CMakeLists.txt create mode 100644 examples/custom-controller/MyController.h create mode 100644 examples/custom-controller/MyDevice.h create mode 100644 examples/custom-controller/main.cxx diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f9096cbd..c6a52fa4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # +# Copyright (C) 2018-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # # # # This software is distributed under the terms of the # # GNU Lesser General Public Licence (LGPL) version 3, # @@ -10,6 +10,7 @@ add_subdirectory(1-1) add_subdirectory(1-n-1) add_subdirectory(builtin-devices) add_subdirectory(copypush) +add_subdirectory(custom-controller) add_subdirectory(dds) add_subdirectory(multipart) add_subdirectory(multiple-channels) diff --git a/examples/custom-controller/CMakeLists.txt b/examples/custom-controller/CMakeLists.txt new file mode 100644 index 00000000..50d4e856 --- /dev/null +++ b/examples/custom-controller/CMakeLists.txt @@ -0,0 +1,20 @@ +################################################################################ +# Copyright (C) 2022 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 fairmq-ex-custom-controller) +add_executable(${target} main.cxx) +target_link_libraries(${target} PRIVATE FairMQ) +set_target_properties(${target} PROPERTIES + CXX_VISIBILITY_PRESET hidden + ENABLE_EXPORTS ON +) + +set(test Example.custom-controller) +add_test(NAME ${test} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${target}) +set_tests_properties(${test} PROPERTIES TIMEOUT 30) + diff --git a/examples/custom-controller/MyController.h b/examples/custom-controller/MyController.h new file mode 100644 index 00000000..bd84f332 --- /dev/null +++ b/examples/custom-controller/MyController.h @@ -0,0 +1,97 @@ +/******************************************************************************** + * Copyright (C) 2022 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_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN +#define FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN + +#include +#include // for std::forward + +namespace example { + +struct MyController : fair::mq::Plugin // NOLINT +{ + template + MyController(Args&&... args) + : Plugin(std::forward(args)...) + { + TakeDeviceControl(); + + SubscribeToDeviceStateChange([this](auto state) { + auto shutdown = GetProperty("please-shut-me-down", false); + try { + switch (state) { + case DeviceState::Idle: { + ChangeDeviceState(shutdown ? DeviceStateTransition::End + : DeviceStateTransition::InitDevice); + break; + } + case DeviceState::InitializingDevice: { + ChangeDeviceState(DeviceStateTransition::CompleteInit); + break; + } + case DeviceState::Initialized: { + ChangeDeviceState(DeviceStateTransition::Bind); + break; + } + case DeviceState::Bound: { + ChangeDeviceState(DeviceStateTransition::Connect); + break; + } + case DeviceState::DeviceReady: { + ChangeDeviceState(shutdown ? DeviceStateTransition::ResetDevice + : DeviceStateTransition::InitTask); + break; + } + case DeviceState::Ready: { + ChangeDeviceState(shutdown ? DeviceStateTransition::ResetTask + : DeviceStateTransition::Run); + break; + } + case DeviceState::Running: { + ChangeDeviceState(DeviceStateTransition::Stop); + break; + } + case DeviceState::Exiting: { + ReleaseDeviceControl(); + break; + } + default: + break; + } + } catch (fair::mq::PluginServices::DeviceControlError const&) { + // this means we do not have device control + } + }); + } + + ~MyController() override { ReleaseDeviceControl(); } +}; + +// auto MyControllerProgramOptions() -> fair::mq::Plugin::ProgOptions +// { +// auto plugin_options = boost::program_options::options_description{"MyController Plugin"}; +// plugin_options.add_options() +// ("custom-dummy-option", boost::program_options::value(), "Cool custom option.") +// ("custom-dummy-option2", boost::program_options::value(), "Another one."); +// return plugin_options; +// } + +} // namespace example + +REGISTER_FAIRMQ_PLUGIN(example::MyController, // Class name + mycontroller, // Plugin name (string, lower case chars only) + (fair::mq::Plugin::Version{0, 42, 0}), // Version + "Mr. Dummy ", // Maintainer + "https://git.test.net/mycontroller.git", // Homepage + // example::MyControllerProgramOptions // Free + // function which declares custom + // program options for the plugin + fair::mq::Plugin::NoProgramOptions) + +#endif /* FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_PLUGIN */ diff --git a/examples/custom-controller/MyDevice.h b/examples/custom-controller/MyDevice.h new file mode 100644 index 00000000..93d701b7 --- /dev/null +++ b/examples/custom-controller/MyDevice.h @@ -0,0 +1,21 @@ +/******************************************************************************** + * Copyright (C) 2022 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_EXAMPLE_CUSTOM_CONTROLLER_DEVICE +#define FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_DEVICE + +#include + +namespace example { + +using MyDevice = typename fair::mq::Device; + +} // namespace example + +#endif /* FAIR_MQ_EXAMPLE_CUSTOM_CONTROLLER_DEVICE */ + diff --git a/examples/custom-controller/main.cxx b/examples/custom-controller/main.cxx new file mode 100644 index 00000000..0a8b01cb --- /dev/null +++ b/examples/custom-controller/main.cxx @@ -0,0 +1,46 @@ +/******************************************************************************** + * Copyright (C) 2022 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 "MyController.h" +#include "MyDevice.h" + +#include // for std::chrono_literals +#include +#include +#include // for std::make_unique + +int main(int argc, char* argv[]) +{ + using namespace fair::mq; + using namespace std::chrono_literals; + + DeviceRunner runner(argc, argv); + + runner.AddHook([](DeviceRunner& r) { + r.fPluginManager.LoadPlugin("s:mycontroller"); + // 's:' stands for static because the plugin is compiled into the executable + // 'mycontroller' is the plugin name passed as second arg to REGISTER_FAIRMQ_PLUGIN + }); + + fair::Logger::SetConsoleSeverity(fair::Severity::debug); + + runner.AddHook([](DeviceRunner& r) { + r.fConfig.SetProperty("catch-signals", 0); + r.fConfig.SetProperty("please-shut-me-down", false); + r.fDevice = std::make_unique(r.fConfig); + + r.fDevice->SubscribeToStateChange("example", [&r](auto state) { + if (state == State::Running) { + r.fDevice->WaitFor(3s); + r.fConfig.SetProperty("please-shut-me-down", true); + } + }); + }); + + return runner.RunWithExceptionHandlers(); +}