13 py::bind_vector<DynExpModule::PyStreamListType>(m,
"StreamListType");
14 py::bind_vector<decltype(DynExpModule::PyStreamManipulatorOutputData::LastConsumedSampleIDsPerInputStream)>(m,
"SampleIDListType");
16 py::class_<PyStreamManipulatorInputData>(m,
"InputData")
18 .def_readonly(
"ModuleID", &PyStreamManipulatorInputData::ModuleID)
19 .def_readonly(
"LastExecutionTime", &PyStreamManipulatorInputData::LastExecutionTime)
20 .def_readwrite(
"InputStreams", &PyStreamManipulatorInputData::InputStreams)
21 .def_readwrite(
"OutputStreams", &PyStreamManipulatorInputData::OutputStreams)
22 .def_readonly(
"SaveFilename", & PyStreamManipulatorInputData::SaveFilename);
24 py::class_<PyStreamManipulatorOutputData>(m,
"OutputData")
26 .def_readwrite(
"MinNextExecutionDelay", &PyStreamManipulatorOutputData::MinNextExecutionDelay)
27 .def_readwrite(
"MaxNextExecutionDelay", &PyStreamManipulatorOutputData::MaxNextExecutionDelay)
28 .def_readwrite(
"LastConsumedSampleIDsPerInputStream", &PyStreamManipulatorOutputData::LastConsumedSampleIDsPerInputStream);
67 bool IsNewDataAvlbl =
false;
70 auto& Instrument =
ModuleData->GetInputDataStreams()[i];
71 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
74 Instrument->ReadData();
78 IsNewDataAvlbl =
true;
81 const auto now = std::chrono::system_clock::now();
122 auto& Instrument =
ModuleData->GetInputDataStreams()[i];
123 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
133 auto& Instrument =
ModuleData->GetOutputDataStreams()[i];
134 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
147 py::gil_scoped_acquire acquire;
150 if (!PyResult.is_none())
154 if (UpdateLastExecutionTime)
161 auto& Instrument =
ModuleData->GetInputDataStreams()[i];
162 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
174 SampleStream->Clear();
180 auto& Instrument =
ModuleData->GetOutputDataStreams()[i];
181 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
186 SampleStream->
Clear();
193 Instrument->WriteData();
202 auto ModuleParams = DynExp::dynamic_Params_cast<StreamManipulator>(Instance->
ParamsGetter());
208 if (ModuleParams->Communicator.ContainsID())
212 PythonCode = std::regex_replace(PythonCode, std::regex(
"\r\n"),
"\n");
213 PythonCode = std::regex_replace(PythonCode, std::regex(
"\n"), std::string(
"\n") +
Util::PyTab);
215 py::gil_scoped_acquire acquire;
217 py::exec(
"import PyModuleStreamManipulator as StreamManipulator");
220 Util::PyTab +
"if 'on_init' in locals() and callable(on_init):\n" +
222 Util::PyTab +
"if 'on_step' in locals() and callable(on_step):\n" +
224 Util::PyTab +
"if 'on_exit' in locals() and callable(on_exit):\n" +
226 Util::PyTab +
"if 'on_finished' in locals() and callable(on_finished):\n" +
228 Util::PyTab +
"if 'on_start' in locals() and callable(on_start):\n" +
230 Util::PyTab +
"if 'on_stop' in locals() and callable(on_stop):\n" +
232 Util::PyTab +
"if 'on_trigger' in locals() and callable(on_trigger):\n" +
236 ManipulatorPyFuncInit = py::hasattr(ManipulatorPyFunc,
"init") ? py::getattr(ManipulatorPyFunc,
"init") : py::none();
237 ManipulatorPyFuncStep = py::hasattr(ManipulatorPyFunc,
"step") ? py::getattr(ManipulatorPyFunc,
"step") : py::none();
238 ManipulatorPyFuncExit = py::hasattr(ManipulatorPyFunc,
"exit") ? py::getattr(ManipulatorPyFunc,
"exit") : py::none();
239 ManipulatorPyFuncFinished = py::hasattr(ManipulatorPyFunc,
"finished") ? py::getattr(ManipulatorPyFunc,
"finished") : py::none();
240 ManipulatorPyFuncStart = py::hasattr(ManipulatorPyFunc,
"start") ? py::getattr(ManipulatorPyFunc,
"start") : py::none();
241 ManipulatorPyFuncStop = py::hasattr(ManipulatorPyFunc,
"stop") ? py::getattr(ManipulatorPyFunc,
"stop") : py::none();
242 ManipulatorPyFuncTrigger = py::hasattr(ManipulatorPyFunc,
"trigger") ? py::getattr(ManipulatorPyFunc,
"trigger") : py::none();
254 for (
size_t i = 0; i <
ModuleData->GetInputDataStreams().GetList().size(); ++i)
256 auto& Instrument =
ModuleData->GetInputDataStreams()[i];
257 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
263 for (
size_t i = 0; i <
ModuleData->GetOutputDataStreams().GetList().size(); ++i)
265 auto& Instrument =
ModuleData->GetOutputDataStreams()[i];
266 auto InstrData = DynExp::dynamic_InstrumentData_cast<DynExpInstr::DataStreamInstrument>(Instrument->GetInstrumentData());
281 py::gil_scoped_acquire acquire;
PYBIND11_EMBEDDED_MODULE(PyModuleStreamManipulator, m)
PYBIND11_MAKE_OPAQUE(DynExpModule::PyStreamListType)
Implementation of a module to process data stored in data stream instrument(s) with a Python script a...
Base class for all circular data streams based on Util::circularbuf.
void Clear()
Removes all samples from the stream's buffer.
static void import()
Make the Python interpreter import this module as PyModuleDataStreamInstrument. GIL has to be acquire...
This event signals that an action (like a measurement) started by a TriggerEvent has been completed.
void Init()
Called by ResetImpl(dispatch_tag<DynExp::ModuleDataBase>) overridden by this class to initialize the ...
void ResetImpl(dispatch_tag< ModuleDataBase >) override final
Refer to DynExp::ModuleDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of ...
void OnStart(DynExp::ModuleInstance *Instance) const
Called when receiving DynExpModule::StartEvent.
void Step(Util::SynchronizedPointer< ModuleDataType > &ModuleData, const PyFuncType &StepFunction, bool UpdateLastExecutionTime=true) const
Performs a single manipulation step by preparing input data for a call to the Python function on_step...
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...
void OnTrigger(DynExp::ModuleInstance *Instance) const
Called when receiving DynExpModule::TriggerEvent.
PyFuncType ManipulatorPyFuncStep
Handle to a Python function called for each manipulation step.
PyFuncType ManipulatorPyFuncFinished
Handle to a Python function called for DynExpModule::FinishedEvent.
PyStreamManipulatorOutputData ManipulatorPyFuncOutput
Output data returned from the on_step() and event handler Python functions.
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...
PyFuncType ManipulatorPyFuncExit
Handle to a Python function called on module termination.
void OnFinished(DynExp::ModuleInstance *Instance) const
Called when receiving DynExpModule::FinishedEvent.
void ResetImpl(dispatch_tag< ModuleBase >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
PyFuncType ManipulatorPyFuncStart
Handle to a Python function called for DynExpModule::StartEvent.
void OnStop(DynExp::ModuleInstance *Instance) const
Called when receiving DynExpModule::StopEvent.
PyFuncType ManipulatorPyFuncInit
Handle to a Python function called on module initialization.
void OnExit(DynExp::ModuleInstance *Instance) const override final
This event is triggered right before the module thread terminates (not due to an exception,...
PyFuncType ManipulatorPyFuncStop
Handle to a Python function called for DynExpModule::StopEvent.
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() and event handler Python functions.
void OnSetFilename(DynExp::ModuleInstance *Instance, const std::string &Filename) const
Called when receiving DynExpModule::SetFilenameEvent.
PyFuncType ManipulatorPyFuncTrigger
Handle to a Python function called for DynExpModule::TriggerEvent.
static void Register(const ModuleBase &Listener, CallableT EventFunc, ItemIDType CommunicatorID=ItemIDNotSet)
Registers/Subscribes module Listener to the event with the event function EventFunc....
static void Deregister(const ModuleBase &Listener)
Deregisters/unsubscribes module Listener from the event, regardless of the inter-module communicator ...
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Refer to ParamsBase::dispatch_tag.
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
ItemIDType GetID() const noexcept
Returns the ID of this Object instance. Thread-safe since ID is const.
auto GetObjectName(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Returns the name of this Object instance.
Refer to ParamsBase::dispatch_tag.
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT > > &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
const auto & GetOwner() const noexcept
Returns Owner.
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
void Reset()
Removes the owned pybind11::object after locking the GIL.
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
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.
DynExpErrorCodes
DynExp's error codes
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
static constexpr auto PyTab
Character sequence to indent a Python instruction by one level.
std::string ReadFromFile(const QString &Filename)
Reads the entire content from a text file.
Accumulates include statements to provide a precompiled header.
Output data type returned from on_step() or event handler Python functions.
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...