DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
Instrument.h
Go to the documentation of this file.
1// This file is part of DynExp.
2
8#pragma once
9
10#include "stdafx.h"
11#include "Object.h"
12
13namespace DynExp
14{
15 class InstrumentBase;
16 class InstrumentInstance;
17 class ExceptionContainer;
18 class TaskBase;
19 class InitTaskBase;
20 class ExitTaskBase;
21 class UpdateTaskBase;
22
26 using InstrumentPtrType = std::shared_ptr<InstrumentBase>;
27
33 template <typename InstrumentT>
35 {
36 return std::make_shared<typename InstrumentT::ConfigType>();
37 }
38
46 template <typename InstrumentT>
47 InstrumentPtrType MakeInstrument(const std::thread::id OwnerThreadID, ParamsBasePtrType&& Params)
48 {
49 dynamic_Params_cast<InstrumentT>(Params.get())->InstrumentData = std::make_unique<typename InstrumentT::InstrumentDataType>();
50
51 return std::make_shared<InstrumentT>(OwnerThreadID, std::move(Params));
52 }
53
62 template <typename TaskT, typename... ArgTs>
63 std::unique_ptr<TaskT> MakeTask(ArgTs&& ...Args)
64 {
65 return std::make_unique<TaskT>(std::forward<ArgTs>(Args)...);
66 }
67
78 int InstrumentThreadMain(std::unique_ptr<RunnableInstance>&& InstancePtr, RunnableObject* BaseObject);
79
86 {
87 public:
92 ExceptionContainer(const std::exception_ptr& Exception = nullptr) noexcept
94
98 void Throw() const { if (Exception) std::rethrow_exception(Exception); }
99
104 bool IsError() const { return static_cast<bool>(Exception); }
105
110 auto GetException() const { return Exception; }
111
117 void ClearError() { Exception = nullptr; }
118
119 private:
120 std::exception_ptr Exception;
121 };
122
135 {
136 public:
137 using TaskQueueType = std::list<std::unique_ptr<TaskBase>>;
138 using TaskQueueIteratorType = TaskQueueType::const_iterator;
139
140 protected:
145 template <typename>
146 struct dispatch_tag {};
147
148 private:
153 {
154 friend class InstrumentDataBase;
155 friend class InstrumentBase;
156
162
163 void Reset() { Parent.Reset(); }
165 void SetException(std::exception_ptr Exception) noexcept { Parent.SetException(Exception); }
166 void EnqueueTask(std::unique_ptr<TaskBase>&& Task, bool CallFromInstrThread, bool NotifyReceiver) { Parent.EnqueueTask(std::move(Task), CallFromInstrThread, NotifyReceiver); }
167 void EnqueuePriorityTask(std::unique_ptr<TaskBase>&& Task, bool CallFromInstrThread, bool NotifyReceiver) { Parent.EnqueuePriorityTask(std::move(Task), CallFromInstrThread, NotifyReceiver); }
172
173 auto& GetNewTaskNotifier() noexcept { return Parent.GetNewTaskNotifier(); }
174
176 };
177
183 {
184 friend class InstrumentDataBase;
185 friend int InstrumentThreadMain(std::unique_ptr<RunnableInstance>&&, RunnableObject*);
186
192
193 auto& GetNewTaskNotifier() noexcept { return Parent.GetNewTaskNotifier(); }
194 void SetLastUpdateTime(std::chrono::system_clock::time_point LastUpdate) { Parent.LastUpdate = LastUpdate; }
195
197 };
198
199 public:
202
203 public:
209
214 void EnqueueTask(std::unique_ptr<TaskBase>&& Task) { EnqueueTask(std::move(Task), false, true); }
215
221 void EnqueuePriorityTask(std::unique_ptr<TaskBase>&& Task) { EnqueuePriorityTask(std::move(Task), false, true); }
222
230 std::unique_ptr<TaskBase> PopTaskFront();
231
239 std::unique_ptr<TaskBase> PopTaskBack();
240
245 auto GetTaskFront() noexcept { return TaskQueue.begin(); }
246
251 auto GetTaskBack() noexcept { return TaskQueue.end(); }
252
257 size_t GetNumEnqueuedTasks() const noexcept { return TaskQueue.size(); }
258
265 std::unique_ptr<TaskBase> PopFinishedTask();
266
271 size_t GetNumFinishedTasks() const noexcept { return FinishedTasks.size(); }
272
277 bool IsQueueClosed() const noexcept { return QueueClosed; }
279
284 auto GetLastUpdateTime() const { return LastUpdate; }
285
290 bool IsExceptionIndicated() const noexcept { return HasException; }
291
298 std::exception_ptr GetException() const noexcept;
299
302
303 private:
312 void EnqueueTask(std::unique_ptr<TaskBase>&& Task, bool CallFromInstrThread, bool NotifyReceiver);
313
322 void EnqueuePriorityTask(std::unique_ptr<TaskBase>&& Task, bool CallFromInstrThread, bool NotifyReceiver);
323
330
334 void RemoveAllTasks();
335
341
345 void CloseQueue() { QueueClosed = true; }
346
352
357
361 void Reset();
362
370
376 void IndicateException() noexcept { HasException = true; }
377
382 void SetException(std::exception_ptr Exception) noexcept;
383
387 void CheckError() const;
388
396 void CheckQueueState(bool CallFromInstrThread) const;
397
401
408
409 std::chrono::system_clock::time_point LastUpdate;
410
416 std::atomic<bool> HasException;
417
423 std::exception_ptr InstrumentException;
424 };
425
430 {
431 friend class InstrumentBase;
432
433 template <typename>
434 friend InstrumentPtrType MakeInstrument(const std::thread::id, ParamsBasePtrType&&);
435
436 public:
442
443 virtual ~InstrumentParamsBase() = 0;
444
445 virtual const char* GetParamClassTag() const noexcept override { return "InstrumentParamsBase"; }
446
447 private:
450
455 std::unique_ptr<InstrumentDataBase> InstrumentData;
456
457 DummyParam Dummy = { *this };
458 };
459
472
480 {
486 {
487 friend class InstrumentBase;
488 friend int InstrumentThreadMain(std::unique_ptr<RunnableInstance>&&, RunnableObject*);
489
495
496 auto HandleTask(InstrumentInstance& Instance) { return Parent.HandleTask(Instance); }
498 void SetException(std::exception_ptr Exception) noexcept { Parent.SetException(Exception); }
499 void OnError() { Parent.OnError(); }
501
503 };
504
505 public:
526
532
538
544
545
554
559 constexpr static auto Category() noexcept { return "General"; }
560
566 InstrumentBase(const std::thread::id OwnerThreadID, ParamsBasePtrType&& Params);
567
568 virtual ~InstrumentBase() = 0;
569
570 virtual std::string GetCategory() const override { return Category(); }
571
573
578
584 virtual std::chrono::milliseconds GetTaskQueueDelay() const { return std::chrono::milliseconds(std::chrono::milliseconds::max()); }
586
591 static constexpr auto GetInstrumentDataTimeoutDefault = std::chrono::milliseconds(1000);
592
597
607
614 InstrumentDataTypeSyncPtrConstType GetInstrumentData(const std::chrono::milliseconds Timeout = GetInstrumentDataTimeoutDefault) const;
615
621 InstrumentDataTypeSyncPtrType (InstrumentBase::*)(const std::chrono::milliseconds)>;
622
626 void UpdateData() const;
627
632 void EnqueueArriveAtLatchTask(std::latch& Latch) const;
633
638 bool IsInitialized() const { return Initialized; }
640
641 private:
646
652 InstrumentDataTypeSyncPtrType GetNonConstInstrumentData(const std::chrono::milliseconds Timeout = GetInstrumentDataTimeoutDefault) const;
654
655 protected:
660 static auto GetExceptionUnsafe(const InstrumentDataTypeSyncPtrConstType& InstrumentDataPtr) { return InstrumentDataPtr->GetException(); }
661
674 template <typename TaskT, typename... ArgTs>
675 void MakeAndEnqueueTask(ArgTs&& ...Args) const
676 {
677 auto Task = MakeTask<TaskT>(std::forward<ArgTs>(Args)...);
678
679 // Locks InstrumentData
680 GetNonConstInstrumentData()->InstrumentBaseOnly.EnqueueTask(std::move(Task), IsCallFromRunnableThread(), true);
681 }
682
683 public:
696 template <typename DerivedInstrT, typename... TaskFuncArgTs, typename... ArgTs>
697 ExceptionContainer AsSyncTask(void (DerivedInstrT::* TaskFunc)(TaskFuncArgTs...) const, ArgTs&& ...Args) const;
698
699 private:
704
712
717 void UpdateDataInternal();
718
725 void SetException(std::exception_ptr Exception) noexcept;
726
731 void OnError();
733
734 void ResetImpl(dispatch_tag<RunnableObject>) override final;
736
741 void RunChild() override final;
742 void NotifyChild() override final;
743 void TerminateChild(const std::chrono::milliseconds Timeout) override final;
744
750 void OnPrepareExit();
752
753 std::exception_ptr GetExceptionChild([[maybe_unused]] const std::chrono::milliseconds Timeout) const override final;
754 bool IsReadyChild() const override final;
755
760 virtual void OnErrorChild() const {}
761 virtual void OnPrepareExitChild() const {}
762
767 virtual bool HandleAdditionalTask() { return true; }
768
774 virtual bool UpdateAdditionalData() { return true; }
775
783 virtual std::unique_ptr<InitTaskBase> MakeInitTask() const { return nullptr; }
784
792 virtual std::unique_ptr<ExitTaskBase> MakeExitTask() const { return nullptr; }
793
801 virtual std::unique_ptr<UpdateTaskBase> MakeUpdateTask() const { return nullptr; }
803
804 const std::unique_ptr<InstrumentDataType> InstrumentData;
805 std::atomic<bool> Initialized = false;
806 };
807
834
848 template <typename To, typename From, std::enable_if_t<
849 std::is_same_v<InstrumentDataBase, std::remove_cv_t<From>>, int> = 0
850 >
852 {
853 if (!InstrumentDataPtr)
854 throw Util::InvalidArgException("InstrumentDataPtr must not be nullptr.");
855
857 std::conditional_t<std::is_const_v<From>, std::add_const_t<typename To::InstrumentDataType>, typename To::InstrumentDataType>
858 >(std::move(InstrumentDataPtr));
859 }
860
865 {
866 public:
870 enum class ContinuationType : bool {
871 Continue,
872 Terminate
873 };
874
878 enum class AbortedType : bool {
879 NotAborted,
880 Aborted
881 };
882
892
897 constexpr bool ShouldContinue() const noexcept { return Continue == ContinuationType::Continue; }
898
904
909 constexpr bool HasAborted() const noexcept { return Aborted == AbortedType::Aborted; }
910
915 constexpr int GetErrorCode() const noexcept { return ErrorCode; }
916
917 private:
920 const int ErrorCode;
921 };
922
929 {
934 {
935 friend class TaskBase;
936 friend class InstrumentBase;
937
943
944 void Lock() { Parent.Lock(); }
945 auto Run(InstrumentInstance& Instance) { return Parent.Run(Instance); }
947
949 };
950
955 {
956 friend class TaskBase;
957 friend class InstrumentDataBase;
958
964
965 bool KeepFinishedTask() const noexcept { return Parent.KeepFinishedTask(); }
966
968 };
969
970 public:
978 {
979 public:
986 using FuncType = std::function<void(const TaskBase*, ExceptionContainer&)>;
987
992
996 CallbackType(std::nullptr_t) : CallbackFunc() {}
997
1003
1009 CallbackType(CallbackType&& Other);
1010
1015 ~CallbackType();
1016
1022 template <typename... ArgTs>
1023 void operator()(ArgTs&& ...Args)
1024 {
1026 {
1027 HasBeenCalled = true;
1028
1029 CallbackFunc(std::forward<ArgTs>(Args)...);
1030 }
1031 }
1032
1036 operator bool() const noexcept { return static_cast<bool>(CallbackFunc); }
1037
1038 private:
1040
1041 bool HasBeenCalled = false;
1042 };
1043
1084 TaskBase(CallbackType CallbackFunc = nullptr, std::chrono::system_clock::time_point DeferUntil = {}) noexcept
1088
1097 TaskBase(TaskBase& Other, std::chrono::system_clock::time_point DeferUntil = {}) noexcept
1098 : TaskBase(std::move(Other.CallbackFunc), DeferUntil) {}
1099
1104 virtual ~TaskBase() = 0;
1105
1110
1114 auto GetDeferUntil() const noexcept { return DeferUntil; }
1115
1120 TaskState GetState() const noexcept { return State; }
1121
1126 bool IsLocked() const noexcept;
1127
1133 bool IsAborting() const noexcept { return ShouldAbort; }
1134
1139 int GetErrorCode() const noexcept { return ErrorCode; }
1140
1146 void Abort() { ShouldAbort = true; }
1148
1151
1152 private:
1157 void Lock();
1158
1174
1180
1187 virtual bool KeepFinishedTask() const noexcept { return false; }
1189
1196
1203 const std::chrono::system_clock::time_point DeferUntil;
1204
1209 std::atomic<TaskState> State;
1210 std::atomic<int> ErrorCode;
1212
1217 std::atomic<bool> ShouldAbort;
1219 };
1220
1221 template <typename DerivedInstrT, typename... TaskFuncArgTs, typename... ArgTs>
1222 ExceptionContainer InstrumentBase::AsSyncTask(void (DerivedInstrT::* TaskFunc)(TaskFuncArgTs...) const, ArgTs&& ...Args) const
1223 {
1224 std::atomic<bool> FinishedFlag = false;
1225 ExceptionContainer Exception;
1226 auto CallbackFunc = TaskBase::CallbackType::FuncType([&FinishedFlag, &Exception](const TaskBase*, auto E) {
1227 Exception = E;
1228
1229 // Must come last!
1230 FinishedFlag = true;
1231 });
1232
1233 (dynamic_cast<const DerivedInstrT&>(*this).*TaskFunc)(std::forward<ArgTs>(Args)..., std::move(CallbackFunc));
1234
1235 while (!FinishedFlag)
1236 std::this_thread::yield();
1237
1238 return Exception;
1239 }
1240
1248 class DefaultTask final : public TaskBase
1249 {
1250 public:
1254 DefaultTask(CallbackType CallbackFunc, std::chrono::system_clock::time_point DeferUntil = {}) noexcept
1255 : TaskBase(std::move(CallbackFunc), DeferUntil) {}
1256
1257 private:
1258 virtual TaskResultType RunChild(InstrumentInstance& Instance) override { return {}; }
1259 };
1260
1268 class InitTaskBase : public TaskBase
1269 {
1270 protected:
1275 template <typename>
1276 struct dispatch_tag {};
1277
1278 private:
1279 TaskResultType RunChild(InstrumentInstance& Instance) override final;
1280
1290 };
1291
1299 class ExitTaskBase : public TaskBase
1300 {
1301 protected:
1306 template <typename>
1307 struct dispatch_tag {};
1308
1309 private:
1310 TaskResultType RunChild(InstrumentInstance& Instance) override final;
1311
1321 };
1322
1331 {
1332 protected:
1337 template <typename>
1338 struct dispatch_tag {};
1339
1340 private:
1341 TaskResultType RunChild(InstrumentInstance& Instance) override final;
1342
1352 };
1353
1360 class ArriveAtLatchTask final : public TaskBase
1361 {
1362 public:
1368 : TaskBase(std::move(CallbackFunc)), Latch(Latch) {}
1369
1375
1376 private:
1377 virtual TaskResultType RunChild(InstrumentInstance& Instance) override;
1378
1379 std::latch& Latch;
1380 bool HasArrived = false;
1381 };
1382
1389 template <typename... InstrTs>
1390 void WaitForInstruments(InstrTs&... Instruments)
1391 {
1392 static_assert(std::conjunction_v<std::is_base_of<InstrumentBase, InstrTs>...>);
1393 static_assert(sizeof...(InstrTs) > 0);
1394 static_assert(sizeof...(InstrTs) <= std::latch::max());
1395
1396 std::latch Latch(sizeof...(InstrTs));
1397 std::array<std::reference_wrapper<const InstrumentBase>, sizeof...(InstrTs)> Instrs{ Instruments... };
1398
1399 for (auto& Instr : Instrs)
1400 Instr.get().EnqueueArriveAtLatchTask(Latch);
1401
1402 Latch.wait();
1403 }
1404}
1405
1410namespace DynExpInstr {};
Implementation of DynExp objects as the base for derived resources and implementation of the object p...
Defines a task which arrives at a std::latch when it is executed. This is useful to synchronize multi...
~ArriveAtLatchTask()
If the task has been aborted or never executed, the destructor arrives at the latch in order to avoid...
ArriveAtLatchTask(std::latch &Latch, CallbackType CallbackFunc=nullptr)
Constructs an instrument task.
bool HasArrived
Indicates whether the task has already arrived at the latch.
std::latch & Latch
Latch the task arrives at when it is executed.
virtual TaskResultType RunChild(InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Default task which does not do anything. Though, calling it ensures that TaskBase::CallbackFunc gets ...
DefaultTask(CallbackType CallbackFunc, std::chrono::system_clock::time_point DeferUntil={}) noexcept
Constructs an instrument task.
virtual TaskResultType RunChild(InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition DynExpCore.h:127
Wrapper holding a pointer to an exception and providing functionality for accessing it....
Definition Instrument.h:86
auto GetException() const
Getter for Exception.
Definition Instrument.h:110
std::exception_ptr Exception
Exception stored in the wrapper.
Definition Instrument.h:120
void ClearError()
Removes the stored exception. If this method is called by a task's CallbackFunc in case of an excepti...
Definition Instrument.h:117
ExceptionContainer(const std::exception_ptr &Exception=nullptr) noexcept
Constructs an ExceptionContainer instance.
Definition Instrument.h:92
bool IsError() const
Checks whether the wrapper holds an exception.
Definition Instrument.h:104
void Throw() const
Throws the stored exception. Doesn't do anything if there isn't a stored exception.
Definition Instrument.h:98
Defines a task for deinitializing an instrument within an instrument inheritance hierarchy....
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual void ExitFuncImpl(dispatch_tag< ExitTaskBase >, InstrumentInstance &Instance)=0
Deinitializes the respective instrument within the instrument inheritance hierarchy....
Refer to DynExp::ParamsBase::dispatch_tag.
Defines a task for initializing an instrument within an instrument inheritance hierarchy....
virtual void InitFuncImpl(dispatch_tag< InitTaskBase >, InstrumentInstance &Instance)=0
Initializes the respective instrument within the instrument inheritance hierarchy....
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Refer to DynExp::ParamsBase::dispatch_tag.
Allow exclusive access to some of InstrumentBase's private methods to the instrument thread Instrumen...
Definition Instrument.h:486
constexpr InstrumenThreadOnlyType(InstrumentBase &Parent) noexcept
Construcs an instance - one for each InstrumentBase instance.
Definition Instrument.h:494
void UpdateData()
Inserts an update task (UpdateTaskBase) into the instrument's task queue. Override UpdateAdditionalDa...
Definition Instrument.h:497
InstrumentBase & Parent
Owning InstrumentBase instance.
Definition Instrument.h:502
auto HandleTask(InstrumentInstance &Instance)
Executes and removes the next pending task from the instrument's task queue.
Definition Instrument.h:496
friend int InstrumentThreadMain(std::unique_ptr< RunnableInstance > &&, RunnableObject *)
Instruments run in their own thread. This is the instrument thread's main function.
Definition Instrument.cpp:8
void OnError()
Derived classes can perform critical shutdown actions after an error has occurred....
Definition Instrument.h:499
void SetInitialized()
Sets InstrumentBase::Initialized to true.
Definition Instrument.h:500
void SetException(std::exception_ptr Exception) noexcept
Sets this instrument instance to an error state and tries to store the exception responsible for the ...
Definition Instrument.h:498
Base class for instruments. Instruments comprise virtual devices (meta instruments) and physial devic...
Definition Instrument.h:480
static auto GetExceptionUnsafe(const InstrumentDataTypeSyncPtrConstType &InstrumentDataPtr)
Getter for InstrumentDataBase::InstrumentException. If InstrumentDataBase::InstrumentException is nul...
Definition Instrument.h:660
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
void ResetImpl(dispatch_tag< RunnableObject >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual bool UpdateAdditionalData()
Determines whether to enqueue update tasks (UpdateTaskBase).
Definition Instrument.h:774
TaskHandlingContinuationType HandleTask(InstrumentInstance &Instance)
Executes and removes the next pending task from the instrument's task queue.
virtual void ResetImpl(dispatch_tag< InstrumentBase >)=0
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
std::exception_ptr GetExceptionChild(const std::chrono::milliseconds Timeout) const override final
Returns a pointer to the exception which has caused this Object instance to fail.
void UpdateData() const
Enqueues an update task (instance of class UpdateTaskBase).
std::atomic< bool > Initialized
Determines whether the init task (InitTaskBase) has run.
Definition Instrument.h:805
void OnPrepareExit()
This function enables derived classes to enqueue tasks to be executed directly before the final exit ...
void SetException(std::exception_ptr Exception) noexcept
Sets this instrument instance to an error state and tries to store the exception responsible for the ...
void EnqueueArriveAtLatchTask(std::latch &Latch) const
Enqueues a task which arrives at a latch when executed (instance of class ArriveAtLatchTask).
void MakeAndEnqueueTask(ArgTs &&...Args) const
Calls MakeTask() to construct a new task and subsequently enqueues the task into the instrument's tas...
Definition Instrument.h:675
virtual std::chrono::milliseconds GetTaskQueueDelay() const
Specifies in which time intervals the instrument's task queue runs to handle pending tasks.
Definition Instrument.h:584
virtual void OnPrepareExitChild() const
This function enables derived classes to enqueue tasks to be executed directly before the final exit ...
Definition Instrument.h:761
virtual std::unique_ptr< InitTaskBase > MakeInitTask() const
Factory function for an init task (InitTaskBase). Override to define the desired initialization task ...
Definition Instrument.h:783
void UpdateDataInternal()
Inserts an update task (UpdateTaskBase) into the instrument's task queue. Override UpdateAdditionalDa...
static constexpr auto GetInstrumentDataTimeoutDefault
Determines the default timeout for GetInstrumentData() to lock the mutex synchronizing the instrument...
Definition Instrument.h:591
void TerminateChild(const std::chrono::milliseconds Timeout) override final
Signals derived classes that terminating the RunnableObject instance's thread is about to be requeste...
virtual void OnErrorChild() const
Derived classes can perform critical shutdown actions after an error has occurred....
Definition Instrument.h:760
void RunChild() override final
Refer to Run().
static constexpr auto Category() noexcept
Every derived class has to redefine this function.
Definition Instrument.h:559
InstrumentDataTypeSyncPtrType GetInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault)
Locks the mutex of the instrument data class instance InstrumentData assigned to this InstrumentBase ...
Util::SynchronizedPointer< InstrumentDataType > InstrumentDataTypeSyncPtrType
Alias for the return type of InstrumentBase::GetInstrumentData(). Data class instances wrapped into U...
Definition Instrument.h:537
InstrumenThreadOnlyType InstrumentThreadOnly
Allow exclusive access to some of InstrumentBase's private methods to the instrument thread Instrumen...
Definition Instrument.h:572
virtual bool HandleAdditionalTask()
Determines whether task handling should continue.
Definition Instrument.h:767
ExceptionContainer AsSyncTask(void(DerivedInstrT::*TaskFunc)(TaskFuncArgTs...) const, ArgTs &&...Args) const
Calls a (derived) instrument's function which inserts a task into the instrument's task queue synchro...
InstrumentDataTypeSyncPtrType GetNonConstInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault) const
Always allows InstrumentBase to obtain a non-const pointer to the instrument's data - even in const t...
void OnError()
Derived classes can perform critical shutdown actions after an error has occurred....
virtual ~InstrumentBase()=0
virtual std::unique_ptr< ExitTaskBase > MakeExitTask() const
Factory function for an exit task (ExitTaskBase). Override to define the desired deinitialization tas...
Definition Instrument.h:792
virtual std::unique_ptr< UpdateTaskBase > MakeUpdateTask() const
Factory function for an update task (UpdateTaskBase). Override to define the desired update task in d...
Definition Instrument.h:801
TaskHandlingContinuationType
Indicates how an instrument should proceed after handling a task.
Definition Instrument.h:509
virtual std::string GetCategory() const override
Returns the category of this Object type.
Definition Instrument.h:570
const std::unique_ptr< InstrumentDataType > InstrumentData
Instrument data belonging to this InstrumentBase instance.
Definition Instrument.h:804
bool IsInitialized() const
Getter for Initialized.
Definition Instrument.h:638
void NotifyChild() override final
Notify derived classes that some state has changed (e.g. the termination of Thread is requested) and ...
Configurator class for InstrumentBase.
Definition Instrument.h:464
Allow exclusive access to some of InstrumentDataBase's private methods to the instrument thread Instr...
Definition Instrument.h:183
constexpr InstrumenThreadOnlyType(InstrumentDataBase &Parent) noexcept
Construcs an instance - one for each InstrumentDataBase instance.
Definition Instrument.h:191
InstrumentDataBase & Parent
Owning InstrumentDataBase instance.
Definition Instrument.h:196
friend int InstrumentThreadMain(std::unique_ptr< RunnableInstance > &&, RunnableObject *)
Instruments run in their own thread. This is the instrument thread's main function.
Definition Instrument.cpp:8
auto & GetNewTaskNotifier() noexcept
Getter for NewTaskNotifier.
Definition Instrument.h:193
void SetLastUpdateTime(std::chrono::system_clock::time_point LastUpdate)
Setter for InstrumentDataBase::LastUpdate.
Definition Instrument.h:194
Allow exclusive access to some of InstrumentDataBase's private methods to InstrumentBase.
Definition Instrument.h:153
auto & GetNewTaskNotifier() noexcept
Getter for NewTaskNotifier.
Definition Instrument.h:173
constexpr InstrumentBaseOnlyType(InstrumentDataBase &Parent) noexcept
Construcs an instance - one for each InstrumentDataBase instance.
Definition Instrument.h:161
void Reset()
Resets the InstrumentDataBase's instance and calls ResetImpl(dispatch_tag<InstrumentDataBase>) subseq...
Definition Instrument.h:163
InstrumentDataBase & Parent
Owning InstrumentDataBase instance.
Definition Instrument.h:175
void IndicateException() noexcept
Indicates to the main thread that an exception has happened in the instrument thread....
Definition Instrument.h:164
void CloseQueue()
Clsoes the instrument's task queue setting QueueClosed to true.
Definition Instrument.h:171
void SetException(std::exception_ptr Exception) noexcept
Setter for InstrumentException.
Definition Instrument.h:165
void RemoveTaskFromQueue(TaskQueueIteratorType &Task)
Removes a task from the instrument's task queue and inserts it into the instrument's list of finished...
Definition Instrument.h:168
void RemoveAllTasks()
Clears the instrument's task queue.
Definition Instrument.h:169
void EnqueuePriorityTask(std::unique_ptr< TaskBase > &&Task, bool CallFromInstrThread, bool NotifyReceiver)
Enqueues a task at the front of an instrument's task queue and notifies the instrument about the new ...
Definition Instrument.h:167
void EnqueueTask(std::unique_ptr< TaskBase > &&Task, bool CallFromInstrThread, bool NotifyReceiver)
Enqueues a task at the back of an instrument's task queue and notifies the instrument about the new t...
Definition Instrument.h:166
void RemoveAllTasksExceptFront()
Clears the instrument's task queue but keeps the front task (the task with highest priority which is ...
Definition Instrument.h:170
Data structure to contain data which is synchronized in between different threads....
Definition Instrument.h:135
bool IsExceptionIndicated() const noexcept
Getter for HasException. Only performs atomic operations. Hence, this instrument data instance does n...
Definition Instrument.h:290
virtual void ResetImpl(dispatch_tag< InstrumentDataBase >)
Refer to DynExp::InstrumentDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl()...
Definition Instrument.h:368
std::list< std::unique_ptr< TaskBase > > TaskQueueType
Type of an instrument task queue owning the tasks within.
Definition Instrument.h:137
TaskQueueType TaskQueue
FIFO task queue of the instrument owning this InstrumentDataBase instance.
Definition Instrument.h:398
std::chrono::system_clock::time_point LastUpdate
Time point when the instrument thread called InstrumentBase::UpdateDataInternal() the last time.
Definition Instrument.h:409
auto GetLastUpdateTime() const
Getter for LastUpdate.
Definition Instrument.h:284
void CheckError() const
Throws InstrumentException if it is not nullptr using Util::ForwardException().
bool IsQueueClosed() const noexcept
Determines whether the instrument task queue is closed.
Definition Instrument.h:277
void Reset()
Resets the InstrumentDataBase's instance and calls ResetImpl(dispatch_tag<InstrumentDataBase>) subseq...
std::unique_ptr< TaskBase > PopTaskBack()
Removes a task from the back of an instrument's task queue.
Util::OneToOneNotifier & GetNewTaskNotifier() noexcept
Getter for NewTaskNotifier.
Definition Instrument.h:351
void EnqueuePriorityTask(std::unique_ptr< TaskBase > &&Task)
Enqueues a task at the front of an instrument's task queue and notifies the instrument about the new ...
Definition Instrument.h:221
InstrumentBaseOnlyType InstrumentBaseOnly
Allow exclusive access to some of InstrumentDataBase's private methods to InstrumentBase.
Definition Instrument.h:300
std::atomic< bool > HasException
If set to true, indicates to the main thread that an exception has happened in the instrument thread....
Definition Instrument.h:416
void RemoveAllTasks()
Clears the instrument's task queue.
TaskQueueType::const_iterator TaskQueueIteratorType
Const iterator type to elements of TaskQueueType.
Definition Instrument.h:138
void CloseQueue()
Clsoes the instrument's task queue setting QueueClosed to true.
Definition Instrument.h:345
auto GetTaskFront() noexcept
Getter for first enqueued task.
Definition Instrument.h:245
void EnqueueTask(std::unique_ptr< TaskBase > &&Task)
Enqueues a task at the back of an instrument's task queue and notifies the instrument about the new t...
Definition Instrument.h:214
void IndicateException() noexcept
Indicates to the main thread that an exception has happened in the instrument thread....
Definition Instrument.h:376
std::unique_ptr< TaskBase > PopTaskFront()
Removes a task from the front of an instrument's task queue.
std::exception_ptr GetException() const noexcept
Getter for InstrumentDataBase::InstrumentException. If InstrumentDataBase::InstrumentException is nul...
Util::OneToOneNotifier NewTaskNotifier
Used to notify the instrument thread about new tasks when enqueuing tasks into the task queue....
Definition Instrument.h:407
void SetException(std::exception_ptr Exception) noexcept
Setter for InstrumentException.
InstrumenThreadOnlyType InstrumentThreadOnly
Allow exclusive access to some of InstrumentDataBase's private methods to the instrument thread Instr...
Definition Instrument.h:301
size_t GetNumFinishedTasks() const noexcept
Getter for the length of the instrument's list of finished tasks.
Definition Instrument.h:271
std::exception_ptr InstrumentException
Used to transfer exceptions from the instrument thread to the main thread. Stores the exception respo...
Definition Instrument.h:423
std::unique_ptr< TaskBase > PopFinishedTask()
Removes a task from the front of an instrument's list of finished tasks.
void RemoveAllTasksExceptFront()
Clears the instrument's task queue but keeps the front task (the task with highest priority which is ...
void CheckQueueState(bool CallFromInstrThread) const
Checks whether it is currently allowed to enqueue tasks into the instrument task queue.
size_t GetNumEnqueuedTasks() const noexcept
Getter for the instrument task queue's length.
Definition Instrument.h:257
void RemoveTaskFromQueue(TaskQueueIteratorType &Task)
Removes a task from the instrument's task queue and inserts it into the instrument's list of finished...
bool QueueClosed
If set to true, no new tasks can be enqueued (useful if an instrument is e.g. stopped).
Definition Instrument.h:400
auto GetTaskBack() noexcept
Getter for last enqueued task.
Definition Instrument.h:251
TaskQueueType FinishedTasks
List of the instrument's finished tasks. Tasks are moved here from TaskQueue after completion.
Definition Instrument.h:399
Refer to ParamsBase::dispatch_tag.
Definition Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition Instrument.h:813
const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter
Getter for instrument's data. Refer to InstrumentBase::InstrumentDataGetterType.
Definition Instrument.h:832
Parameter class for InstrumentBase.
Definition Instrument.h:430
virtual void ConfigureParamsImpl(dispatch_tag< InstrumentParamsBase >)
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Instrument.h:449
DummyParam Dummy
Dummy parameter which is to be owned once by parameter classes that do not contain any other paramete...
Definition Instrument.h:457
std::unique_ptr< InstrumentDataBase > InstrumentData
Just used temporarily during the construction of an instrument. Refer to MakeInstrument() and to Inst...
Definition Instrument.h:455
InstrumentParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a InstrumentBase instance.
Definition Instrument.h:441
void ConfigureParamsImpl(dispatch_tag< RunnableObjectParams >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Instrument.h:448
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...
Definition Instrument.h:445
friend InstrumentPtrType MakeInstrument(const std::thread::id, ParamsBasePtrType &&)
Factory function to generate an instrument of a specific type.
Definition Instrument.h:47
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
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2018
Dummy parameter which is to be owned once by parameter classes that do not contain any other paramete...
Definition Object.h:522
const ItemIDType ID
ID of the Object this parameter class instance belongs to.
Definition Object.h:1779
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
Defines data for a thread belonging to a RunnableObject instance. This data is only accessed by the R...
Definition Object.h:3513
const RunnableObject & Owner
RunnableObject instance which operates on this RunnableInstance (by its thread). The RunnableObject i...
Definition Object.h:3746
std::promise< void > ThreadExitedPromise
Signals the RunnableObject instance owning the thread that its thread has terminated....
Definition Object.h:3760
Configurator class for RunnableObject.
Definition Object.h:2412
Parameter class for RunnableObject.
Definition Object.h:2349
Defines an Object which possesses a thread it runs in. The RunnableObject can be started and stopped ...
Definition Object.h:2426
bool IsCallFromRunnableThread() const
Checks whether Thread's id matches the id of the calling thread. This is thread-safe if the function ...
Definition Object.cpp:658
Type owning a callback function which is invoked when a task has finished, failed,...
Definition Instrument.h:978
bool HasBeenCalled
Indicates whether CallbackFunc has been invoked already.
CallbackType(std::nullptr_t)
Constructs a CallbackType instance with an empty CallbackFunc.
Definition Instrument.h:996
void operator()(ArgTs &&...Args)
Invokes CallbackFunc if it has not been invoked before.
~CallbackType()
Calls operator()() passing nullptr to the first argument of FuncType. Swallows all exceptions possibl...
const FuncType CallbackFunc
Pointer to the owned callback function.
CallbackType()
Constructs a CallbackType instance with an empty CallbackFunc.
Definition Instrument.h:991
CallbackType(FuncType &&CallbackFunc)
Constructs a CallbackType instance owning a callback function.
std::function< void(const TaskBase *, ExceptionContainer &)> FuncType
Type of the owned callback function. The function receives a pointer to the task the CallbackType ins...
Definition Instrument.h:986
Allow exclusive access to some of TaskBase's private methods to InstrumentBase.
Definition Instrument.h:934
void Lock()
Locks the task to prepare it for execution.
Definition Instrument.h:944
auto Run(InstrumentInstance &Instance)
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition Instrument.h:945
constexpr InstrumentBaseOnlyType(TaskBase &Parent) noexcept
Construcs an instance - one for each TaskBase instance.
Definition Instrument.h:942
void SetAborted()
Sets TaskBase::State to TaskBase::TaskState::Aborted.
Definition Instrument.h:946
TaskBase & Parent
Owning TaskBase instance.
Definition Instrument.h:948
Allow exclusive access to some of TaskBase's private methods to InstrumentDataBase.
Definition Instrument.h:955
TaskBase & Parent
Owning TaskBase instance.
Definition Instrument.h:967
bool KeepFinishedTask() const noexcept
Determines whether the task should be kept to check its results after execution. InstrumentDataBase::...
Definition Instrument.h:965
constexpr InstrumentDataBaseOnlyType(TaskBase &Parent) noexcept
Construcs an instance - one for each TaskBase instance.
Definition Instrument.h:963
Base class for all tasks being processed by instruments. The class must not contain public virtual fu...
Definition Instrument.h:929
CallbackType CallbackFunc
This callback function is called after the task has finished (either successfully or not) with a poin...
void Abort()
Requests the task to abort. There is no guarantee that the derived task does call IsAborting() to che...
void Lock()
Locks the task to prepare it for execution.
const std::chrono::system_clock::time_point DeferUntil
The execution of this task is deferred until the specified point in time is reached if time_since_epo...
auto GetDeferUntil() const noexcept
Getter for the instrument task's earliest execution time point.
int GetErrorCode() const noexcept
Getter for the error code related to an error possibly occurred while the task was executed.
bool IsAborting() const noexcept
Determines whether the task should abort. A derived task is encouraged to call this method before per...
virtual TaskResultType RunChild(InstrumentInstance &Instance)=0
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
std::atomic< int > ErrorCode
Holds the error code of an error which occurred during execution of the task function.
std::atomic< TaskState > State
Holds the task's current state. Refer to TaskBase::TaskState.
InstrumentBaseOnlyType InstrumentBaseOnly
Allow exclusive access to some of TaskBase's private methods to InstrumentBase.
bool IsLocked() const noexcept
Determines whether the task is locked.
TaskBase(CallbackType CallbackFunc=nullptr, std::chrono::system_clock::time_point DeferUntil={}) noexcept
Constructs an instrument task.
TaskBase(TaskBase &Other, std::chrono::system_clock::time_point DeferUntil={}) noexcept
Constructs an instrument task, moving CallbackFunc from another task to this task....
InstrumentDataBaseOnlyType InstrumentDataBaseOnly
Allow exclusive access to some of TaskBase's private methods to InstrumentDataBase.
std::atomic< bool > ShouldAbort
Indicates whether the task should abort. Refer to Abort() and IsAborting().
TaskState GetState() const noexcept
Getter for the instrument task's current state.
virtual bool KeepFinishedTask() const noexcept
Determines whether the task should be kept to check its results after execution. InstrumentDataBase::...
virtual ~TaskBase()=0
The destructor aborts a waiting task setting State to TaskState::Aborted. Then, it calls CallbackFunc...
TaskState
Defines states an instrument's task can undergo. Possible state transitions are:
InstrumentBase::TaskHandlingContinuationType Run(InstrumentInstance &Instance)
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Defines the return type of task functions.
Definition Instrument.h:865
constexpr TaskResultType(const ContinuationType Continue=ContinuationType::Continue, const AbortedType Aborted=AbortedType::NotAborted, const int ErrorCode=0) noexcept
Constructs a TaskResultType instance.
Definition Instrument.h:889
ContinuationType
Determines whether an instrument should terminate after handling a task.
Definition Instrument.h:870
@ Terminate
Task handling should not continue, the instrument should terminate.
@ Continue
Task handling should continue, the instrument does not terminate.
constexpr int GetErrorCode() const noexcept
Getter for the error code of an error which occurred during execution of the task function.
Definition Instrument.h:915
const int ErrorCode
DynExp error code from DynExpErrorCodes::DynExpErrorCodes. Anything else than 0 indicates an error.
Definition Instrument.h:920
constexpr InstrumentBase::TaskHandlingContinuationType ToTaskHandlingContinuationType() const noexcept
Converts Continue to InstrumentBase::TaskHandlingContinuationType.
constexpr bool ShouldContinue() const noexcept
Determines whether the instrument having handled this task should continue or terminate.
Definition Instrument.h:897
const AbortedType Aborted
Determines whether a task has been aborted.
Definition Instrument.h:919
constexpr bool HasAborted() const noexcept
Determines whether this task has been aborted.
Definition Instrument.h:909
AbortedType
Determines whether a task has been aborted.
Definition Instrument.h:878
@ NotAborted
The task has not been aborted.
@ Aborted
The task has been aborted.
const ContinuationType Continue
Determines whether an instrument should terminate after handling a task.
Definition Instrument.h:918
Defines a task for updating an instrument within an instrument inheritance hierarchy....
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
virtual void UpdateFuncImpl(dispatch_tag< UpdateTaskBase >, InstrumentInstance &Instance)=0
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
Refer to DynExp::ParamsBase::dispatch_tag.
Wraps a member function of some object and stores its default arguments. Moving from CallableMemberWr...
Definition Util.h:448
Interface to allow synchronizing the access to derived classes between different threads by making th...
Definition Util.h:93
An invalid argument like a null pointer has been passed to a function.
Definition Exception.h:138
Helper class to communicate flags between different threads based on a condition variable and a mutex...
Definition Util.h:265
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition Util.h:170
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
DynExp's main namespace contains the implementation of DynExp including classes to manage resources (...
InstrumentPtrType MakeInstrument(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Factory function to generate an instrument of a specific type.
Definition Instrument.h:47
int InstrumentThreadMain(std::unique_ptr< RunnableInstance > &&InstancePtr, RunnableObject *BaseObject)
Instruments run in their own thread. This is the instrument thread's main function.
Definition Instrument.cpp:8
std::shared_ptr< InstrumentBase > InstrumentPtrType
Pointer type to store an instrument (DynExp::InstrumentBase) with.
Definition Instrument.h:26
void WaitForInstruments(InstrTs &... Instruments)
Blocks until every instrument passed to the function as a reference parameter has arrived at a synchr...
auto dynamic_InstrumentData_cast(Util::SynchronizedPointer< From > &&InstrumentDataPtr)
Casts the data base class From into a derived InstrumentBase's (To) data class keeping the data locke...
Definition Instrument.h:851
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.
std::unique_ptr< TaskT > MakeTask(ArgTs &&...Args)
Factory function to create a task to be enqueued in an instrument's task queue.
Definition Instrument.h:63
ConfiguratorBasePtrType MakeInstrumentConfig()
Factory function to generate a configurator for a specific instrument type.
Definition Instrument.h:34
std::shared_ptr< ConfiguratorBase > ConfiguratorBasePtrType
Alias for a pointer to the configurator base class ConfiguratorBase.
Definition Object.h:1959
Accumulates include statements to provide a precompiled header.