DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
Module.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 ModuleBase;
16 class ModuleInstance;
17 class EventListenersBase;
18 class InterModuleEventLibrary;
19 class QModuleBase;
20 class QMLModuleBase;
21
25 using ModulePtrType = std::unique_ptr<ModuleBase>;
26
32 template <typename ModuleT>
34 {
35 return std::make_shared<typename ModuleT::ConfigType>();
36 }
37
45 template <typename ModuleT>
46 ModulePtrType MakeModule(const std::thread::id OwnerThreadID, ParamsBasePtrType&& Params)
47 {
48 dynamic_Params_cast<ModuleT>(Params.get())->ModuleData = std::make_unique<typename ModuleT::ModuleDataType>();
49
50 return std::make_unique<ModuleT>(OwnerThreadID, std::move(Params));
51 }
52
63 int ModuleThreadMain(std::unique_ptr<RunnableInstance>&& InstancePtr, RunnableObject* BaseObject);
64
69 {
70 public:
71 EventBase() = default;
72 virtual ~EventBase() = 0;
73
79 void Invoke(ModuleInstance& Instance) const { InvokeChild(Instance); }
80
81 private:
86 virtual void InvokeChild(ModuleInstance& Instance) const = 0;
88 };
89
96 template <typename ReceiverType, typename ArgTupleType>
97 class DefaultEvent : public EventBase
98 {
99 private:
104 template <size_t... Indices>
106 {
107 constexpr EventFuncTraits() = default;
108
114 using EventFuncPtrType = void (ReceiverType::*)(ModuleInstance*, std::tuple_element_t<Indices, ArgTupleType>...) const;
115
120 };
121
127 template <size_t... Indices>
128 constexpr static auto MakeEventFuncTraits(std::index_sequence<Indices...>) { return EventFuncTraits<Indices...>(); }
129
133 using ArgTupleIndexSequenceType = decltype(std::make_index_sequence<std::tuple_size_v<ArgTupleType>>());
134
138 using InstantiatedEventFuncTraitsType = decltype(DefaultEvent<ReceiverType, ArgTupleType>::MakeEventFuncTraits(std::declval<ArgTupleIndexSequenceType>()));
139
140 public:
141 using EventFuncPtrType = typename InstantiatedEventFuncTraitsType::EventFuncPtrType;
142 using EventFuncType = typename InstantiatedEventFuncTraitsType::EventFuncType;
143
149
150 virtual ~DefaultEvent() {}
151
152 private:
153 virtual void InvokeChild(ModuleInstance& Instance) const override { EventFunc(&Instance); }
154
159 };
160
174 {
175 public:
179 using EventPtrType = std::unique_ptr<EventBase>;
180
184 using EventQueueType = std::queue<EventPtrType>;
185
186 protected:
191 template <typename>
192 struct dispatch_tag {};
193
194 private:
199 {
200 friend class ModuleDataBase;
201 friend class ModuleBase;
202
208
209 void Reset() { Parent.Reset(); }
211 void SetException(std::exception_ptr Exception) noexcept { Parent.SetException(Exception); }
212
213 auto& GetNewEventNotifier() noexcept { return Parent.GetNewEventNotifier(); }
214
216 };
217
223 {
224 friend class ModuleDataBase;
225 friend int ModuleThreadMain(std::unique_ptr<RunnableInstance>&&, RunnableObject*);
226
232
233 auto& GetNewEventNotifier() noexcept { return Parent.GetNewEventNotifier(); }
234
236 };
237
238 public:
240 virtual ~ModuleDataBase() {}
241
247
254 void EnqueueEvent(EventPtrType&& Event);
255
262
268 const auto& GetEventFront() const noexcept { return *EventQueue.front().get(); }
269
274 auto& GetEventFront() noexcept { return *EventQueue.front().get(); }
275
280 size_t GetNumEnqueuedEvents() const noexcept { return EventQueue.size(); }
281
287
292 bool IsExceptionIndicated() const noexcept { return HasException; }
293
300 std::exception_ptr GetException() const noexcept;
301
304
305 private:
310 Util::OneToOneNotifier& GetNewEventNotifier() noexcept { return NewEventNotifier; }
311
316
320 void Reset();
321
329
335 void IndicateException() noexcept { HasException = true; }
336
341 void SetException(std::exception_ptr Exception) noexcept;
342
347
354
360 std::atomic<bool> HasException;
361
367 std::exception_ptr ModuleException;
368 };
369
374 {
375 friend class ModuleBase;
376
377 template <typename>
378 friend ModulePtrType MakeModule(const std::thread::id, ParamsBasePtrType&&);
379
380 public:
386
387 virtual ~ModuleParamsBase() = 0;
388
389 virtual const char* GetParamClassTag() const noexcept override { return "ModuleParamsBase"; }
390
391 private:
394
395 // Usage parameters may be used in the future also by modules.
396 bool ConfigureUsageTypeChild() const noexcept override final { return false; }
397
402 std::unique_ptr<ModuleDataBase> ModuleData;
403
404 DummyParam Dummy = { *this };
405 };
406
419
429 {
435 {
436 friend class ModuleBase;
437 friend int ModuleThreadMain(std::unique_ptr<RunnableInstance>&&, RunnableObject*);
438
444
445 void HandleEvent(ModuleInstance& Instance) { Parent.HandleEvent(Instance); } //<! @copydoc ModuleBase::HandleEvent
446 Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(ModuleInstance& Instance) { return Parent.ExecModuleMainLoop(Instance); } //<! @copydoc ModuleBase::ExecModuleMainLoop
447 void SetException(std::exception_ptr Exception) noexcept { Parent.SetException(Exception); }
448 void OnPause(ModuleInstance& Instance) { Parent.OnPause(Instance); } //<! @copydoc ModuleBase::OnPause
449 void OnResume(ModuleInstance& Instance) { Parent.OnResume(Instance); } //<! @copydoc ModuleBase::OnResume
450 void OnError(ModuleInstance& Instance) { Parent.OnError(Instance); } //<! @copydoc ModuleBase::OnError
451
452 void SetReasonWhyPaused(std::string Description) { Parent.ModuleSetReasonWhyPaused(std::move(Description)); } //<! @copydoc ModuleBase::ModuleSetReasonWhyPaused
453
455 };
456
462 {
463 friend class ModuleBase;
464
465 template <typename...>
467
473
474 void AddRegisteredEvent(EventListenersBase& EventListeners) const { Parent.AddRegisteredEvent(EventListeners); }
475 void RemoveRegisteredEvent(EventListenersBase& EventListeners) const { Parent.RemoveRegisteredEvent(EventListeners); }
476
478 };
479
480 public:
483
489
495
501
506 constexpr static auto Category() noexcept { return ""; }
507
513 ModuleBase(const std::thread::id OwnerThreadID, ParamsBasePtrType&& Params);
514
515 virtual ~ModuleBase() = 0;
516
517 virtual std::string GetCategory() const override { return Category(); }
518
523
528 virtual bool HasUI() const noexcept { return false; }
529
536 virtual bool TreatModuleExceptionsAsWarnings() const { return true; }
537
544 virtual std::chrono::milliseconds GetMainLoopDelay() const { return std::chrono::milliseconds(10); }
546
551 static constexpr auto GetModuleDataTimeoutDefault = std::chrono::milliseconds(1000);
552
555
560
566
573
583 ModuleDataTypeSyncPtrType GetModuleData(const std::chrono::milliseconds Timeout = GetModuleDataTimeoutDefault);
584
591 ModuleDataTypeSyncPtrConstType GetModuleData(const std::chrono::milliseconds Timeout = GetModuleDataTimeoutDefault) const;
592
596 void EnqueueEvent(ModuleDataBase::EventPtrType&& Event) const;
597
616 template <typename ReceiverType, typename EventType, typename... ArgsTs>
617 void MakeAndEnqueueEvent(ReceiverType* Receiver, EventType EventFuncPtr, ArgsTs&& ...Args) const;
619
625 ModuleDataTypeSyncPtrType (ModuleBase::*)(const std::chrono::milliseconds)>;
626
627 private:
632
638 ModuleDataTypeSyncPtrType GetNonConstModuleData(const std::chrono::milliseconds Timeout = GetModuleDataTimeoutDefault) const;
640
641 protected:
648 static auto GetExceptionUnsafe(const ModuleDataTypeSyncPtrConstType& ModuleDataPtr) { return ModuleDataPtr->GetException(); }
649
650 private:
655
659 void HandleEvent(ModuleInstance& Instance);
660
666 void AddRegisteredEvent(EventListenersBase& EventListeners);
667
673 void RemoveRegisteredEvent(EventListenersBase& EventListeners);
674
680
687 void SetException(std::exception_ptr Exception) noexcept;
688
695 void OnPause(ModuleInstance& Instance);
696
703 void OnResume(ModuleInstance& Instance);
704
710 void OnError(ModuleInstance& Instance);
712
717 virtual void OnPauseChild(ModuleInstance& Instance) const {}
718 virtual void OnResumeChild(ModuleInstance& Instance) const {}
719 virtual void OnErrorChild(ModuleInstance& Instance) const {}
720
723
732
733 void ResetImpl(dispatch_tag<RunnableObject>) override final;
735
740 void ModuleSetReasonWhyPaused(std::string Description) { SetReasonWhyPaused(std::move(Description)); }
741
746 void RunChild() override final;
747 void NotifyChild() override final;
748 void TerminateChild(const std::chrono::milliseconds Timeout) override final;
749 std::unique_ptr<BusyDialog> MakeStartupBusyDialogChild(QWidget* ParentWidget) const override final;
751
752 std::exception_ptr GetExceptionChild([[maybe_unused]] const std::chrono::milliseconds Timeout) const override final;
753 bool IsReadyChild() const override final;
754
759
765 virtual void OnInit(ModuleInstance* Instance) const {}
766
774 virtual void OnExit(ModuleInstance* Instance) const {}
775
783 void OnDeregisterEvents(ModuleInstance* Instance) const;
785
789 const std::unique_ptr<ModuleDataType> ModuleData;
790
798 std::vector<EventListenersBase*> RegisteredEvents;
799 };
800
810 template <typename ReceiverType, typename... ArgsTs>
811 auto MakeEvent(ReceiverType* Receiver,
812 typename DefaultEvent<ReceiverType, std::tuple<std::remove_reference_t<ArgsTs>...>>::EventFuncPtrType EventFuncPtr,
813 ArgsTs&& ...Args)
814 {
815 if (!EventFuncPtr)
816 throw Util::InvalidArgException("EventFuncPtr cannot be nullptr.");
817
818 // Use EventArgTs instead of std::tuple<ArgsTs...> since the latter would create a tuple of references!
819 using EventArgTs = Util::remove_first_from_tuple_t<Util::argument_of_t<decltype(EventFuncPtr)>>;
820
821 auto EventFunc = typename DefaultEvent<ReceiverType, EventArgTs>::EventFuncType(*Receiver, EventFuncPtr,
822 Util::argument_of_t<decltype(EventFuncPtr)>(nullptr, std::forward<ArgsTs>(Args)...));
823
824 return std::make_unique<DefaultEvent<ReceiverType, EventArgTs>>(EventFunc);
825 }
826
827 template <typename ReceiverType, typename EventType, typename... ArgsTs>
828 void ModuleBase::MakeAndEnqueueEvent(ReceiverType* Receiver, EventType EventFuncPtr, ArgsTs&& ...Args) const
829 {
830 if (Receiver != this)
831 throw Util::InvalidArgException("Receiver cannot point to a module different from the instance MakeAndEnqueueEvent() is called on.");
832
833 EnqueueEvent(MakeEvent(Receiver, EventFuncPtr, std::forward<ArgsTs>(Args)...));
834 }
835
841 {
842 public:
847 ModuleInstance(ModuleBase& Owner, std::promise<void>&& ThreadExitedPromise,
849
854
855 ~ModuleInstance() = default;
856
861 void Exit() noexcept { ShouldExit = true; }
862
868 bool IsExiting() const noexcept { return ShouldExit; }
869
874
875 private:
880 bool ShouldExit = false;
881 };
882
896 template <typename To, typename From, std::enable_if_t<
897 std::is_same_v<ModuleDataBase, std::remove_cv_t<From>>, int> = 0
898 >
900 {
901 if (!ModuleDataPtr)
902 throw Util::InvalidArgException("ModuleDataPtr must not be nullptr.");
903
905 std::conditional_t<std::is_const_v<From>, std::add_const_t<typename To::ModuleDataType>, typename To::ModuleDataType>
906 >(std::move(ModuleDataPtr));
907 }
908
914 {
915 protected:
918
919 public:
927 virtual void Deregister(const ModuleBase& Listener,
928 const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0)) = 0;
929
938 virtual void Deregister(const ModuleBase& Listener, ItemIDType CommunicatorID,
939 const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0)) = 0;
940 };
941
950 template <typename... EventFuncArgs>
952 {
958 {
963
970
976 inline bool operator==(const ListenersTypeKey& Other) const
977 {
978 return Module == Other.Module && CommunicatorID == Other.CommunicatorID;
979 }
980 };
981
987 {
993 inline size_t operator()(const ListenersTypeKey& v) const
994 {
995 size_t seed = std::hash<decltype(ListenersTypeKey::Module)>()(v.Module);
997
998 return seed;
999 }
1000 };
1001
1002 public:
1009 using EventFunctionType = std::function<void(ModuleInstance*, EventFuncArgs...)>;
1010
1012 virtual ~TypedEventListeners() = default;
1013
1030 template <typename CallableT>
1031 void Register(const ModuleBase& Listener, CallableT EventFunc, ItemIDType CommunicatorID = ItemIDNotSet,
1032 const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0))
1033 {
1034 auto lock = AcquireLock(Timeout);
1035 RegisterUnsafe(Listener, EventFunc, CommunicatorID);
1036 }
1037
1038 virtual void Deregister(const ModuleBase& Listener, ItemIDType CommunicatorID,
1039 const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0)) override
1040 {
1041 auto lock = AcquireLock(Timeout);
1042 DeregisterUnsafe(Listener, CommunicatorID);
1043 }
1044
1045 virtual void Deregister(const ModuleBase& Listener,
1046 const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0)) override
1047 {
1048 auto lock = AcquireLock(Timeout);
1049 DeregisterAllUnsafe(Listener);
1050 }
1051
1062 const std::chrono::milliseconds Timeout = DefaultTimeout) const
1063 {
1064 auto lock = AcquireLock(Timeout);
1065 return GetFuncUnsafe(Listener, CommunicatorID);
1066 }
1067
1068 private:
1079 template <typename CallableT>
1080 void RegisterUnsafe(const ModuleBase& Listener, CallableT EventFunc, ItemIDType CommunicatorID)
1081 {
1082 const auto NumListeners = Listeners.size();
1083 Listeners[ListenersTypeKey{ &Listener, CommunicatorID }] = [&Listener, EventFunc](ModuleInstance* Instance, EventFuncArgs... Args) {
1084 (dynamic_cast<std::add_const_t<typename Util::member_fn_ptr_traits<CallableT>::instance_type>&>(Listener).*EventFunc)(Instance, Args...);
1085 };
1086
1087 // New Listener has been added (not a pure update).
1088 if (Listeners.size() > NumListeners)
1089 Listener.EventListenersOnly.AddRegisteredEvent(*this);
1090 }
1091
1099 void DeregisterUnsafe(const ModuleBase& Listener, ItemIDType CommunicatorID)
1100 {
1101 auto ListenerIt = Listeners.find(ListenersTypeKey{ &Listener, CommunicatorID });
1102 if (ListenerIt == Listeners.cend())
1103 return;
1104
1105 Listeners.erase(ListenerIt);
1107 }
1108
1115 void DeregisterAllUnsafe(const ModuleBase& Listener)
1116 {
1117 const auto NumErased = std::erase_if(Listeners, [&Listener](const auto& v) { return v.first.Module == &Listener; });
1118
1119 for (std::remove_const_t<decltype(NumErased)> i = 0; i < NumErased; ++i)
1121 }
1122
1131 EventFunctionType GetFuncUnsafe(const ModuleBase& Listener, ItemIDType CommunicatorID) const
1132 {
1133 // First, find event function assigned to a module-communicator pair.
1134 auto ListenerIt = Listeners.find(ListenersTypeKey{ &Listener, CommunicatorID });
1135 if (ListenerIt != Listeners.cend())
1136 return ListenerIt->second;
1137
1138 // If none has been found, find event function assigned to a module, ignoring the communicator instance.
1139 ListenerIt = Listeners.find(ListenersTypeKey{ &Listener, ItemIDNotSet });
1140 return ListenerIt != Listeners.cend() ? ListenerIt->second : nullptr;
1141 }
1142
1147 std::unordered_map<const ListenersTypeKey, EventFunctionType, ListenersTypeKeyHasher> Listeners;
1148 };
1149
1154 {
1155 public:
1159 using InterModuleEventPtrType = std::unique_ptr<InterModuleEventBase>;
1160
1165
1173
1174 virtual ~InterModuleEventBase() = 0;
1175
1182
1183 virtual size_t GetID() const noexcept = 0;
1184
1189 virtual std::string GetName() const = 0;
1191
1195 auto GetCommunicatorID() const noexcept { return CommunicatorID; }
1196
1197 private:
1202 };
1203
1210 template <typename DerivedEvent, typename... EventFuncArgs>
1212 {
1213 public:
1219 using EventListenersType = TypedEventListeners<EventFuncArgs...>;
1220
1224 InterModuleEvent() = default;
1225
1231
1233
1238 static auto ID() { return EventID; }
1239
1246 static size_t Publish(InterModuleEventLibrary& Library);
1247
1252 static InterModuleEventPtrType Make() { return std::make_unique<DerivedEvent>(); }
1253
1254 virtual InterModuleEventPtrType Clone(ItemIDType CommunicatorID) const override final { return std::make_unique<DerivedEvent>(*static_cast<const DerivedEvent*>(this), CommunicatorID); }
1255 virtual size_t GetID() const noexcept override final { return ID(); }
1256 virtual std::string GetName() const override { return typeid(DerivedEvent).name(); }
1257
1262 template <typename CallableT>
1263 static void Register(const ModuleBase& Listener, CallableT EventFunc, ItemIDType CommunicatorID = ItemIDNotSet)
1264 {
1265 Listeners.Register(Listener, EventFunc, CommunicatorID);
1266 }
1267
1272 static void Deregister(const ModuleBase& Listener)
1273 {
1274 Listeners.Deregister(Listener);
1275 }
1276
1281 static void Deregister(const ModuleBase& Listener, ItemIDType CommunicatorID)
1282 {
1284 }
1285
1286 private:
1287 virtual void InvokeChild(ModuleInstance& Instance) const override final
1288 {
1289 auto EventFunc = Listeners.GetFunc(static_cast<const ModuleBase&>(Instance.GetOwner()), GetCommunicatorID());
1290
1291 if (EventFunc)
1292 InvokeWithParamsChild(Instance, EventFunc);
1293 }
1294
1299
1308
1312 static const size_t EventID;
1313
1319 };
1320
1325 {
1326 public:
1332
1337 static InterModuleEventLibrary& Get();
1338
1344 void Register(size_t ID, EventFactoryFuncPtrType EventFactoryFuncPtr) { Events.try_emplace(ID, std::move(EventFactoryFuncPtr)); }
1345
1350 auto& GetEvents() const noexcept { return Events; }
1351
1352 private:
1357
1362 std::map<size_t, EventFactoryFuncPtrType> Events;
1363 };
1364
1365 template <typename DerivedEvent, typename ...EventFuncArgs>
1367 {
1368 auto ID = Util::UniqueID::Get<DerivedEvent>();
1369
1370 Library.Register(ID, &Make);
1371
1372 return ID;
1373 }
1374
1380 template <typename DerivedEvent, typename... EventFuncArgs>
1381 const size_t InterModuleEvent<DerivedEvent, EventFuncArgs...>::EventID = InterModuleEvent<DerivedEvent, EventFuncArgs...>::Publish(InterModuleEventLibrary::Get());
1382
1387 template <typename DerivedEvent, typename... EventFuncArgs>
1388 typename InterModuleEvent<DerivedEvent, EventFuncArgs...>::EventListenersType InterModuleEvent<DerivedEvent, EventFuncArgs...>::Listeners;
1389
1395 class QModuleWidget : public QWidget
1396 {
1397 Q_OBJECT
1398
1399 friend class QModuleBase;
1400
1401 public:
1406 constexpr static Qt::WindowFlags GetQtWindowFlagsResizable();
1407
1412 constexpr static Qt::WindowFlags GetQtWindowFlagsNonResizable();
1413
1420 QModuleWidget(QModuleBase& Owner, QWidget* Parent = nullptr);
1421
1422 ~QModuleWidget() = default;
1423
1428 const auto& GetOwner() const noexcept { return Owner; }
1429
1434
1438 virtual bool AllowResize() const noexcept { return false; }
1439
1445 virtual bool AllowDocked() const noexcept { return true; }
1447
1453 Qt::WindowFlags GetQtWindowFlags() const noexcept;
1454
1461 std::string GetDataSaveDirectory() const;
1462
1469 void SetDataSaveDirectory(std::string_view Directory) const;
1470
1471 private:
1476 void EnableDockWindowShortcut(bool Enable) noexcept;
1477
1484 virtual void closeEvent(QCloseEvent* Event) override;
1485
1488
1491
1492 private slots:
1493 void OnDockWindow();
1494 void OnFocusWindow();
1495 void OnFocusMainWindow();
1496 };
1497
1502 class QModuleDockWidget : public QDockWidget
1503 {
1504 Q_OBJECT
1505
1506 public:
1515 QModuleDockWidget(QModuleBase& Owner, QWidget* Parent, Qt::WindowFlags Flags);
1516
1518
1519 private:
1526 virtual void closeEvent(QCloseEvent* Event) override;
1527
1535 virtual void keyPressEvent(QKeyEvent* Event) override;
1536
1538 };
1539
1544 {
1545 public:
1546 QModuleDataBase() = default;
1547 virtual ~QModuleDataBase() = default;
1548
1549 private:
1550 void ResetImpl(dispatch_tag<ModuleDataBase>) override final;
1552 };
1553
1558 {
1559 public:
1563 enum WindowStateType { Normal, Minimized, Maximized };
1580 enum WindowDockingStateType { Docked, Undocked };
1596 WindowStyleParamsExtension(ParamsBase& Owner, const std::string& Prefix = "")
1597 : WindowPosX{ Owner, Prefix + "WindowPosX" },
1598 WindowPosY{ Owner, Prefix + "WindowPosY" },
1599 WindowWidth{ Owner, Prefix + "WindowWidth" },
1600 WindowHeight{ Owner, Prefix + "WindowHeight" },
1601 WindowState{ Owner, Prefix + "WindowState", WindowStateType::Normal },
1602 WindowDockingState{ Owner, Prefix + "WindowDockingState", WindowDockingStateType::Docked }
1603 {}
1604
1610 void ApplyTo(QWidget& Widget, bool Show = true) const;
1611
1616 void FromWidget(const QWidget& Widget);
1617
1624 };
1625
1630 {
1631 public:
1637 : ModuleParamsBase(ID, Core), WindowStyleParams(*this) {}
1638
1639 virtual ~QModuleParamsBase() = 0;
1640
1641 virtual const char* GetParamClassTag() const noexcept override { return "QModuleParamsBase"; }
1642
1644
1645 private:
1648 };
1649
1654 {
1655 public:
1658
1660 virtual ~QModuleConfiguratorBase() = 0;
1661 };
1662
1668 {
1669 public:
1673
1678 QModuleBase(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params);
1679
1680 virtual ~QModuleBase() = 0;
1681
1682 bool HasUI() const noexcept override final { return true; }
1683
1689
1698 QAction& InitUI(DynExpManager& DynExpMgr, QMdiArea* const MdiArea);
1699
1700 void HideUI();
1701 virtual void DisableUI();
1702 virtual void UpdateUI();
1703
1711 void UpdateModuleWindowFocusAction();
1712
1713 void DockWindow() noexcept;
1714 void UndockWindow() noexcept;
1715 void DockUndockWindow() noexcept;
1716 void SetFocus() noexcept;
1717 void FocusMainWindow() noexcept;
1718
1724 void SendKeyPressEventToMainWindow(QKeyEvent* Event) noexcept;
1725
1732 bool IsWindowDocked() noexcept;
1733
1741 bool IsActiveWindow();
1743
1744 protected:
1767 template <typename SenderType, typename SignalType, typename ReceiverType, typename EventType>
1768 void Connect(SenderType* Sender, SignalType Signal, ReceiverType* Receiver, EventType Event);
1769
1777 template <typename WidgetType = QModuleWidget>
1778 WidgetType* GetWidget() const;
1779
1780 private:
1781 virtual void RestoreWindowStatesFromParamsChild() override;
1782 virtual void UpdateParamsFromWindowStatesChild() override;
1783
1790 void SetWidgetProperties(QWidget* const WindowWidget) const;
1791
1792 void ResetImpl(dispatch_tag<ModuleBase>) override final;
1793 virtual void ResetImpl(dispatch_tag<QModuleBase>) = 0;
1794
1799
1805 virtual std::unique_ptr<QModuleWidget> MakeUIWidget() = 0;
1806
1813 virtual void UpdateUIChild(const ModuleBase::ModuleDataGetterType& ModuleDataGetter) {}
1815
1817 std::unique_ptr<QMdiSubWindow> MdiSubWindow;
1818 std::unique_ptr<QModuleDockWidget> DockWidget;
1819 std::unique_ptr<QAction> ModuleWindowFocusAction;
1820
1821 QMdiArea* MdiArea;
1822 };
1823
1824 template <typename SenderType, typename SignalType, typename ReceiverType, typename EventType>
1825 void QModuleBase::Connect(SenderType* Sender, SignalType Signal, ReceiverType* Receiver, EventType Event)
1826 {
1827 EnsureCallFromOwningThread();
1828
1829 if (!Sender || !Receiver)
1830 throw Util::InvalidArgException("Sender and Receiver cannot be nullptr.");
1831
1832 // Arguments must not be passed by reference or by pointer to Event since Event is invoked later when
1833 // references/pointers might not be valid anymore.
1834 auto Connection = QObject::connect(Sender, Signal, [this, Receiver, Event](auto... Args) {
1835 try
1836 {
1837 MakeAndEnqueueEvent(Receiver, Event, std::move(Args)...);
1838 }
1839 catch (const Util::Exception& e)
1840 {
1841 Util::EventLog().Log("Posting an event from a module's UI to the module's thread, the error listed below occurred.", Util::ErrorType::Error);
1842 Util::EventLog().Log(e);
1843 }
1844 catch (const std::exception& e)
1845 {
1846 Util::EventLog().Log("Posting an event from a module's UI to the module's thread, the error listed below occurred.", Util::ErrorType::Error);
1847 Util::EventLog().Log(e.what());
1848 }
1849 catch (...)
1850 {
1851 Util::EventLog().Log("Posting an event from a module's UI to the module's thread, an unknown error occurred.", Util::ErrorType::Error);
1852 }
1853 });
1854
1855 if (!Connection)
1856 throw Util::InvalidArgException("QObject::connect() cannot establish a connection for the given sender and signal types.");
1857 }
1858
1859 template <typename WidgetType>
1860 WidgetType* QModuleBase::GetWidget() const
1861 {
1862 // EnsureCallFromOwningThread(); considered here, but it also prohibits legitimate calls
1863 // to thread-safe (probably const) member functions of the widget.
1864
1865 if (!Widget)
1866 throw Util::InvalidStateException("UI widget has not been created yet.");
1867
1868 // Throws if it fails.
1869 return &dynamic_cast<WidgetType&>(*Widget);
1870 }
1871
1873 {
1874 public:
1881 QMLModuleWidget(QAnyStringView SourceUri, QAnyStringView SourceTypeName, QMLModuleBase& Owner, QWidget* Parent = nullptr);
1882
1883 ~QMLModuleWidget() = default;
1884
1889 QObject* GetRootObject() const noexcept;
1890
1895 QObject* GetBackend() const noexcept;
1896
1897 bool AllowResize() const noexcept override { return true; }
1898
1899 private:
1900 QQuickView* QuickView;
1902 mutable QObject* Backend = nullptr;
1903 };
1904
1909 {
1910 public:
1912 virtual ~QMLModuleDataBase() = default;
1913
1914 private:
1915 void ResetImpl(dispatch_tag<QModuleDataBase>) override final;
1917 };
1918
1923 {
1924 public:
1930 : QModuleParamsBase(ID, Core) {}
1931
1932 virtual ~QMLModuleParamsBase() = 0;
1933
1934 virtual const char* GetParamClassTag() const noexcept override { return "QMLModuleParamsBase"; }
1935
1936 private:
1939
1940 DummyParam Dummy = { *this };
1941 };
1942
1955
1961 {
1962 public:
1966
1971 QMLModuleBase(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params);
1972
1973 virtual ~QMLModuleBase() = 0;
1974
1975 void DisableUI() override;
1976 void UpdateUI() override;
1977
1978 protected:
1988 template <typename BackendType>
1989 BackendType* GetBackend() const;
1990
1991 private:
1992 void ResetImpl(dispatch_tag<QModuleBase>) override final;
1994
1995 std::unique_ptr<QModuleWidget> MakeUIWidget() override final;
1996
2001
2005 virtual void MakeConnections(QObject* Backend) {}
2006
2012 virtual QAnyStringView GetModuleSourceUri() const noexcept = 0;
2013
2019 virtual QAnyStringView GetModuleSourceTypeName() const noexcept = 0;
2021 };
2022
2023 template <typename BackendType>
2024 BackendType* QMLModuleBase::GetBackend() const
2025 {
2026 EnsureCallFromOwningThread();
2027
2028 auto Backend = GetWidget<QMLModuleWidget>()->GetBackend();
2029 if (!Backend)
2030 throw Util::InvalidStateException("QML module's UI backend has not been set.");
2031
2032 return &dynamic_cast<BackendType&>(*Backend);
2033 }
2034}
2035
2040namespace DynExpModule {};
Implementation of DynExp objects as the base for derived resources and implementation of the object p...
Implements DynExp's main window as a Qt-based user interface (UI).
Describes an event which consists of a receiver's member function and a set of arguments to call this...
Definition Module.h:98
decltype(DefaultEvent< ReceiverType, ArgTupleType >::MakeEventFuncTraits(std::declval< ArgTupleIndexSequenceType >())) InstantiatedEventFuncTraitsType
Type of the instantiated EventFuncTraits - not actually instantiating it.
Definition Module.h:138
DefaultEvent(EventFuncType EventFunc) noexcept
Constructs a DefaultEvent instance.
Definition Module.h:148
virtual ~DefaultEvent()
Definition Module.h:150
decltype(std::make_index_sequence< std::tuple_size_v< ArgTupleType > >()) ArgTupleIndexSequenceType
Index sequence for the (pseudo-)instantiation of EventFuncTraits.
Definition Module.h:133
virtual void InvokeChild(ModuleInstance &Instance) const override
Invokes the event passing the receiving module's instance reference to it. Only to be called from Mod...
Definition Module.h:153
const EventFuncType EventFunc
Util::CallableMemberWrapper to store the event receiver, the event function, and its arguments.
Definition Module.h:158
static constexpr auto MakeEventFuncTraits(std::index_sequence< Indices... >)
Instantiates EventFuncTraits. This function is not meant to be called. It is used for type deduction ...
Definition Module.h:128
typename InstantiatedEventFuncTraitsType::EventFuncPtrType EventFuncPtrType
Signature of an event function. Pointer to ModuleInstance to be passed as parameter instead of refere...
Definition Module.h:141
typename InstantiatedEventFuncTraitsType::EventFuncType EventFuncType
Type of a Util::CallableMemberWrapper to store the event.
Definition Module.h:142
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
Definition DynExpCore.h:127
Common base class for all events to store them in a FIFO queue to be invoked later.
Definition Module.h:69
EventBase()=default
virtual ~EventBase()=0
Definition Module.cpp:150
void Invoke(ModuleInstance &Instance) const
Invokes the event passing the receiving module's instance reference to it. Only to be called from Mod...
Definition Module.h:79
virtual void InvokeChild(ModuleInstance &Instance) const =0
Invokes the event passing the receiving module's instance reference to it. Only to be called from Mod...
Common base class for all managers of event listeners of type TypedEventListeners....
Definition Module.h:914
virtual void Deregister(const ModuleBase &Listener, ItemIDType CommunicatorID, const std::chrono::milliseconds Timeout=std::chrono::milliseconds(0))=0
Deregisters/unsubscribes module Listener from the event, removing a single registration for a particu...
virtual ~EventListenersBase()
Definition Module.h:917
virtual void Deregister(const ModuleBase &Listener, const std::chrono::milliseconds Timeout=std::chrono::milliseconds(0))=0
Deregisters/unsubscribes module Listener from the event, regardless of the inter-module communicator ...
Common base class for all inter-module events.
Definition Module.h:1154
virtual std::string GetName() const =0
Returns the name of this event type.
virtual InterModuleEventPtrType Clone(ItemIDType CommunicatorID) const =0
Creates a deep copy of this inter-module instance.
const ItemIDType CommunicatorID
ID of the DynExpInstr::InterModuleCommunicator instance that sends the event.
Definition Module.h:1201
InterModuleEventBase(const InterModuleEventBase &Other, ItemIDType CommunicatorID)
Copy-constrcuts an inter-module event setting the CommunicatorID.
Definition Module.h:1171
virtual size_t GetID() const noexcept=0
Returns the unique ID of this event type.
std::unique_ptr< InterModuleEventBase > InterModuleEventPtrType
Pointer type to store an inter-module event (InterModuleEventBase).
Definition Module.h:1159
auto GetCommunicatorID() const noexcept
Getter for CommunicatorID.
Definition Module.h:1195
InterModuleEventBase()
Constructs an inter-module event.
Definition Module.h:1164
virtual ~InterModuleEventBase()=0
Definition Module.cpp:428
Library type that holds factory functions to all available inter-module events.
Definition Module.h:1325
std::map< size_t, EventFactoryFuncPtrType > Events
Maps the unique ID of inter-module events derived from InterModuleEventBase to their respective facto...
Definition Module.h:1362
InterModuleEventLibrary()=default
Constructs an instance of InterModuleEventLibrary. Private to make singleton class.
static InterModuleEventLibrary & Get()
Getter for the singleton instance of InterModuleEventLibrary.
Definition Module.cpp:432
std::function< InterModuleEventBase::InterModuleEventPtrType(void)> EventFactoryFuncPtrType
Type of a function pointer pointing to a factory function to create an instance of an inter-module ev...
Definition Module.h:1331
void Register(size_t ID, EventFactoryFuncPtrType EventFactoryFuncPtr)
Adds an inter-module event derived from InterModuleEventBase to this library.
Definition Module.h:1344
auto & GetEvents() const noexcept
Getter for Events.
Definition Module.h:1350
Typed base class for inter-module events to realize CRTP.
Definition Module.h:1212
static void Register(const ModuleBase &Listener, CallableT EventFunc, ItemIDType CommunicatorID=ItemIDNotSet)
Registers/Subscribes module Listener to the event with the event function EventFunc....
Definition Module.h:1263
static const size_t EventID
Unique ID assigned to this inter-module event.
Definition Module.h:1312
static size_t Publish(InterModuleEventLibrary &Library)
Publishes this event type to the InterModuleEventLibrary. This function should not be called manually...
Definition Module.h:1366
InterModuleEvent()=default
Constructs an inter-module event.
virtual void InvokeWithParamsChild(ModuleInstance &Instance, EventListenersType::EventFunctionType EventFunc) const =0
Called by InvokeChild(). Override to call EventFunc with Instance as the first argument and with furt...
virtual size_t GetID() const noexcept override final
Returns the unique ID of this event type.
Definition Module.h:1255
virtual ~InterModuleEvent()
Definition Module.h:1232
virtual void InvokeChild(ModuleInstance &Instance) const override final
Invokes the event passing the receiving module's instance reference to it. Only to be called from Mod...
Definition Module.h:1287
static InterModuleEventPtrType Make()
Factory function for events of type DerivedEvent.
Definition Module.h:1252
virtual InterModuleEventPtrType Clone(ItemIDType CommunicatorID) const override final
Creates a deep copy of this inter-module instance.
Definition Module.h:1254
static void Deregister(const ModuleBase &Listener, ItemIDType CommunicatorID)
Deregisters/unsubscribes module Listener from the event, removing a single registration for a particu...
Definition Module.h:1281
InterModuleEvent(const InterModuleEventBase &Other, ItemIDType CommunicatorID)
Copy-constrcuts an inter-module event setting the CommunicatorID.
Definition Module.h:1229
static auto ID()
Getter for EventID.
Definition Module.h:1238
static void Deregister(const ModuleBase &Listener)
Deregisters/unsubscribes module Listener from the event, regardless of the inter-module communicator ...
Definition Module.h:1272
static EventListenersType Listeners
Holds one EventListenersType instance per derived event, which manages all the subscribers of Derived...
Definition Module.h:1318
virtual std::string GetName() const override
Returns the name of this event type.
Definition Module.h:1256
Allow exclusive access to some of ModuleBase's private methods to any TypedEventListeners class.
Definition Module.h:462
ModuleBase & Parent
Owning ModuleBase instance.
Definition Module.h:477
constexpr EventListenersOnlyType(ModuleBase &Parent) noexcept
Construcs an instance - one for each ModuleBase instance.
Definition Module.h:472
void AddRegisteredEvent(EventListenersBase &EventListeners) const
Adds a manager of event listeners to RegisteredEvents. Called indirectly by TypedEventListeners::Regi...
Definition Module.h:474
void RemoveRegisteredEvent(EventListenersBase &EventListeners) const
Removes a manager of event listeners from RegisteredEvents if it was added before....
Definition Module.h:475
Allow exclusive access to some of ModuleBase's private methods to the module thread ModuleThreadMain(...
Definition Module.h:435
void OnPause(ModuleInstance &Instance)
Definition Module.h:448
ModuleBase & Parent
Owning ModuleBase instance.
Definition Module.h:454
void SetException(std::exception_ptr Exception) noexcept
Sets this module instance to an error state and tries to store the exception responsible for the erro...
Definition Module.h:447
Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(ModuleInstance &Instance)
Definition Module.h:446
void OnError(ModuleInstance &Instance)
Definition Module.h:450
constexpr ModuleThreadOnlyType(ModuleBase &Parent) noexcept
Construcs an instance - one for each ModuleBase instance.
Definition Module.h:443
void SetReasonWhyPaused(std::string Description)
Definition Module.h:452
friend int ModuleThreadMain(std::unique_ptr< RunnableInstance > &&, RunnableObject *)
Modules run in their own thread. This is the module thread's main function.
Definition Module.cpp:10
void HandleEvent(ModuleInstance &Instance)
Definition Module.h:445
void OnResume(ModuleInstance &Instance)
Definition Module.h:449
Base class for modules. Modules implement programs on their own (e.g. measurement protocols or server...
Definition Module.h:429
void TerminateChild(const std::chrono::milliseconds Timeout) override final
Signals derived classes that terminating the RunnableObject instance's thread is about to be requeste...
Definition Module.cpp:360
ModuleDataTypeSyncPtrType GetModuleData(const std::chrono::milliseconds Timeout=GetModuleDataTimeoutDefault)
Locks the mutex of the module data class instance ModuleData assigned to this ModuleBase instance and...
Definition Module.cpp:219
virtual void OnErrorChild(ModuleInstance &Instance) const
This handler gets called just before the module thread terminates due to an exception....
Definition Module.h:719
void OnPause(ModuleInstance &Instance)
This handler gets called just after the module pauses due to e.g. an error in an instrument the modul...
Definition Module.cpp:298
void NotifyChild() override final
Notify derived classes that some state has changed (e.g. the termination of Thread is requested) and ...
Definition Module.cpp:355
void RunChild() override final
Refer to Run().
Definition Module.cpp:344
void ModuleSetReasonWhyPaused(std::string Description)
Sets the reason why this ModuleBase instance has been paused.
Definition Module.h:740
void OnDeregisterEvents(ModuleInstance *Instance) const
This event is triggered after the OnExit event. It calls EventListenersBase::Deregister() for all man...
Definition Module.cpp:406
static auto GetExceptionUnsafe(const ModuleDataTypeSyncPtrConstType &ModuleDataPtr)
Getter for ModuleDataBase::ModuleException assuming that the module data has already been locked.
Definition Module.h:648
virtual void ResetImpl(dispatch_tag< ModuleBase >)=0
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual void OnInit(ModuleInstance *Instance) const
This event is triggered right before the module thread starts. Override it to lock instruments this m...
Definition Module.h:765
const std::unique_ptr< ModuleDataType > ModuleData
Module data belonging to this ModuleBase instance.
Definition Module.h:789
virtual ~ModuleBase()=0
Definition Module.cpp:215
void ResetImpl(dispatch_tag< RunnableObject >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
Definition Module.cpp:336
virtual void OnResumeChild(ModuleInstance &Instance) const
This handler gets called just after the module resumed from a paused state. Override OnResumeChild() ...
Definition Module.h:718
void SetException(std::exception_ptr Exception) noexcept
Sets this module instance to an error state and tries to store the exception responsible for the erro...
Definition Module.cpp:284
void UpdateParamsFromWindowStates()
UpdateParamsFromWindowStates() only calls UpdateParamsFromWindowStatesChild(). Override UpdateParamsF...
Definition Module.h:572
void MakeAndEnqueueEvent(ReceiverType *Receiver, EventType EventFuncPtr, ArgsTs &&...Args) const
Calls MakeEvent() to construct a new event and subsequently enqueues the event into the module's even...
Definition Module.h:828
virtual std::string GetCategory() const override
Returns the category of this Object type.
Definition Module.h:517
virtual void OnExit(ModuleInstance *Instance) const
This event is triggered right before the module thread terminates (not due to an exception,...
Definition Module.h:774
void EnqueueEvent(ModuleDataBase::EventPtrType &&Event) const
Enqueues Event at the module event queue's back. Takes ownership of the event. Notifies the module ow...
Definition Module.cpp:229
void RemoveRegisteredEvent(EventListenersBase &EventListeners)
Removes a manager of event listeners from RegisteredEvents if it was added before....
Definition Module.cpp:266
void HandleEvent(ModuleInstance &Instance)
Executes and removes the next pending event from the module's event queue.
Definition Module.cpp:239
virtual void RestoreWindowStatesFromParamsChild()
RestoreWindowStatesFromParams() only calls RestoreWindowStatesFromParamsChild(). Override RestoreWind...
Definition Module.h:721
Util::SynchronizedPointer< const ModuleDataType > ModuleDataTypeSyncPtrConstType
Alias for the return type of ModuleBase::GetModuleData() const. Data class instances wrapped into Uti...
Definition Module.h:500
void OnResume(ModuleInstance &Instance)
This handler gets called just after the module resumed from a paused state. Override OnResumeChild() ...
Definition Module.cpp:305
ModuleThreadOnlyType ModuleThreadOnly
Allow exclusive access to some of ModuleBase's private methods to the module thread ModuleThreadMain(...
Definition Module.h:553
Util::SynchronizedPointer< ModuleDataType > ModuleDataTypeSyncPtrType
Alias for the return type of ModuleBase::GetModuleData(). Data class instances wrapped into Util::Syn...
Definition Module.h:494
EventListenersOnlyType EventListenersOnly
Allow exclusive access to some of ModuleBase's private methods to any TypedEventListeners class.
Definition Module.h:554
std::unique_ptr< BusyDialog > MakeStartupBusyDialogChild(QWidget *ParentWidget) const override final
Override to make this function return a pointer to a BusyDialog instance. Refer to Run().
Definition Module.cpp:377
std::vector< EventListenersBase * > RegisteredEvents
Holds a list of pointers to managers of event listeners of the events this module has registered/subs...
Definition Module.h:798
void OnError(ModuleInstance &Instance)
This handler gets called just before the module thread terminates due to an exception....
Definition Module.cpp:312
static constexpr auto Category() noexcept
Every derived class has to redefine this function.
Definition Module.h:506
virtual Util::DynExpErrorCodes::DynExpErrorCodes ModuleMainLoop(ModuleInstance &Instance)=0
Module main loop. The function is executed periodically by the module thread. Also refer to GetMainLo...
void AddRegisteredEvent(EventListenersBase &EventListeners)
Adds a manager of event listeners to RegisteredEvents. Called indirectly by TypedEventListeners::Regi...
Definition Module.cpp:259
virtual void UpdateParamsFromWindowStatesChild()
UpdateParamsFromWindowStates() only calls UpdateParamsFromWindowStatesChild(). Override UpdateParamsF...
Definition Module.h:722
static constexpr auto GetModuleDataTimeoutDefault
Determines the default timeout for GetModuleData() to lock the mutex synchronizing the module's data ...
Definition Module.h:551
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.
Definition Module.cpp:385
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
Definition Module.cpp:395
virtual void OnPauseChild(ModuleInstance &Instance) const
This handler gets called just after the module pauses due to e.g. an error in an instrument the modul...
Definition Module.h:717
ModuleDataTypeSyncPtrType GetNonConstModuleData(const std::chrono::milliseconds Timeout=GetModuleDataTimeoutDefault) const
Always allows ModuleBase to obtain a non-const pointer to the module's data - even in const event fun...
Definition Module.cpp:234
virtual bool TreatModuleExceptionsAsWarnings() const
Determines whether this module should be terminated if an exception leaves the module's main loop or ...
Definition Module.h:536
void RestoreWindowStatesFromParams()
RestoreWindowStatesFromParams() only calls RestoreWindowStatesFromParamsChild(). Override RestoreWind...
Definition Module.h:565
virtual std::chrono::milliseconds GetMainLoopDelay() const
Specifies in which time intervals the module's event queue runs to handle pending events.
Definition Module.h:544
Util::DynExpErrorCodes::DynExpErrorCodes ExecModuleMainLoop(ModuleInstance &Instance)
Runs ModuleMainLoop().
Definition Module.cpp:277
virtual bool HasUI() const noexcept
Determines whether this module possesses a user interface (UI) which is shown in a window dedicated t...
Definition Module.h:528
Configurator class for ModuleBase.
Definition Module.h:411
virtual ~ModuleConfiguratorBase()=0
Definition Module.cpp:202
Allow exclusive access to some of ModuleDataBase's private methods to ModuleBase.
Definition Module.h:199
auto & GetNewEventNotifier() noexcept
Getter for NewEventNotifier.
Definition Module.h:213
ModuleDataBase & Parent
Owning ModuleDataBase instance.
Definition Module.h:215
void IndicateException() noexcept
Indicates to the main thread that an exception has happened in the module thread. Only performs atomi...
Definition Module.h:210
void Reset()
Resets the ModuleDataBase's instance and calls ResetImpl(dispatch_tag<ModuleDataBase>) subsequently.
Definition Module.h:209
constexpr ModuleBaseOnlyType(ModuleDataBase &Parent) noexcept
Construcs an instance - one for each ModuleDataBase instance.
Definition Module.h:207
void SetException(std::exception_ptr Exception) noexcept
Setter for ModuleException.
Definition Module.h:211
Allow exclusive access to some of ModuleDataBase's private methods to the module thread ModuleThreadM...
Definition Module.h:223
auto & GetNewEventNotifier() noexcept
Getter for NewEventNotifier.
Definition Module.h:233
ModuleDataBase & Parent
Owning ModuleDataBase instance.
Definition Module.h:235
constexpr ModuleThreadOnlyType(ModuleDataBase &Parent) noexcept
Construcs an instance - one for each ModuleDataBase instance.
Definition Module.h:231
friend int ModuleThreadMain(std::unique_ptr< RunnableInstance > &&, RunnableObject *)
Modules run in their own thread. This is the module thread's main function.
Definition Module.cpp:10
Data structure to contain data which is synchronized in between different threads....
Definition Module.h:174
ModuleThreadOnlyType ModuleThreadOnly
Allow exclusive access to some of ModuleDataBase's private methods to the module thread ModuleThreadM...
Definition Module.h:303
virtual ~ModuleDataBase()
Definition Module.h:240
const auto & GetEventFront() const noexcept
Returns a pointer to the event in the front of the module's event queue without transferring ownershi...
Definition Module.h:268
std::exception_ptr ModuleException
Used to transfer exceptions from the module thread to the main (user interface) thread....
Definition Module.h:367
Util::OneToOneNotifier NewEventNotifier
Notifies the thread of the module which owns the respective ModuleDataBase's instance when an event h...
Definition Module.h:353
std::queue< EventPtrType > EventQueueType
A module's event queue is a FIFO queue owning the enqueued events.
Definition Module.h:184
std::unique_ptr< EventBase > EventPtrType
Pointer owning an event.
Definition Module.h:179
void IndicateException() noexcept
Indicates to the main thread that an exception has happened in the module thread. Only performs atomi...
Definition Module.h:335
void SetException(std::exception_ptr Exception) noexcept
Setter for ModuleException.
Definition Module.cpp:191
void RunQueue()
Wakes up a module waiting for events and forces it to run its main loop once.
Definition Module.h:285
std::exception_ptr GetException() const noexcept
Getter for ModuleDataBase::ModuleException. If ModuleDataBase::ModuleException is nullptr and ModuleD...
Definition Module.cpp:174
Util::OneToOneNotifier & GetNewEventNotifier() noexcept
Getter for NewEventNotifier.
Definition Module.h:310
bool IsExceptionIndicated() const noexcept
Getter for HasException. Only performs atomic operations. Hence, this module data instance does not n...
Definition Module.h:292
void Reset()
Resets the ModuleDataBase's instance and calls ResetImpl(dispatch_tag<ModuleDataBase>) subsequently.
Definition Module.cpp:182
auto & GetEventFront() noexcept
Returns a pointer to the event in the front of the module's event queue without transferring ownershi...
Definition Module.h:274
size_t GetNumEnqueuedEvents() const noexcept
Getter for the module event queue's length.
Definition Module.h:280
void EnqueueEvent(EventPtrType &&Event)
Enqueues Event at the module event queue's back. Takes ownership of the event. Notifies the module ow...
Definition Module.cpp:154
EventQueueType EventQueue
FIFO event queue of the module which owns the respective ModuleDataBase's instance.
Definition Module.h:346
std::atomic< bool > HasException
If set to true, indicates to the main (user interface) thread that an exception has happened in the m...
Definition Module.h:360
virtual void ResetImpl(dispatch_tag< ModuleDataBase >)
Refer to DynExp::ModuleDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of ...
Definition Module.h:327
EventPtrType PopEvent()
Removes one event from the event queue's front and returns the event. Ownership of the event is trans...
Definition Module.cpp:163
ModuleBaseOnlyType ModuleBaseOnly
Allow exclusive access to some of ModuleDataBase's private methods to ModuleBase.
Definition Module.h:302
Refer to ParamsBase::dispatch_tag.
Definition Module.h:192
Defines data for a thread belonging to a ModuleBase instance. Refer to RunnableInstance.
Definition Module.h:841
void Exit() noexcept
Might be called from anywhere where this ModuleInstance instance is accessible to make the associated...
Definition Module.h:861
const ModuleBase::ModuleDataGetterType ModuleDataGetter
Getter for module's data. Refer to ModuleBase::ModuleDataGetterType.
Definition Module.h:873
bool IsExiting() const noexcept
Getter for ShouldExit.
Definition Module.h:868
bool ShouldExit
Indicates whether the module thread using this ModuleInstance instance should terminate.
Definition Module.h:880
Parameter class for ModuleBase.
Definition Module.h:374
std::unique_ptr< ModuleDataBase > ModuleData
Just used temporarily during the construction of a module. Refer to MakeModule() and ModuleBase::Modu...
Definition Module.h:402
DummyParam Dummy
Dummy parameter which is to be owned once by parameter classes that do not contain any other paramete...
Definition Module.h:404
bool ConfigureUsageTypeChild() const noexcept override final
Determines whether the Usage parameter should be configurable in the settings dialog....
Definition Module.h:396
void ConfigureParamsImpl(dispatch_tag< RunnableObjectParams >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:392
friend ModulePtrType MakeModule(const std::thread::id, ParamsBasePtrType &&)
Factory function to generate a module of a specific type.
Definition Module.h:46
virtual void ConfigureParamsImpl(dispatch_tag< ModuleParamsBase >)
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:393
virtual ~ModuleParamsBase()=0
Definition Module.cpp:198
ModuleParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a ModuleBase instance.
Definition Module.h:385
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 Module.h:389
const std::thread::id OwnerThreadID
Thread id of the thread which has constructed (and owns) this Object instance.
Definition Object.h:2310
const ParamsBasePtrType Params
Pointer to the parameter class instance belonging to this Object instance.
Definition Object.h:2311
Refer to ParamsBase::dispatch_tag.
Definition Object.h:2026
Dummy parameter which is to be owned once by parameter classes that do not contain any other paramete...
Definition Object.h:522
Abstract base class for object parameter classes. Each class derived from class Object must be accomp...
Definition Object.h:326
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
Base class for modules with a QML-based user interface. Derive from this class to implement modules w...
Definition Module.h:1961
virtual QAnyStringView GetModuleSourceUri() const noexcept=0
Used by QModuleBase::MakeUIWidget to construct the module's user interface QML widget.
virtual void ResetImpl(dispatch_tag< QMLModuleBase >)=0
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
Configurator class for QMLModuleBase.
Definition Module.h:1947
Data class for QMLModuleBase.
Definition Module.h:1909
virtual ~QMLModuleDataBase()=default
virtual void ResetImpl(dispatch_tag< QMLModuleDataBase >)
Definition Module.h:1916
Parameter class for QMLModuleBase.
Definition Module.h:1923
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 Module.h:1934
void ConfigureParamsImpl(dispatch_tag< QModuleParamsBase >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:1937
virtual void ConfigureParamsImpl(dispatch_tag< QMLModuleParamsBase >)
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:1938
QMLModuleParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a QMLModuleBase instance.
Definition Module.h:1929
QQuickView * QuickView
QQuick target displaying the UI.
Definition Module.h:1900
QWidget * QuickViewContainer
Widget containing QuickView.
Definition Module.h:1901
Base class for modules with a Qt-based user interface. Derive from this class to implement modules wi...
Definition Module.h:1668
WidgetType * GetWidget() const
Getter for Widget.
Definition Module.h:1860
QModuleWidget * Widget
User interface widget belonging to the module.
Definition Module.h:1816
void Connect(SenderType *Sender, SignalType Signal, ReceiverType *Receiver, EventType Event)
Uses Qt's connect mechanism to connect a QObject's signal to a DynExp module's event....
Definition Module.h:1825
bool HasUI() const noexcept override final
Determines whether this module possesses a user interface (UI) which is shown in a window dedicated t...
Definition Module.h:1682
QMdiArea * MdiArea
Pointer to DynExpManager's QMdiArea.
Definition Module.h:1821
std::unique_ptr< QModuleDockWidget > DockWidget
Frame for Widget when the module window is undocked from MdiArea.
Definition Module.h:1818
std::unique_ptr< QMdiSubWindow > MdiSubWindow
Frame for Widget when the module window is docked to MdiArea.
Definition Module.h:1817
std::unique_ptr< QAction > ModuleWindowFocusAction
Qt action to push module window into focus. When triggered, QModuleWidget::OnFocusWindow() in invoked...
Definition Module.h:1819
Configurator class for QModuleBase.
Definition Module.h:1654
Data class for QModuleBase.
Definition Module.h:1544
virtual ~QModuleDataBase()=default
virtual void ResetImpl(dispatch_tag< QModuleDataBase >)
Definition Module.h:1551
Provides a frame for QModuleWidget windows, which are undocked from the DynExpManager's QMdiArea.
Definition Module.h:1503
QModuleBase & Owner
Module owning this user interface window.
Definition Module.h:1537
Parameter class for QModuleBase.
Definition Module.h:1630
virtual void ConfigureParamsImpl(dispatch_tag< QModuleParamsBase >)
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:1647
WindowStyleParamsExtension WindowStyleParams
Bundles several parameters to describe a UI window's style. Use in parameter classes.
Definition Module.h:1643
void ConfigureParamsImpl(dispatch_tag< ModuleParamsBase >) override final
Called by DynExp::ParamsBase::ConfigureParams() as a starting point for the tag dispatch mechanism to...
Definition Module.h:1646
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 Module.h:1641
QModuleParamsBase(ItemIDType ID, const DynExpCore &Core)
Constructs the parameters for a QModuleBase instance.
Definition Module.h:1636
Window class for Qt-based user interfaces belonging to DynExp modules. User interface Qt window class...
Definition Module.h:1396
void OnDockWindow()
Qt slot called when DockWindowShortcut is activated, calls QModuleBase::DockUndockWindow().
Definition Module.cpp:499
virtual bool AllowDocked() const noexcept
Indicates the docking behavior of the user interface window. Override to adjust.
Definition Module.h:1445
virtual bool AllowResize() const noexcept
Indicates the resizing behavior of the user interface window. Override to adjust.
Definition Module.h:1438
friend class QModuleBase
Definition Module.h:1399
Qt::WindowFlags GetQtWindowFlags() const noexcept
Depending on thr return value of AllowResize(), returns either the return value of GetQtWindowFlagsRe...
Definition Module.cpp:460
void OnFocusWindow()
Qt slot called when QModuleBase::ModuleWindowFocusAction is triggered, calls QModuleBase::SetFocus().
Definition Module.cpp:504
virtual void closeEvent(QCloseEvent *Event) override
Qt event indicating that the module window is closed. Asks the user whether to terminate the module....
Definition Module.cpp:480
QModuleBase & Owner
Module owning this user interface window (reference, because it should never change nor be nullptr).
Definition Module.h:1486
static constexpr Qt::WindowFlags GetQtWindowFlagsResizable()
Default Qt window flags for resizable module windows.
Definition Module.cpp:439
void OnFocusMainWindow()
Qt slot called when FocusMainWindowShortcut is activated, calls QModuleBase::FocusMainWindow().
Definition Module.cpp:509
static constexpr Qt::WindowFlags GetQtWindowFlagsNonResizable()
Default Qt window flags for non-resizable module windows.
Definition Module.cpp:445
const auto & GetOwner() const noexcept
Getter for the owning module.
Definition Module.h:1428
QShortcut * FocusMainWindowShortcut
Shortcut (Ctrl + 0) to activate/focus DynExp's main window.
Definition Module.h:1490
std::string GetDataSaveDirectory() const
Recalls a path where modules might save recorded data to. Used by Util::PromptSaveFilePathModule() to...
Definition Module.cpp:465
QShortcut * DockWindowShortcut
Shortcut (Ctrl + D) to dock/undock a module window to/from DynExp's main window.
Definition Module.h:1489
void SetDataSaveDirectory(std::string_view Directory) const
Sets a path where modules might save recorded data to. Used by Util::PromptSaveFilePathModule() to st...
Definition Module.cpp:470
void EnableDockWindowShortcut(bool Enable) noexcept
Enables/disables DockWindowShortcut.
Definition Module.cpp:475
DynExpManager * DynExpMgr
DynExp's main window (pointer, because it is set later by QModuleBase::InitUI()).
Definition Module.h:1487
Defines data for a thread belonging to a RunnableObject instance. This data is only accessed by the R...
Definition Object.h:3521
const RunnableObject & Owner
RunnableObject instance which operates on this RunnableInstance (by its thread). The RunnableObject i...
Definition Object.h:3754
std::promise< void > ThreadExitedPromise
Signals the RunnableObject instance owning the thread that its thread has terminated....
Definition Object.h:3768
Configurator class for RunnableObject.
Definition Object.h:2420
Parameter class for RunnableObject.
Definition Object.h:2357
Defines an Object which possesses a thread it runs in. The RunnableObject can be started and stopped ...
Definition Object.h:2434
void SetReasonWhyPaused(std::string Description)
Sets the reason why this RunnableObject instance has been paused.
Definition Object.h:2615
Typed managers of event listeners class whose instances are owned by classes derived from InterModule...
Definition Module.h:952
virtual ~TypedEventListeners()=default
void DeregisterAllUnsafe(const ModuleBase &Listener)
This function is not thread-safe (assuming EventListenersBase's mutex has already been locked before ...
Definition Module.h:1115
std::unordered_map< const ListenersTypeKey, EventFunctionType, ListenersTypeKeyHasher > Listeners
Each module can register to each inter-module event with one event function of type EventFunctionType...
Definition Module.h:1147
EventFunctionType GetFunc(const ModuleBase &Listener, ItemIDType CommunicatorID=ItemIDNotSet, const std::chrono::milliseconds Timeout=DefaultTimeout) const
Looks up the event function the module Listener has registered/subscribed with.
Definition Module.h:1061
virtual void Deregister(const ModuleBase &Listener, const std::chrono::milliseconds Timeout=std::chrono::milliseconds(0)) override
Deregisters/unsubscribes module Listener from the event, regardless of the inter-module communicator ...
Definition Module.h:1045
EventFunctionType GetFuncUnsafe(const ModuleBase &Listener, ItemIDType CommunicatorID) const
This function is the version of GetFunc() which is not thread-safe (assuming EventListenersBase's mut...
Definition Module.h:1131
virtual void Deregister(const ModuleBase &Listener, ItemIDType CommunicatorID, const std::chrono::milliseconds Timeout=std::chrono::milliseconds(0)) override
Deregisters/unsubscribes module Listener from the event, removing a single registration for a particu...
Definition Module.h:1038
void DeregisterUnsafe(const ModuleBase &Listener, ItemIDType CommunicatorID)
This function is not thread-safe (assuming EventListenersBase's mutex has already been locked before ...
Definition Module.h:1099
void Register(const ModuleBase &Listener, CallableT EventFunc, ItemIDType CommunicatorID=ItemIDNotSet, const std::chrono::milliseconds Timeout=std::chrono::milliseconds(0))
Registers/Subscribes module Listener to the event with the event function EventFunc....
Definition Module.h:1031
std::function< void(ModuleInstance *, EventFuncArgs...)> EventFunctionType
Type of event functions to be invoked when the event is triggered. The first ModuleInstance argument ...
Definition Module.h:1009
void RegisterUnsafe(const ModuleBase &Listener, CallableT EventFunc, ItemIDType CommunicatorID)
This function is not thread-safe (assuming EventListenersBase's mutex has already been locked before ...
Definition Module.h:1080
Bundles several parameters to describe a UI window's style. Use in parameter classes.
Definition Module.h:1558
WindowStyleParamsExtension(ParamsBase &Owner, const std::string &Prefix="")
Constructs a WindowStyleParamsExtension instance.
Definition Module.h:1596
WindowDockingStateType
Indicates the window docking state.
Definition Module.h:1580
ParamsBase::Param< unsigned int > WindowWidth
Window width.
Definition Module.h:1620
ParamsBase::Param< int > WindowPosY
Window y coordinate.
Definition Module.h:1619
WindowStateType
Indicates the window state for showing it.
Definition Module.h:1563
ParamsBase::Param< WindowDockingStateType > WindowDockingState
Window docking state.
Definition Module.h:1623
ParamsBase::Param< int > WindowPosX
Window x coordinate.
Definition Module.h:1618
ParamsBase::Param< WindowStateType > WindowState
Window show state.
Definition Module.h:1622
ParamsBase::Param< unsigned int > WindowHeight
Window height.
Definition Module.h:1621
Wraps a member function of some object and stores its default arguments. Moving from CallableMemberWr...
Definition Util.h:449
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.
Definition Util.cpp:317
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
Definition Exception.h:51
Interface to allow synchronizing the access to derived classes between different threads by providing...
Definition Util.h:57
LockType AcquireLock(const std::chrono::milliseconds Timeout=DefaultTimeout) const
Locks the internal mutex. Blocks until the mutex is locked or until the timeout duration is exceeded.
Definition Util.cpp:8
static constexpr std::chrono::milliseconds DefaultTimeout
Duration which is used as a default timeout within all methods of this class if no different duration...
Definition Util.h:63
Interface to allow synchronizing the access to derived classes between different threads by making th...
Definition Util.h:94
An invalid argument like a null pointer has been passed to a function.
Definition Exception.h:138
An operation cannot be performed currently since the related object is in an invalid state like an er...
Definition Exception.h:151
Helper class to communicate flags between different threads based on a condition variable and a mutex...
Definition Util.h:266
void Notify()
Set notification to stop waiting (sets EventOccurred to true).
Definition Util.cpp:69
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition Util.h:171
DynExp's module namespace contains the implementation of DynExp modules which extend DynExp's core fu...
DynExp's main namespace contains the implementation of DynExp including classes to manage resources (...
int ModuleThreadMain(std::unique_ptr< RunnableInstance > &&InstancePtr, RunnableObject *BaseObject)
Modules run in their own thread. This is the module thread's main function.
Definition Module.cpp:10
ConfiguratorBasePtrType MakeModuleConfig()
Factory function to generate a configurator for a specific module type.
Definition Module.h:33
ModulePtrType MakeModule(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Factory function to generate a module of a specific type.
Definition Module.h:46
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.
auto MakeEvent(ReceiverType *Receiver, typename DefaultEvent< ReceiverType, std::tuple< std::remove_reference_t< ArgsTs >... > >::EventFuncPtrType EventFuncPtr, ArgsTs &&...Args)
Creates an event of type DefaultEvent.
Definition Module.h:811
auto dynamic_ModuleData_cast(Util::SynchronizedPointer< From > &&ModuleDataPtr)
Casts the data base class From into a derived ModuleBase's (To) data class keeping the data locked by...
Definition Module.h:899
std::unique_ptr< ModuleBase > ModulePtrType
Pointer type to store a module (DynExp::ModuleBase) with.
Definition Module.h:25
std::shared_ptr< ConfiguratorBase > ConfiguratorBasePtrType
Alias for a pointer to the configurator base class ConfiguratorBase.
Definition Object.h:1959
DynExpErrorCodes
DynExp's error codes
Definition Exception.h:22
DynExp's Util namespace contains commonly used functions and templates as well as extensions to Qt an...
typename remove_first_from_tuple< TupleT >::type remove_first_from_tuple_t
Alias for a tuple of types where the first type of the input tuple TupleT is removed.
Definition Util.h:393
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
Definition Util.cpp:517
void HashCombine(std::size_t &seed, const T &value)
Combines the std::hash seed with the hash of value. Resembles hash_combine() from the Boost library p...
Definition Util.h:612
typename member_fn_ptr_traits< CallableT >::argument_types argument_of_t
Alias for a tuple of argument types the member function callable of type CallableT expects.
Definition Util.h:375
Accumulates include statements to provide a precompiled header.
Helper struct to allow accessing elements within ArgTupleType.
Definition Module.h:106
void(ReceiverType::*)(ModuleInstance *, std::tuple_element_t< Indices, ArgTupleType >...) const EventFuncPtrType
Signature of an event function. Pointer to ModuleInstance to be passed as parameter instead of refere...
Definition Module.h:114
Hasher required to use ListenersTypeKey as the key type for the std::unordered_map Listeners.
Definition Module.h:987
size_t operator()(const ListenersTypeKey &v) const
Computes the hash of v.
Definition Module.h:993
Key type of the unordered_map storing module/inter-module communicator combinations that registered t...
Definition Module.h:958
const ModuleBase * Module
Module that registered to the event.
Definition Module.h:962
bool operator==(const ListenersTypeKey &Other) const
Checks for equality of Module and CommunicatorID.
Definition Module.h:976
const ItemIDType CommunicatorID
ID of the inter-module communicator instrument (instance of DynExpInstr::InterModuleCommunicator) bel...
Definition Module.h:969