ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
Module.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#include "Module.h"
4
5#include "Application.h"
6#include "ApplicationModule.h"
7#include "ConfigReader.h"
8#include "DeviceModule.h"
9#include "Utilities.h"
10
11namespace ChimeraTK {
12
13 Module::Module(EntityOwner* owner, const std::string& name, const std::string& description,
14 const std::unordered_set<std::string>& tags)
15 : EntityOwner(ChimeraTK::Utilities::raiseIftrailingSlash(name, true), description, tags), _owner(owner) {
16 if(_owner != nullptr) {
18 }
19 }
20
21 /********************************************************************************************************************/
22
24 if(_owner != nullptr) {
26 }
27 }
28
29 /********************************************************************************************************************/
30
31 Module& Module::operator=(Module&& other) noexcept {
32 if(_owner != nullptr) {
33 _owner->unregisterModule(this);
34 }
35 if(other._owner != nullptr) {
36 other._owner->unregisterModule(&other);
37 }
38 _owner = other._owner;
39 other._owner = nullptr;
40 EntityOwner::operator=(std::move(other));
41 if(_owner != nullptr) {
42 _owner->registerModule(this, false);
43 }
44 return *this;
45 }
46 /********************************************************************************************************************/
47
48 void Module::run() {
49 _testableModeReached = true; // Modules which don't implement run() have now reached testable mode
50 }
51
52 /********************************************************************************************************************/
53
54 ChimeraTK::ReadAnyGroup Module::readAnyGroup() {
55 auto recursiveAccessorList = getAccessorListRecursive();
56
57 // put push-type transfer elements into a ReadAnyGroup
58 ChimeraTK::ReadAnyGroup group;
59 for(auto& accessor : recursiveAccessorList) {
60 if(accessor.getDirection() == VariableDirection{VariableDirection::feeding, false}) {
61 continue;
62 }
63 group.add(accessor.getAppAccessorNoType());
64 }
65
66 group.finalise();
67 return group;
68 }
69
70 /********************************************************************************************************************/
71
72 void Module::readAll(bool includeReturnChannels) {
73 auto recursiveAccessorList = getAccessorListRecursive();
74 // first blockingly read all push-type variables
75 for(auto& accessor : recursiveAccessorList) {
76 if(accessor.getMode() != UpdateMode::push) {
77 continue;
78 }
79 if(includeReturnChannels) {
80 if(accessor.getDirection() == VariableDirection{VariableDirection::feeding, false}) {
81 continue;
82 }
83 }
84 else {
85 if(accessor.getDirection().dir != VariableDirection::consuming) {
86 continue;
87 }
88 }
89 accessor.getAppAccessorNoType().read();
90 }
91 // next non-blockingly read the latest values of all poll-type variables
92 for(auto& accessor : recursiveAccessorList) {
93 if(accessor.getMode() == UpdateMode::push) {
94 continue;
95 }
96 // poll-type accessors cannot have a readback channel
97 if(accessor.getDirection().dir != VariableDirection::consuming) {
98 continue;
99 }
100 accessor.getAppAccessorNoType().readLatest();
101 }
102 }
103
104 /********************************************************************************************************************/
105
106 void Module::readAllNonBlocking(bool includeReturnChannels) {
107 auto recursiveAccessorList = getAccessorListRecursive();
108 for(auto& accessor : recursiveAccessorList) {
109 if(accessor.getMode() != UpdateMode::push) {
110 continue;
111 }
112 if(includeReturnChannels) {
113 if(accessor.getDirection() == VariableDirection{VariableDirection::feeding, false}) {
114 continue;
115 }
116 }
117 else {
118 if(accessor.getDirection().dir != VariableDirection::consuming) {
119 continue;
120 }
121 }
122 accessor.getAppAccessorNoType().readNonBlocking();
123 }
124 for(auto& accessor : recursiveAccessorList) {
125 if(accessor.getMode() == UpdateMode::push) {
126 continue;
127 }
128 // poll-type accessors cannot have a readback channel
129 if(accessor.getDirection().dir != VariableDirection::consuming) {
130 continue;
131 }
132 accessor.getAppAccessorNoType().readLatest();
133 }
134 }
135
136 /********************************************************************************************************************/
137
138 void Module::readAllLatest(bool includeReturnChannels) {
139 auto recursiveAccessorList = getAccessorListRecursive();
140 for(auto& accessor : recursiveAccessorList) {
141 if(includeReturnChannels) {
142 if(accessor.getDirection() == VariableDirection{VariableDirection::feeding, false}) {
143 continue;
144 }
145 }
146 else {
147 if(accessor.getDirection().dir != VariableDirection::consuming) {
148 continue;
149 }
150 }
151 accessor.getAppAccessorNoType().readLatest();
152 }
153 }
154
155 /********************************************************************************************************************/
156
157 void Module::writeAll(bool includeReturnChannels) {
158 auto versionNumber = getCurrentVersionNumber();
159 auto recursiveAccessorList = getAccessorListRecursive();
160 for(auto& accessor : recursiveAccessorList) {
161 if(includeReturnChannels) {
162 if(accessor.getDirection() == VariableDirection{VariableDirection::consuming, false}) {
163 continue;
164 }
165 }
166 else {
167 if(accessor.getDirection().dir != VariableDirection::feeding) {
168 continue;
169 }
170 }
171 accessor.getAppAccessorNoType().write(versionNumber);
172 }
173 }
174
175 /********************************************************************************************************************/
176
177 void Module::writeAllDestructively(bool includeReturnChannels) {
178 auto versionNumber = getCurrentVersionNumber();
179 auto recursiveAccessorList = getAccessorListRecursive();
180 for(auto& accessor : recursiveAccessorList) {
181 if(includeReturnChannels) {
182 if(accessor.getDirection() == VariableDirection{VariableDirection::consuming, false}) {
183 continue;
184 }
185 }
186 else {
187 if(accessor.getDirection().dir != VariableDirection::feeding) {
188 continue;
189 }
190 }
191 accessor.getAppAccessorNoType().writeDestructively(versionNumber);
192 }
193 }
194
195 /********************************************************************************************************************/
196
199 auto* ret = dynamic_cast<ApplicationModule*>(this);
200 assert(ret != nullptr);
201 return ret;
202 }
204 auto* ret = dynamic_cast<DeviceModule*>(this);
205 assert(ret != nullptr);
206 return ret;
207 }
209 auto* owningModule = dynamic_cast<Module*>(getOwner());
210 assert(owningModule != nullptr);
211 return owningModule->findApplicationModule();
212 }
213 throw ChimeraTK::logic_error(
214 "EntityOwner::findApplicationModule() called on neither an ApplicationModule nor a VariableGroup.");
215 }
216
217 /********************************************************************************************************************/
218
219 std::string Module::getQualifiedName() const {
220 return ((_owner != nullptr) ? _owner->getQualifiedName() : "") + "/" + _name;
221 }
222
223 /********************************************************************************************************************/
224
225 std::string Module::getFullDescription() const {
226 if(_owner == nullptr) {
227 return _description;
228 }
229 auto ownerDescription = _owner->getFullDescription();
230 if(ownerDescription.empty()) {
231 return _description;
232 }
233 if(_description.empty()) {
234 return ownerDescription;
235 }
236 return ownerDescription + " - " + _description;
237 }
238
239 /********************************************************************************************************************/
240
241 std::list<EntityOwner*> Module::getInputModulesRecursively(std::list<EntityOwner*> startList) {
242 if(_owner == nullptr) {
243 return {};
244 }
245
246 return _owner->getInputModulesRecursively(startList);
247 }
248
249 /********************************************************************************************************************/
250
254
255 /********************************************************************************************************************/
256
258 for(const auto& acc : getAccessorList()) {
259 auto m = acc.getModel();
260 if(m.isValid()) {
261 m.removeNode(acc);
262 }
263 }
264
265 for(auto* submod : getSubmoduleList()) {
266 submod->disable();
267 }
268
269 if(_owner) {
271 _owner = nullptr;
272 }
273 }
274
275 /********************************************************************************************************************/
276
277} /* namespace ChimeraTK */
ConfigReader & getConfigReader()
static Application & getInstance()
Obtain instance of the application.
ChimeraTK::Model::ApplicationModuleProxy getModel()
Return the application model proxy representing this module.
Generic module to read an XML config file and provide the defined values as constant variables.
Base class for owners of other EntityOwners (e.g.
Definition EntityOwner.h:38
std::list< VariableNetworkNode > getAccessorList() const
Obtain the list of accessors/variables directly associated with this instance.
Definition EntityOwner.h:77
std::list< Module * > getSubmoduleList() const
Obtain the list of submodules associated with this instance.
Definition EntityOwner.h:80
std::string _name
The name of this instance.
virtual ModuleType getModuleType() const =0
Return the module type of this module, or in case of a VirtualModule the module type this VirtualModu...
virtual void unregisterModule(Module *module)
Unregister another module as a sub-module.
std::string _description
The description of this instance.
std::atomic< bool > _testableModeReached
Flag used by the testable mode to identify whether a thread within the EntityOwner has reached the po...
void registerModule(Module *module, bool addTags=true)
Register another module as a sub-module.
virtual std::string getQualifiedName() const =0
Get the fully qualified name of the module instance, i.e.
EntityOwner & operator=(EntityOwner &&other) noexcept
Move assignment operator.
virtual std::string getFullDescription() const =0
Obtain the full description including the full description of the owner.
virtual std::list< EntityOwner * > getInputModulesRecursively(std::list< EntityOwner * > startList)=0
Use pointer to the module as unique identifier.
std::list< VariableNetworkNode > getAccessorListRecursive() const
Obtain the list of accessors/variables associated with this instance and any submodules.
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Definition Module.h:21
void readAllLatest(bool includeReturnChannels=false)
Just call readLatest() on all readable variables in the group.
Definition Module.cc:138
std::string getQualifiedName() const override
Get the fully qualified name of the module instance, i.e.
Definition Module.cc:219
VersionNumber getCurrentVersionNumber() const override
Return the current version number which has been received with the last push-type read operation.
Definition Module.h:104
void readAll(bool includeReturnChannels=false)
Read all readable variables in the group.
Definition Module.cc:72
void readAllNonBlocking(bool includeReturnChannels=false)
Just call readNonBlocking() on all readable variables in the group.
Definition Module.cc:106
EntityOwner * _owner
Owner of this instance.
Definition Module.h:145
void disable()
Disable the module such that it is not part of the Application.
Definition Module.cc:257
void writeAllDestructively(bool includeReturnChannels=false)
Just call writeDestructively() on all writable variables in the group.
Definition Module.cc:177
Module * findApplicationModule()
Find ApplicationModule owner.
Definition Module.cc:197
std::list< EntityOwner * > getInputModulesRecursively(std::list< EntityOwner * > startList) override
Use pointer to the module as unique identifier.
Definition Module.cc:241
~Module() override
Destructor.
Definition Module.cc:23
Module & operator=(Module &&other) noexcept
Move assignment operator.
Definition Module.cc:31
static ConfigReader & appConfig()
Obtain the ConfigReader instance of the application.
Definition Module.cc:251
ChimeraTK::ReadAnyGroup readAnyGroup()
Create a ChimeraTK::ReadAnyGroup for all readable variables in this Module.
Definition Module.cc:54
EntityOwner * getOwner() const
Definition Module.h:102
void writeAll(bool includeReturnChannels=false)
Just call write() on all writable variables in the group.
Definition Module.cc:157
std::string getFullDescription() const override
Obtain the full description including the full description of the owner.
Definition Module.cc:225
virtual void run()
Execute the module.
Definition Module.cc:48
Module()=default
Default constructor: Allows late initialisation of modules (e.g.
InvalidityTracer application module.
Struct to define the direction of variables.
Definition Flags.h:13