ChimeraTK-ApplicationCore  04.01.00
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 #include <unordered_map>
12 #include <unordered_set>
13 
14 #include <ChimeraTK/NDRegisterAccessorAbstractor.h>
15 
16 #include <boost/shared_ptr.hpp>
17 
18 #include <cassert>
19 #include <iostream>
20 
21 namespace 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 
43  VariableNetworkNode& operator=(const VariableNetworkNode& rightHandSide);
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, 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 
79  void setMetaData(const std::string& name, const std::string& unit, const std::string& description) const;
80  void setMetaData(const std::string& name, const std::string& unit, const std::string& description,
81  const std::unordered_set<std::string>& tags) const;
82 
84  void clearOwner();
85 
88  void setValueType(const std::type_info& newType) const;
89 
92  void setDirection(VariableDirection newDirection) const;
93 
95  [[nodiscard]] bool hasImplementation() const;
96 
98  bool operator==(const VariableNetworkNode& other) const;
99  bool operator!=(const VariableNetworkNode& other) const;
100  bool operator<(const VariableNetworkNode& other) const;
101 
103  void dump(std::ostream& stream = std::cout) const;
104 
109  void addTag(const std::string& tag) const;
110 
112  [[nodiscard]] bool isCircularInput() const;
113 
117  [[nodiscard]] std::list<EntityOwner*> scanForCircularDepencency() const;
118 
120  [[nodiscard]] size_t getCircularNetworkHash() const;
121 
122  [[nodiscard]] bool isValid() const { return pdata && getType() != NodeType::invalid; }
123 
125  [[nodiscard]] NodeType getType() const;
126  [[nodiscard]] UpdateMode getMode() const;
127  [[nodiscard]] VariableDirection getDirection() const;
128  [[nodiscard]] const std::type_info& getValueType() const;
129  [[nodiscard]] std::string getName() const;
130  [[nodiscard]] std::string getQualifiedName() const;
131  [[nodiscard]] const std::string& getUnit() const;
132  [[nodiscard]] const std::string& getDescription() const;
133  [[nodiscard]] VariableNetworkNode getNodeToTrigger() const;
134  [[nodiscard]] const std::string& getPublicName() const;
135  [[nodiscard]] const std::string& getDeviceAlias() const;
136  [[nodiscard]] const std::string& getRegisterName() const;
137  [[nodiscard]] const std::unordered_set<std::string>& getTags() const;
138  void setNumberOfElements(size_t nElements) const;
139  [[nodiscard]] size_t getNumberOfElements() const;
140  [[nodiscard]] ChimeraTK::TransferElementAbstractor& getAppAccessorNoType() const;
141 
142  [[nodiscard]] Model::ProcessVariableProxy getModel() const;
143 
144  void setModel(const Model::ProcessVariableProxy& model) const;
145 
146  void setPublicName(const std::string& name) const;
147 
148  template<typename UserType>
149  ChimeraTK::NDRegisterAccessorAbstractor<UserType>& getAppAccessor() const;
150 
151  template<typename UserType>
152  void setAppAccessorImplementation(boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> impl) const;
153 
154  void setAppAccessorConstImplementation(const VariableNetworkNode& feeder) const;
155 
158  [[nodiscard]] const void* getUniqueId() const { return pdata.get(); }
159 
161  void setAppAccessorPointer(ChimeraTK::TransferElementAbstractor* accessor) const;
162 
163  [[nodiscard]] EntityOwner* getOwningModule() const;
164 
165  void setOwningModule(EntityOwner* newOwner) const;
166 
167  void accept(Visitor<VariableNetworkNode>& visitor) const;
168 
169  template<typename UserType>
170  void setConstantValue(UserType value);
171 
172  template<typename UserType>
173  UserType getConstantValue() const;
174 
175  // protected: @todo make protected again (with proper interface extension)
176 
177  boost::shared_ptr<VariableNetworkNode_data> pdata;
178  };
179 
180  /********************************************************************************************************************/
181 
184  constexpr auto explicitDataValidityTag = "_ChimeraTK_NodeHasExplicitDataValidity";
185 
186  /********************************************************************************************************************/
187 
192  VariableNetworkNode_data() = default;
193 
196 
199 
202 
205  const std::type_info* valueType{&typeid(AnyType)};
206 
209  std::string unit{ChimeraTK::TransferElement::unitNotSet};
210 
212  std::string description;
213 
215  ChimeraTK::TransferElementAbstractor* appNode{nullptr};
216 
219 
224 
226  std::string publicName;
227 
229  std::string name;
230  std::string qualifiedName;
231 
233  std::string deviceAlias;
234  std::string registerName;
235 
237  size_t nElements{0};
238 
240  std::unordered_set<std::string> tags;
241 
244  std::map<VariableNetworkNode, VariableNetworkNode> nodeWithTrigger;
245 
248 
251 
254 
256  userTypeMap constantValue;
257  };
258 
259  /********************************************************************************************************************/
260  /*** Implementations ************************************************************************************************/
261  /********************************************************************************************************************/
262 
263  template<typename UserType>
264  ChimeraTK::NDRegisterAccessorAbstractor<UserType>& VariableNetworkNode::getAppAccessor() const {
265  assert(typeid(UserType) == getValueType());
266  assert(pdata->type == NodeType::Application);
267  auto accessor = static_cast<ChimeraTK::NDRegisterAccessorAbstractor<UserType>*>(pdata->appNode);
268  assert(accessor != nullptr);
269  return *accessor;
270  }
271 
272  /********************************************************************************************************************/
273 
274  template<typename UserType>
275  void VariableNetworkNode::setAppAccessorImplementation(boost::shared_ptr<NDRegisterAccessor<UserType>> impl) const {
276  auto decorated =
277  boost::make_shared<MetaDataPropagatingRegisterDecorator<UserType>>(impl, getOwningModule(), getDirection());
278  if(pdata->tags.find(explicitDataValidityTag) != pdata->tags.end()) {
279  decorated->disableDataValidityPropagation();
280  }
281 
282  getAppAccessor<UserType>().replace(decorated);
283  auto flagProvider = boost::dynamic_pointer_cast<MetaDataPropagationFlagProvider>(decorated);
284  assert(flagProvider);
285  }
286 
287  /********************************************************************************************************************/
288 
289  template<typename UserType>
291  assert(pdata->type == NodeType::Constant);
292  boost::fusion::at_key<UserType>(pdata->constantValue) = value;
293  }
294 
295  /********************************************************************************************************************/
296 
297  template<typename UserType>
299  assert(pdata->type == NodeType::Constant);
300  return boost::fusion::at_key<UserType>(pdata->constantValue);
301  }
302 
303  /********************************************************************************************************************/
304 
305 } /* namespace ChimeraTK */
ChimeraTK::VariableNetworkNode
Class describing a node of a variable network.
Definition: VariableNetworkNode.h:37
ChimeraTK::VariableDirection
Struct to define the direction of variables.
Definition: Flags.h:13
ChimeraTK::VariableNetworkNode_data::name
std::string name
Accessor name if type == Application.
Definition: VariableNetworkNode.h:229
ChimeraTK::VariableNetworkNode::pdata
boost::shared_ptr< VariableNetworkNode_data > pdata
Definition: VariableNetworkNode.h:177
Flags.h
ChimeraTK::VariableDirection::invalid
@ invalid
Definition: Flags.h:18
ChimeraTK::VariableNetworkNode::getOwningModule
EntityOwner * getOwningModule() const
Definition: VariableNetworkNode.cc:391
ChimeraTK::VariableNetworkNode::setConstantValue
void setConstantValue(UserType value)
Definition: VariableNetworkNode.h:290
ChimeraTK::VariableNetworkNode::getType
NodeType getType() const
Getter for the properties.
Definition: VariableNetworkNode.cc:173
ChimeraTK::VariableNetworkNode::getQualifiedName
std::string getQualifiedName() const
Definition: VariableNetworkNode.cc:206
ChimeraTK::VariableNetworkNode::isValid
bool isValid() const
Definition: VariableNetworkNode.h:122
ChimeraTK::UpdateMode::invalid
@ invalid
ChimeraTK::VariableNetworkNode_data::tags
std::unordered_set< std::string > tags
Set of tags if type == Application.
Definition: VariableNetworkNode.h:240
ChimeraTK::EntityOwner
Base class for owners of other EntityOwners (e.g.
Definition: EntityOwner.h:38
ChimeraTK::VariableNetworkNode_data::publicName
std::string publicName
Public name if type == ControlSystem.
Definition: VariableNetworkNode.h:226
ChimeraTK::VariableNetworkNode_data::unit
std::string unit
Engineering unit.
Definition: VariableNetworkNode.h:209
ChimeraTK::VariableNetworkNode::getUnit
const std::string & getUnit() const
Definition: VariableNetworkNode.cc:212
ChimeraTK::VariableNetworkNode::getValueType
const std::type_info & getValueType() const
Definition: VariableNetworkNode.cc:194
ChimeraTK::VariableNetworkNode::setAppAccessorImplementation
void setAppAccessorImplementation(boost::shared_ptr< ChimeraTK::NDRegisterAccessor< UserType >> impl) const
ChimeraTK::VariableNetworkNode::accept
void accept(Visitor< VariableNetworkNode > &visitor) const
Definition: VariableNetworkNode.cc:124
ChimeraTK::VariableNetworkNode::getAppAccessor
ChimeraTK::NDRegisterAccessorAbstractor< UserType > & getAppAccessor() const
Definition: VariableNetworkNode.h:264
ChimeraTK::VariableNetworkNode::clearOwner
void clearOwner()
Clear the owner network of this node.
ChimeraTK::VariableNetworkNode_data::nElements
size_t nElements
Number of elements in the variable.
Definition: VariableNetworkNode.h:237
ChimeraTK::UpdateMode
UpdateMode
Enum to define the update mode of variables.
Definition: Flags.h:31
ChimeraTK::VariableNetworkNode::getDeviceAlias
const std::string & getDeviceAlias() const
Definition: VariableNetworkNode.cc:238
ChimeraTK::VariableNetworkNode::getDescription
const std::string & getDescription() const
Definition: VariableNetworkNode.cc:218
ChimeraTK::AnyType
Pseudo type to identify nodes which can have arbitrary types.
Definition: VariableNetworkNode.h:32
ChimeraTK::VariableNetworkNode::getConstantValue
UserType getConstantValue() const
Definition: VariableNetworkNode.h:298
ChimeraTK::VariableNetworkNode_data::mode
UpdateMode mode
Update mode: poll or push.
Definition: VariableNetworkNode.h:198
ChimeraTK::VariableNetworkNode::getModel
Model::ProcessVariableProxy getModel() const
Definition: VariableNetworkNode.cc:415
Logger.h
ChimeraTK::VariableNetworkNode::hasImplementation
bool hasImplementation() const
Function checking if the node requires a fixed implementation.
Definition: VariableNetworkNode.cc:117
ChimeraTK::VariableNetworkNode_data::qualifiedName
std::string qualifiedName
Definition: VariableNetworkNode.h:230
ChimeraTK::VariableNetworkNode::setDirection
void setDirection(VariableDirection newDirection) const
Set the direction for this node.
Definition: VariableNetworkNode.cc:158
ChimeraTK::VariableNetworkNode::getCircularNetworkHash
size_t getCircularNetworkHash() const
Get the unique ID of the circular network.
Definition: VariableNetworkNode.cc:409
ChimeraTK::VariableNetworkNode::VariableNetworkNode
VariableNetworkNode()
Default constructor for an invalid node.
Definition: VariableNetworkNode.cc:113
ChimeraTK::VariableNetworkNode_data::appNode
ChimeraTK::TransferElementAbstractor * appNode
Pointer to implementation if type == Application.
Definition: VariableNetworkNode.h:215
ChimeraTK::VariableNetworkNode::getRegisterName
const std::string & getRegisterName() const
Definition: VariableNetworkNode.cc:245
ChimeraTK::VariableNetworkNode::getTags
const std::unordered_set< std::string > & getTags() const
Definition: VariableNetworkNode.cc:378
ChimeraTK::VariableNetworkNode_data::valueType
const std::type_info * valueType
Value type of this node.
Definition: VariableNetworkNode.h:205
ChimeraTK::VariableNetworkNode_data::owningModule
EntityOwner * owningModule
Pointer to the module owning this node.
Definition: VariableNetworkNode.h:247
MetaDataPropagatingRegisterDecorator.h
ChimeraTK::VariableNetworkNode_data::nodeToTrigger
VariableNetworkNode nodeToTrigger
Pointer to network which should be triggered by this node.
Definition: VariableNetworkNode.h:218
ChimeraTK::VariableNetworkNode_data::deviceAlias
std::string deviceAlias
Device information if type == Device.
Definition: VariableNetworkNode.h:233
ChimeraTK::NodeType::Constant
@ Constant
ChimeraTK::VariableNetworkNode_data::circularNetworkHash
size_t circularNetworkHash
Hash which idientifies a circular network.
Definition: VariableNetworkNode.h:250
ChimeraTK::VariableNetworkNode_data::nodeWithTrigger
std::map< VariableNetworkNode, VariableNetworkNode > nodeWithTrigger
Map to store triggered versions of this node.
Definition: VariableNetworkNode.h:244
ChimeraTK::VariableNetworkNode_data::description
std::string description
Description.
Definition: VariableNetworkNode.h:212
ChimeraTK::VariableNetworkNode::getUniqueId
const void * getUniqueId() const
Return the unique ID of this node (will change every time the application is started).
Definition: VariableNetworkNode.h:158
ChimeraTK::VariableNetworkNode::operator<
bool operator<(const VariableNetworkNode &other) const
Definition: VariableNetworkNode.cc:142
ChimeraTK::VariableNetworkNode::getPublicName
const std::string & getPublicName() const
Definition: VariableNetworkNode.cc:231
Model.h
ChimeraTK::VariableNetworkNode_data::direction
VariableDirection direction
Node direction: feeding or consuming.
Definition: VariableNetworkNode.h:201
ChimeraTK::explicitDataValidityTag
constexpr auto explicitDataValidityTag
Special tag to designate that a not should not automatically take over DataValidity of its owning mod...
Definition: VariableNetworkNode.h:184
ChimeraTK::VariableNetworkNode::operator!=
bool operator!=(const VariableNetworkNode &other) const
Definition: VariableNetworkNode.cc:136
ChimeraTK::Visitor< VariableNetworkNode >
ChimeraTK::VariableNetworkNode::addTag
void addTag(const std::string &tag) const
Add a tag.
Definition: VariableNetworkNode.cc:295
ChimeraTK::VariableNetworkNode::setAppAccessorPointer
void setAppAccessorPointer(ChimeraTK::TransferElementAbstractor *accessor) const
Change pointer to the accessor.
Definition: VariableNetworkNode.cc:384
ChimeraTK::VariableNetworkNode::getMode
UpdateMode getMode() const
Definition: VariableNetworkNode.cc:182
ChimeraTK::VariableNetworkNode::getNumberOfElements
size_t getNumberOfElements() const
Definition: VariableNetworkNode.cc:258
ChimeraTK::VariableNetworkNode::setAppAccessorConstImplementation
void setAppAccessorConstImplementation(const VariableNetworkNode &feeder) const
Definition: VariableNetworkNode.cc:427
ChimeraTK::NodeType
NodeType
Enum to define types of VariableNetworkNode.
Definition: Flags.h:36
ChimeraTK::VariableNetworkNode::getNodeToTrigger
VariableNetworkNode getNodeToTrigger() const
Definition: VariableNetworkNode.cc:224
ChimeraTK::VariableNetworkNode::setModel
void setModel(const Model::ProcessVariableProxy &model) const
Definition: VariableNetworkNode.cc:421
ChimeraTK::VariableNetworkNode_data::type
NodeType type
Type of the node (Application, Device, ControlSystem, Trigger)
Definition: VariableNetworkNode.h:195
ChimeraTK::VariableNetworkNode::isCircularInput
bool isCircularInput() const
Returns true if a circular dependency has been detected and the node is a consumer.
Definition: VariableNetworkNode.cc:308
ChimeraTK::Model::NonOwningProxy
Proxy class which does not keep the ownership of the model.
Definition: Model.h:51
ChimeraTK::VariableNetworkNode_data::externalTrigger
VariableNetworkNode externalTrigger
Pointer to the network providing the external trigger.
Definition: VariableNetworkNode.h:223
ChimeraTK::VariableNetworkNode_data::model
Model::NonOwningProxy< Model::ProcessVariableProxy > model
Model representation of this variable.
Definition: VariableNetworkNode.h:253
ChimeraTK::VariableNetworkNode::operator=
VariableNetworkNode & operator=(const VariableNetworkNode &rightHandSide)
Copy by assignment operator: Just copy the pointer to the data storage object.
ChimeraTK::NodeType::Application
@ Application
ChimeraTK::VariableNetworkNode::getName
std::string getName() const
Definition: VariableNetworkNode.cc:200
ChimeraTK::VariableNetworkNode::operator==
bool operator==(const VariableNetworkNode &other) const
Compare two nodes.
Definition: VariableNetworkNode.cc:130
ChimeraTK::VariableNetworkNode::setOwningModule
void setOwningModule(EntityOwner *newOwner) const
Definition: VariableNetworkNode.cc:397
ChimeraTK::VariableNetworkNode::getDirection
VariableDirection getDirection() const
Definition: VariableNetworkNode.cc:188
ConstantAccessor.h
Visitor.h
ChimeraTK::VariableNetworkNode_data::constantValue
userTypeMap constantValue
Value in case of a constant.
Definition: VariableNetworkNode.h:256
ChimeraTK::VariableNetworkNode::setNumberOfElements
void setNumberOfElements(size_t nElements) const
Definition: VariableNetworkNode.cc:252
ChimeraTK::VariableNetworkNode::setValueType
void setValueType(const std::type_info &newType) const
Set the value type for this node.
Definition: VariableNetworkNode.cc:151
ChimeraTK::VariableNetworkNode_data
We use a pimpl pattern so copied instances of VariableNetworkNode refer to the same instance of the d...
Definition: VariableNetworkNode.h:191
ChimeraTK::NodeType::invalid
@ invalid
ChimeraTK
InvalidityTracer application module.
Definition: spec_dataValidityPropagation.dox:2
ChimeraTK::VariableNetworkNode_data::VariableNetworkNode_data
VariableNetworkNode_data()=default
ChimeraTK::VariableNetworkNode::getAppAccessorNoType
ChimeraTK::TransferElementAbstractor & getAppAccessorNoType() const
Definition: VariableNetworkNode.cc:264
ChimeraTK::VariableNetworkNode::setPublicName
void setPublicName(const std::string &name) const
Definition: VariableNetworkNode.cc:403
ChimeraTK::VariableNetworkNode::dump
void dump(std::ostream &stream=std::cout) const
Print node information to specified stream.
Definition: VariableNetworkNode.cc:166
ChimeraTK::Model::ProcessVariableProxy
Definition: Model.h:376
ChimeraTK::VariableNetworkNode_data::registerName
std::string registerName
Definition: VariableNetworkNode.h:234
ChimeraTK::VariableNetworkNode::setMetaData
void setMetaData(const std::string &name, const std::string &unit, const std::string &description) const
Change meta data (name, unit, description and optionally tags).
Definition: VariableNetworkNode.cc:270
ChimeraTK::VariableNetworkNode::scanForCircularDepencency
std::list< EntityOwner * > scanForCircularDepencency() const
Scan the networks and set the isCircularInput() flags if circular dependencies are detected.
Definition: VariableNetworkNode.cc:314