DynExp
Highly flexible laboratory automation for dynamically changing experiments.
StreamManipulator.h
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
9 #pragma once
10 
11 #include "stdafx.h"
12 #include "DynExpCore.h"
13 #include "PyModules.h"
14 
15 namespace DynExpModule
16 {
17  class StreamManipulator;
18 
22  using PyStreamListType = std::vector<DynExpInstr::PyDataStreamInstrument>;
23 
28  {
33 
37  std::chrono::time_point<std::chrono::system_clock> LastExecutionTime{};
38 
43 
48 
53  void Reset();
54  };
55 
60  {
65  std::chrono::milliseconds MinNextExecutionDelay{};
66 
71  std::chrono::milliseconds MaxNextExecutionDelay{};
72 
80 
85  void Reset();
86  };
87 
92  {
93  public:
95  virtual ~StreamManipulatorData() = default;
96 
97  auto& GetInputDataStreams() const noexcept { return InputDataStreams; }
98  auto& GetInputDataStreams() noexcept { return InputDataStreams; }
99  auto& GetOutputDataStreams() const noexcept { return OutputDataStreams; }
100  auto& GetOutputDataStreams() noexcept { return OutputDataStreams; }
101 
102  private:
106  void ResetImpl(dispatch_tag<ModuleDataBase>) override final;
107 
112 
117  void Init();
118 
123 
128  };
129 
134  {
135  public:
140 
141  virtual ~StreamManipulatorParams() = default;
142 
143  virtual const char* GetParamClassTag() const noexcept override { return "StreamManipulatorParams"; }
144 
150  "InputDataStreams", "Input data stream instrument(s)", "Data stream instruments to be used as data sources", DynExpUI::Icons::Instrument, true };
151 
157  "OutputDataStreams", "Output data stream instrument(s)", "Data stream instruments to be used as data sinks", DynExpUI::Icons::Instrument, true };
158 
181  Param<ParamsConfigDialog::TextType> PythonCodePath = { *this, "PythonCodePath", "Python code path",
182  "Path to a Python file containing the function which writes samples to the output streams based on the input streams' data", true, "", DynExp::TextUsageType::Code };
183 
184  private:
189  };
190 
195  {
196  public:
199 
201  virtual ~StreamManipulatorConfigurator() = default;
202 
203  private:
204  virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore& Core) const override final { return DynExp::MakeParams<StreamManipulatorConfigurator>(ID, Core); }
205  };
206 
212  {
218 
223 
224  public:
228 
229  constexpr static auto Name() noexcept { return "Stream Manipulator"; }
230  constexpr static auto Category() noexcept { return "I/O"; }
231 
236  : ModuleBase(OwnerThreadID, std::move(Params)) {}
237 
238  virtual ~StreamManipulator() = default;
239 
240  virtual std::string GetName() const override { return Name(); }
241  virtual std::string GetCategory() const override { return Category(); }
242 
247  bool TreatModuleExceptionsAsWarnings() const override { return IsInitialized; }
248 
249  std::chrono::milliseconds GetMainLoopDelay() const override final { return std::chrono::milliseconds(1); }
250 
251  private:
253 
257  void ResetImpl(dispatch_tag<ModuleBase>) override final;
258 
265 
270  void OnInit(DynExp::ModuleInstance* Instance) const override final;
271  void OnExit(DynExp::ModuleInstance* Instance) const override final;
273 
279  mutable std::atomic<bool> IsInitialized = false;
280 
288 
292 
297 
302 
308 
312  std::chrono::time_point<std::chrono::system_clock> LastManipulatorPyFuncExecution{};
313  };
314 }
Defines DynExp's core module as an interface between the UI and DynExp objects.
Implementation of mappings between DynExp instruments and corresponding embedded Python modules makin...
Base class for all circular data streams based on Util::circularbuf.
Configurator class for StreamManipulator.
virtual DynExp::ParamsBasePtrType MakeParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core) const override final
Override to make derived classes call DynExp::MakeParams with the correct configurator type derived f...
Data class for StreamManipulator.
virtual void ResetImpl(dispatch_tag< StreamManipulatorData >)
Refer to DynExp::ModuleDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of ...
auto & GetOutputDataStreams() noexcept
Getter for OutputDataStreams.
virtual ~StreamManipulatorData()=default
auto & GetInputDataStreams() const noexcept
Getter for InputDataStreams.
auto & GetInputDataStreams() noexcept
Getter for InputDataStreams.
DynExp::LinkedObjectWrapperContainerList< DynExpInstr::DataStreamInstrument > InputDataStreams
Linked input data stream instruments whose samples are going to be used for calculations.
auto & GetOutputDataStreams() const noexcept
Getter for OutputDataStreams.
void Init()
Called by ResetImpl(dispatch_tag<DynExp::ModuleDataBase>) overridden by this class to initialize the ...
DynExp::LinkedObjectWrapperContainerList< DynExpInstr::DataStreamInstrument > OutputDataStreams
Linked output data stream instruments to write the computed new samples to.
void ResetImpl(dispatch_tag< ModuleDataBase >) override final
Refer to DynExp::ModuleDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of ...
Parameter class for StreamManipulator.
ListParam< DynExp::ObjectLink< DynExpInstr::DataStreamInstrument > > InputDataStreams
Parameter for data stream instruments containing input samples. Refer to StreamManipulatorData::Input...
Param< ParamsConfigDialog::TextType > PythonCodePath
Path to the Python file containing the code, which performs the stream manipulation.
virtual const char * GetParamClassTag() const noexcept override
This function is intended to be overridden once in each derived class returning the name of the respe...
StreamManipulatorParams(DynExp::ItemIDType ID, const DynExp::DynExpCore &Core)
Constructs the parameters for a StreamManipulator instance.
void ConfigureParamsImpl(dispatch_tag< ModuleParamsBase >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
ListParam< DynExp::ObjectLink< DynExpInstr::DataStreamInstrument > > OutputDataStreams
Parameter for data stream instruments containing output samples. Refer to StreamManipulatorData::Outp...
virtual ~StreamManipulatorParams()=default
Module to process data stored in data stream instrument(s) with a Python script and to write the resu...
void OnInit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread starts. Override it to lock instruments this m...
size_t NumFailedUpdateAttempts
Counts how often StreamManipulator::ModuleMainLoop() contiguously failed due to an exception of type ...
std::chrono::time_point< std::chrono::system_clock > LastManipulatorPyFuncExecution
Time point when the on_step() Python function was invoked last.
std::atomic< bool > IsInitialized
Indicates whether the module has been fully initialized by finishing OnInit(). The variable is atomic...
PyFuncType ManipulatorPyFuncStep
Handle to a Python function called for each manipulation step.
virtual std::string GetCategory() const override
Returns the category of this Object type.
PyStreamManipulatorOutputData ManipulatorPyFuncOutput
Output data returned from the on_step() Python function.
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(DynExp::ModuleInstance &Instance) override final
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
StreamManipulator(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Constructs a ModuleBase instance.
PyFuncType ManipulatorPyFuncExit
Handle to a Python function called on module termination.
virtual std::string GetName() const override
Returns the name of this Object type.
virtual ~StreamManipulator()=default
void ResetImpl(dispatch_tag< ModuleBase >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
PyFuncType ManipulatorPyFuncInit
Handle to a Python function called on module initialization.
constexpr static auto Name() noexcept
Every derived class has to redefine this function.
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
std::string ManipulatorPyFuncName
Unique name of the Python function all the code of this StreamManipulator instance is declared in....
PyStreamManipulatorInputData ManipulatorPyFuncInput
Input data passed to the on_step() Python function.
constexpr static auto Category() noexcept
Every derived class has to redefine this function.
std::chrono::milliseconds GetMainLoopDelay() const override final
Specifies in which time intervals the module's event queue runs to handle pending events.
void Step(Util::SynchronizedPointer< ModuleDataType > &ModuleData)
Performs a single manipulation step by preparing input data for a call to the Python function on_step...
bool TreatModuleExceptionsAsWarnings() const override
Determines whether this module should be terminated if an exception leaves the module's main loop or ...
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition: DynExpCore.h:127
Base class for modules. Modules implement programs on their own (e.g. measurement protocols or server...
Definition: Module.h:392
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition: Module.h:743
ModuleBase(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Constructs a ModuleBase instance.
Definition: Module.cpp:189
Configurator class for ModuleBase.
Definition: Module.h:374
Data structure to contain data which is synchronized in between different threads....
Definition: Module.h:171
Refer to ParamsBase::dispatch_tag.
Definition: Module.h:189
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition: Module.h:793
Parameter class for ModuleBase.
Definition: Module.h:337
ModuleParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a ModuleBase instance.
Definition: Module.h:348
const std::thread::id OwnerThreadID
Thread id of the thread which has constructed (and owns) this Object instance.
Definition: Object.h:2302
const ParamsBasePtrType Params
Pointer to the parameter class instance belonging to this Object instance.
Definition: Object.h:2303
const ItemIDType ID
ID of the Object this parameter class instance belongs to.
Definition: Object.h:1779
const auto & GetCore() const noexcept
Returns a reference to DynExp's core.
Definition: Object.h:1677
const DynExpCore & Core
Reference to DynExp's core.
Definition: Object.h:1780
Tag for function dispatching mechanism within this class used when derived classes are not intended t...
Definition: Object.h:349
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition: Util.h:170
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
std::vector< DynExpInstr::PyDataStreamInstrument > PyStreamListType
Type of a list of data stream instruments made available to Python.
constexpr auto Instrument
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
size_t ItemIDType
ID type of objects/items managed by DynExp.
DynExpErrorCodes
DynExp's error codes
Definition: Exception.h:22
Accumulates include statements to provide a precompiled header.
Input data type passed to on_step() Python function.
PyStreamListType OutputStreams
Vector of data stream instruments to write the resulting output samples to.
PyStreamListType InputStreams
Vector of data stream instruments with input samples to be manipulated.
void Reset()
Resets all member variables of this PyStreamManipulatorInputData instance back to their default value...
DynExp::ItemIDType ModuleID
ID of the module invoking the on_step() Python function for stream manipulation.
std::chrono::time_point< std::chrono::system_clock > LastExecutionTime
Time point when the on_step() Python function was invoked last.
Output data type returned from on_step() Python function.
void Reset()
Resets all member variables of this PyStreamManipulatorOutputData instance back to their default valu...
std::chrono::milliseconds MinNextExecutionDelay
Time wo wait minimally before the on_step() Python function is called again when each input data stre...
std::chrono::milliseconds MaxNextExecutionDelay
Time to wait maximally before the on_step() Python function is called again when the input data strea...
std::vector< size_t > LastConsumedSampleIDsPerInputStream
Maintaining the order of input data streams in PyStreamManipulatorInputData::InputStreams as passed t...