13#include <boost/container_hash/hash.hpp>
31 const std::string& description,
const std::type_info* valueType,
const std::unordered_set<std::string>& tags)
33 pdata->owningModule = owner;
35 pdata->appNode = accessorBridge;
39 pdata->direction = direction;
40 pdata->valueType = valueType;
41 pdata->unit = std::move(unit);
42 pdata->nElements = nElements;
43 pdata->description = description;
56 pdata->direction = dir;
57 pdata->valueType = &valTyp;
58 pdata->deviceAlias = devAlias;
59 pdata->registerName = regName;
60 pdata->nElements = nElements;
67 const std::string& pubName,
VariableDirection dir,
const std::type_info& valTyp,
size_t nElements)
69 pdata->name = pubName;
72 pdata->direction = dir;
73 pdata->valueType = &valTyp;
74 pdata->publicName = pubName;
75 pdata->nElements = nElements;
85 pdata->deviceAlias = deviceAliasOrCdd;
92 pdata = boost::make_shared<VariableNetworkNode_data>();
94 pdata->valueType = valTyp;
95 pdata->nElements = length;
96 pdata->name =
"*UNNAMED CONSTANT*";
110 : pdata(std::move(_pdata)) {}
126 visitor.dispatch(*
this);
154 pdata->valueType = &newType;
162 pdata->direction = newDirection;
190 return pdata->direction;
196 return *(
pdata->valueType);
208 return pdata->qualifiedName;
220 return pdata->description;
227 return pdata->nodeToTrigger;
234 return pdata->publicName;
241 return pdata->deviceAlias;
248 return pdata->registerName;
254 pdata->nElements = nElements;
260 return pdata->nElements;
266 return pdata->isReadable;
272 return *(
pdata->appNode);
278 const std::optional<std::string>& description,
const std::optional<std::unordered_set<std::string>>& tags) {
280 throw ChimeraTK::logic_error(
"Calling VariableNetworkNode::updateMetaData() is not allowed for "
281 "non-application type nodes.");
286 if(needModelUpdate) {
290 if(name.has_value()) {
291 pdata->name = name.value();
292 pdata->qualifiedName =
pdata->owningModule->getQualifiedName() +
"/" + name.value();
294 if(unit.has_value()) {
295 pdata->unit = unit.value();
297 if(description.has_value()) {
298 pdata->description = description.value();
300 if(tags.has_value()) {
301 pdata->tags = tags.value();
304 if(needModelUpdate) {
314 pdata->tags.insert(tag);
316 auto model =
pdata->model.lock();
317 if(model.isValid()) {
325 return pdata->circularNetworkHash != 0;
332 detail::CircularDependencyDetectionRecursionStopper::startNewScan();
345 auto amProxy =
getModel().
visit(Model::returnApplicationModule, Model::keepPvAccess, Model::keepApplicationModules,
349 if(!amProxy.isValid()) {
354 Module* owningModule = &amProxy.getApplicationModule();
361 auto nInstancesFound = std::count(inputModuleList.begin(), inputModuleList.end(), owningModule);
362 assert(nInstancesFound >= 1);
364 if(nInstancesFound > 1) {
366 inputModuleList.sort();
367 inputModuleList.unique();
370 pdata->circularNetworkHash = boost::hash_range(inputModuleList.begin(), inputModuleList.end());
378 for(
auto& elem : internalTargetElements) {
379 auto flagProvider = boost::dynamic_pointer_cast<MetaDataPropagationFlagProvider>(elem);
381 flagProvider->_isCircularInput =
true;
385 return inputModuleList;
402 pdata->appNode = accessor;
408 return pdata->owningModule;
414 pdata->owningModule = newOwner;
420 pdata->publicName = name;
426 return pdata->circularNetworkHash;
432 return pdata->model.lock();
438 pdata->model = model;
445 using UserType =
decltype(t);
446 auto impl = boost::dynamic_pointer_cast<ChimeraTK::NDRegisterAccessor<UserType>>(
452 impl, detail::TestableMode::DecoratorType::READ,
"Constant"));
455 setAppAccessorImplementation<UserType>(impl);
467 auto addToOnwer = [&](
auto& owner_casted) {
468 auto model = owner_casted.getModel();
469 if(!model.isValid()) {
473 auto neighbourDir = model.visit(
479 model.addVariable(var, *
this);
486 addToOnwer(*owner_am);
489 addToOnwer(*owner_vg);
492 throw ChimeraTK::logic_error(
"Trying to add " + name +
" to " + owner->getQualifiedName() +
493 " which is neither an ApplicationModule nor a VariableGroup, but a " +
494 boost::core::demangled_name(
typeid(owner)));
Pseudo type to identify nodes which can have arbitrary types.
static Application & getInstance()
Obtain instance of the application.
void setCircularNetworkHash(size_t circularNetworkHash)
Set the ID of the circular dependency network.
Base class for owners of other EntityOwners (e.g.
virtual std::string getQualifiedName() const =0
Get the fully qualified name of the module instance, i.e.
void removeNode(const VariableNetworkNode &node)
Remove VariableNetworkNode from the list of nodes. Note: Will invalidate return value of getNodes()!
bool isValid() const
Check if the model is valid.
auto visit(VISITOR visitor, Args... args) const
Traverse the model using the specified filter and call the visitor functor for each ModuleGroup,...
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
std::list< EntityOwner * > getInputModulesRecursively(std::list< EntityOwner * > startList) override
Use pointer to the module as unique identifier.
The VariableNetworkNodeDumpingVisitor class.
void dispatch(const VariableNetworkNode &t) override
dispatch
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.
const std::string & getRegisterName() const
const std::unordered_set< std::string > & getTags() const
Model::ProcessVariableProxy getModel() const
std::string getQualifiedName() const
std::string getName() 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
size_t getNumberOfElements() 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.
UpdateMode getMode() const
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
VariableDirection getDirection() const
void setAppAccessorConstImplementation(const VariableNetworkNode &feeder) 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
EntityOwner * getOwningModule() const
const std::string & getDeviceAlias() const
const std::string & getUnit() const
UserType getConstantValue() 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).
constexpr ReturnFirstHitWithValue< void > returnFirstHit()
Stop the search after the first hit and return.
std::string getPathName(const std::string &qualifiedName)
Return all but the last components of the given qualified name.
std::string getUnqualifiedName(const std::string &qualifiedName)
Return the last component of the given qualified path name.
InvalidityTracer application module.
std::string negateTag(const std::string &tag)
negate tag using prefix '!'
UpdateMode
Enum to define the update mode of variables.
NodeType
Enum to define types of VariableNetworkNode.
Struct to define the direction of variables.
We use a pimpl pattern so copied instances of VariableNetworkNode refer to the same instance of the d...