ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
VariableNetworkNode.h
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#pragma once
4
5#include "ConstantAccessor.h"
6#include "Flags.h"
7#include "Logger.h"
9#include "Model.h"
10#include "Visitor.h"
11
12#include <ChimeraTK/NDRegisterAccessorAbstractor.h>
13
14#include <boost/shared_ptr.hpp>
15
16#include <cassert>
17#include <iostream>
18#include <unordered_map>
19#include <unordered_set>
20
21namespace ChimeraTK {
22
23 /********************************************************************************************************************/
24
25 class AccessorBase;
26 class EntityOwner;
27 struct VariableNetworkNode_data;
28
29 /********************************************************************************************************************/
30
32 class AnyType {};
33
34 /********************************************************************************************************************/
35
38 public:
41
44
46 VariableNetworkNode(EntityOwner* owner, ChimeraTK::TransferElementAbstractor* accessorBridge,
47 const std::string& name, VariableDirection direction, std::string unit, size_t nElements, UpdateMode mode,
48 const std::string& description, const std::type_info* valueType,
49 const std::unordered_set<std::string>& tags = {});
50
52 VariableNetworkNode(const std::string& name, const std::string& devAlias, const std::string& regName,
53 UpdateMode mode, VariableDirection direction, bool isReadable, const std::type_info& valTyp = typeid(AnyType),
54 size_t nElements = 0);
55
57 VariableNetworkNode(const std::string& pubName, VariableDirection direction,
58 const std::type_info& valTyp = typeid(AnyType), size_t nElements = 0);
59
61 VariableNetworkNode(const std::type_info* valTyp, bool makeFeeder, size_t length);
62
67 VariableNetworkNode(const std::string& deviceAliasOrCdd, int);
68
70 explicit VariableNetworkNode(boost::shared_ptr<VariableNetworkNode_data> pdata);
71
74
80 void setMetaData(const std::optional<std::string>& name, const std::optional<std::string>& unit = {},
81 const std::optional<std::string>& description = {},
82 const std::optional<std::unordered_set<std::string>>& tags = {});
83
85 void clearOwner();
86
89 void setValueType(const std::type_info& newType) const;
90
93 void setDirection(VariableDirection newDirection) const;
94
96 [[nodiscard]] bool hasImplementation() const;
97
99 bool operator==(const VariableNetworkNode& other) const;
100 bool operator!=(const VariableNetworkNode& other) const;
101 bool operator<(const VariableNetworkNode& other) const;
102
104 void dump(std::ostream& stream = std::cout) const;
105
110 void addTag(const std::string& tag) const;
111
113 [[nodiscard]] bool isCircularInput() const;
114
118 [[nodiscard]] std::list<EntityOwner*> scanForCircularDepencency() const;
119
121 [[nodiscard]] size_t getCircularNetworkHash() const;
122
123 [[nodiscard]] bool isValid() const { return pdata && getType() != NodeType::invalid; }
124
126 [[nodiscard]] NodeType getType() const;
127 [[nodiscard]] UpdateMode getMode() const;
128 [[nodiscard]] VariableDirection getDirection() const;
129 [[nodiscard]] const std::type_info& getValueType() const;
130 [[nodiscard]] std::string getName() const;
131 [[nodiscard]] std::string getQualifiedName() const;
132 [[nodiscard]] const std::string& getUnit() const;
133 [[nodiscard]] const std::string& getDescription() const;
134 [[nodiscard]] VariableNetworkNode getNodeToTrigger() const;
135 [[nodiscard]] const std::string& getPublicName() const;
136 [[nodiscard]] const std::string& getDeviceAlias() const;
137 [[nodiscard]] const std::string& getRegisterName() const;
138 [[nodiscard]] const std::unordered_set<std::string>& getTags() const;
139 void setNumberOfElements(size_t nElements) const;
140 [[nodiscard]] size_t getNumberOfElements() const;
141 [[nodiscard]] ChimeraTK::TransferElementAbstractor& getAppAccessorNoType() const;
142 [[nodiscard]] bool isReadable() const;
143
144 [[nodiscard]] Model::ProcessVariableProxy getModel() const;
145
146 void setModel(const Model::ProcessVariableProxy& model) const;
147
148 void setPublicName(const std::string& name) const;
149
150 template<typename UserType>
151 ChimeraTK::NDRegisterAccessorAbstractor<UserType>& getAppAccessor() const;
152
153 template<typename UserType>
154 void setAppAccessorImplementation(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> impl) const;
155
157
160 [[nodiscard]] const void* getUniqueId() const { return pdata.get(); }
161
163 void setAppAccessorPointer(ChimeraTK::TransferElementAbstractor* accessor) const;
164
165 [[nodiscard]] EntityOwner* getOwningModule() const;
166
167 void setOwningModule(EntityOwner* newOwner) const;
168
169 void accept(Visitor<VariableNetworkNode>& visitor) const;
170
171 template<typename UserType>
172 void setConstantValue(UserType value);
173
174 template<typename UserType>
175 UserType getConstantValue() const;
176
177 void registerInModel();
178
179 // protected: @todo make protected again (with proper interface extension)
180
181 boost::shared_ptr<VariableNetworkNode_data> pdata;
182 };
183
184 /********************************************************************************************************************/
185
188 constexpr auto explicitDataValidityTag = "_ChimeraTK_NodeHasExplicitDataValidity";
189
192 constexpr auto independentVersionTag = "_ChimeraTK_NodeHasIndependentVersion";
193
194 /********************************************************************************************************************/
195
201
204
207
210
213 const std::type_info* valueType{&typeid(AnyType)};
214
217 std::string unit{ChimeraTK::TransferElement::unitNotSet};
218
220 std::string description;
221
223 ChimeraTK::TransferElementAbstractor* appNode{nullptr};
224
227
232
234 std::string publicName;
235
237 std::string name;
238 std::string qualifiedName;
239
241 std::string deviceAlias;
242 std::string registerName;
243 bool isReadable{true};
244
246 size_t nElements{0};
247
249 std::unordered_set<std::string> tags;
250
253 std::map<VariableNetworkNode, VariableNetworkNode> nodeWithTrigger;
254
257
260
263
265 userTypeMap constantValue;
266 };
267
268 /********************************************************************************************************************/
269 /*** Implementations ************************************************************************************************/
270 /********************************************************************************************************************/
271
272 template<typename UserType>
273 ChimeraTK::NDRegisterAccessorAbstractor<UserType>& VariableNetworkNode::getAppAccessor() const {
274 assert(typeid(UserType) == getValueType());
275 assert(pdata->type == NodeType::Application);
276 auto accessor = static_cast<ChimeraTK::NDRegisterAccessorAbstractor<UserType>*>(pdata->appNode);
277 assert(accessor != nullptr);
278 return *accessor;
279 }
280
281 /********************************************************************************************************************/
282
283 template<typename UserType>
284 void VariableNetworkNode::setAppAccessorImplementation(boost::shared_ptr<NDRegisterAccessor<UserType>> impl) const {
285 auto decorated =
286 boost::make_shared<MetaDataPropagatingRegisterDecorator<UserType>>(impl, getOwningModule(), getDirection());
287 if(pdata->tags.find(explicitDataValidityTag) != pdata->tags.end()) {
288 decorated->disableDataValidityPropagation();
289 }
290 if(pdata->tags.find(independentVersionTag) != pdata->tags.end()) {
291 decorated->disableVersionNumberPropagation();
292 }
293
294 getAppAccessor<UserType>().replace(decorated);
295 auto flagProvider = boost::dynamic_pointer_cast<MetaDataPropagationFlagProvider>(decorated);
296 assert(flagProvider);
297 }
298
299 /********************************************************************************************************************/
300
301 template<typename UserType>
303 assert(pdata->type == NodeType::Constant);
304 boost::fusion::at_key<UserType>(pdata->constantValue) = value;
305 }
306
307 /********************************************************************************************************************/
308
309 template<typename UserType>
311 assert(pdata->type == NodeType::Constant);
312 return boost::fusion::at_key<UserType>(pdata->constantValue);
313 }
314
315 /********************************************************************************************************************/
316
317} /* namespace ChimeraTK */
Pseudo type to identify nodes which can have arbitrary types.
Base class for owners of other EntityOwners (e.g.
Definition EntityOwner.h:38
Proxy class which does not keep the ownership of the model.
Definition Model.h:466
Class describing a node of a variable network.
void dump(std::ostream &stream=std::cout) const
Print node information to specified stream.
void setValueType(const std::type_info &newType) const
Set the value type for this node.
boost::shared_ptr< VariableNetworkNode_data > pdata
ChimeraTK::TransferElementAbstractor & getAppAccessorNoType() const
NodeType getType() const
Getter for the properties.
void clearOwner()
Clear the owner network of this node.
void setAppAccessorImplementation(boost::shared_ptr< ChimeraTK::NDRegisterAccessor< UserType > > impl) const
const std::string & getRegisterName() const
const std::unordered_set< std::string > & getTags() const
Model::ProcessVariableProxy getModel() const
void setDirection(VariableDirection newDirection) const
Set the direction for this node.
const std::string & getPublicName() const
bool isCircularInput() const
Returns true if a circular dependency has been detected and the node is a consumer.
void setAppAccessorPointer(ChimeraTK::TransferElementAbstractor *accessor) const
Change pointer to the accessor.
const std::type_info & getValueType() const
bool operator<(const VariableNetworkNode &other) const
void setOwningModule(EntityOwner *newOwner) const
const std::string & getDescription() const
void setModel(const Model::ProcessVariableProxy &model) const
VariableNetworkNode & operator=(const VariableNetworkNode &rightHandSide)
Copy by assignment operator: Just copy the pointer to the data storage object.
void setNumberOfElements(size_t nElements) const
bool operator==(const VariableNetworkNode &other) const
Compare two nodes.
bool hasImplementation() const
Function checking if the node requires a fixed implementation.
VariableNetworkNode()
Default constructor for an invalid node.
size_t getCircularNetworkHash() const
Get the unique ID of the circular network.
void setPublicName(const std::string &name) const
const void * getUniqueId() const
Return the unique ID of this node (will change every time the application is started).
VariableDirection getDirection() const
void setAppAccessorConstImplementation(const VariableNetworkNode &feeder) const
ChimeraTK::NDRegisterAccessorAbstractor< UserType > & getAppAccessor() const
bool operator!=(const VariableNetworkNode &other) const
std::list< EntityOwner * > scanForCircularDepencency() const
Scan the networks and set the isCircularInput() flags if circular dependencies are detected.
void accept(Visitor< VariableNetworkNode > &visitor) const
void addTag(const std::string &tag) const
Add a tag.
VariableNetworkNode getNodeToTrigger() const
VariableNetworkNode(const VariableNetworkNode &other)
Copy-constructor: Just copy the pointer to the data storage object.
const std::string & getDeviceAlias() const
const std::string & getUnit() const
void setMetaData(const std::optional< std::string > &name, const std::optional< std::string > &unit={}, const std::optional< std::string > &description={}, const std::optional< std::unordered_set< std::string > > &tags={})
Change meta data (name, unit, description and optionally tags).
InvalidityTracer application module.
constexpr auto explicitDataValidityTag
Special tag to designate that a node should not automatically take over DataValidity of its owning mo...
constexpr auto independentVersionTag
Special tag to designate that a push-input should not propagate VersionNumber updates to its owning m...
UpdateMode
Enum to define the update mode of variables.
Definition Flags.h:31
NodeType
Enum to define types of VariableNetworkNode.
Definition Flags.h:36
Struct to define the direction of variables.
Definition Flags.h:13
We use a pimpl pattern so copied instances of VariableNetworkNode refer to the same instance of the d...
std::string deviceAlias
Device information if type == Device.
Model::NonOwningProxy< Model::ProcessVariableProxy > model
Model representation of this variable.
UpdateMode mode
Update mode: poll or push.
size_t nElements
Number of elements in the variable.
VariableNetworkNode nodeToTrigger
Pointer to network which should be triggered by this node.
std::string name
Accessor name if type == Application.
std::string unit
Engineering unit.
const std::type_info * valueType
Value type of this node.
ChimeraTK::TransferElementAbstractor * appNode
Pointer to implementation if type == Application.
EntityOwner * owningModule
Pointer to the module owning this node.
size_t circularNetworkHash
Hash which identifies a circular network.
std::string publicName
Public name if type == ControlSystem.
std::unordered_set< std::string > tags
Set of tags if type == Application || type == Device.
userTypeMap constantValue
Value in case of a constant.
NodeType type
Type of the node (Application, Device, ControlSystem, Trigger)
std::map< VariableNetworkNode, VariableNetworkNode > nodeWithTrigger
Map to store triggered versions of this node.
VariableNetworkNode externalTrigger
Pointer to the network providing the external trigger.
VariableDirection direction
Node direction: feeding or consuming.