Newer
Older
Martin Christoph Hierholzer
committed
/*
* VariableNetworkNode.cc
*
* Created on: Jun 23, 2016
* Author: Martin Hierholzer
*/
#include "VariableNetworkNode.h"
#include "Application.h"
#include "EntityOwner.h"
#include "VariableNetworkNodeDumpingVisitor.h"
Martin Christoph Hierholzer
committed
namespace ChimeraTK {
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(const VariableNetworkNode& other) : pdata(other.pdata) {}
/*********************************************************************************************************************/
VariableNetworkNode& VariableNetworkNode::operator=(const VariableNetworkNode& rightHandSide) {
pdata = rightHandSide.pdata;
return *this;
}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(EntityOwner* owner, ChimeraTK::TransferElementAbstractor* accessorBridge,
const std::string& name, VariableDirection direction, std::string unit, size_t nElements, UpdateMode mode,
const std::string& description, const std::type_info* valueType, const std::unordered_set<std::string>& tags)
: pdata(boost::make_shared<VariableNetworkNode_data>()) {
pdata->owningModule = owner;
pdata->type = NodeType::Application;
pdata->appNode = accessorBridge;
pdata->name = name;
pdata->qualifiedName = owner->getQualifiedName() + "/" + name;
pdata->mode = mode;
pdata->direction = direction;
pdata->valueType = valueType;
pdata->unit = unit;
pdata->nElements = nElements;
pdata->description = description;
pdata->tags = tags;
}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(const std::string& name, const std::string& devAlias,
const std::string& regName, UpdateMode mode, VariableDirection dir, const std::type_info& valTyp,
size_t nElements)
: pdata(boost::make_shared<VariableNetworkNode_data>()) {
pdata->name = name;
pdata->type = NodeType::Device;
pdata->mode = mode;
pdata->direction = dir;
pdata->valueType = &valTyp;
pdata->deviceAlias = devAlias;
pdata->registerName = regName;
pdata->nElements = nElements;
}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(
std::string pubName, VariableDirection dir, const std::type_info& valTyp, size_t nElements)
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
: pdata(boost::make_shared<VariableNetworkNode_data>()) {
pdata->name = pubName;
pdata->type = NodeType::ControlSystem;
pdata->mode = UpdateMode::push;
pdata->direction = dir;
pdata->valueType = &valTyp;
pdata->publicName = pubName;
pdata->nElements = nElements;
}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(VariableNetworkNode& nodeToTrigger, int)
: pdata(boost::make_shared<VariableNetworkNode_data>()) {
pdata->type = NodeType::TriggerReceiver;
pdata->direction = {VariableDirection::consuming, false};
pdata->nodeToTrigger = nodeToTrigger;
pdata->name = "trigger:" + nodeToTrigger.getName();
}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode(boost::shared_ptr<VariableNetworkNode_data> _pdata) : pdata(_pdata) {}
/*********************************************************************************************************************/
VariableNetworkNode::VariableNetworkNode() : pdata(boost::make_shared<VariableNetworkNode_data>()) {}
/*********************************************************************************************************************/
void VariableNetworkNode::setOwner(VariableNetwork* net) {
assert(pdata->network == nullptr);
assert(pdata->type != NodeType::invalid);
pdata->network = net;
}
/*********************************************************************************************************************/
void VariableNetworkNode::clearOwner() { pdata->network = nullptr; }
/*********************************************************************************************************************/
bool VariableNetworkNode::hasImplementation() const {
return pdata->type == NodeType::Device || pdata->type == NodeType::ControlSystem ||
pdata->type == NodeType::Constant;
}
/*********************************************************************************************************************/
void VariableNetworkNode::accept(Visitor<VariableNetworkNode>& visitor) const { visitor.dispatch(*this); }
/*********************************************************************************************************************/
bool VariableNetworkNode::operator==(const VariableNetworkNode& other) const {
return (other.pdata == pdata) || (pdata->type == NodeType::invalid && other.pdata->type == NodeType::invalid);
}
/*********************************************************************************************************************/
bool VariableNetworkNode::operator!=(const VariableNetworkNode& other) const { return !operator==(other); }
/*********************************************************************************************************************/
bool VariableNetworkNode::operator<(const VariableNetworkNode& other) const {
if(pdata->type == NodeType::invalid && other.pdata->type == NodeType::invalid) return false;
return (other.pdata < pdata);
}
/*********************************************************************************************************************/
VariableNetworkNode VariableNetworkNode::operator>>(VariableNetworkNode other) {
if(pdata->direction.dir == VariableDirection::invalid) {
if(!other.hasOwner()) {
pdata->direction = {VariableDirection::feeding, false};
Martin Christoph Hierholzer
committed
}
else {
if(other.getOwner().hasFeedingNode()) {
pdata->direction = {VariableDirection::consuming, false};
if(getType() == NodeType::Device) { // special treatment for Device-type variables:
// consumers are push-type
pdata->mode = UpdateMode::push;
}
}
else {
pdata->direction = {VariableDirection::feeding, false};
}
}
if(other.pdata->direction.dir == VariableDirection::invalid) {
if(!hasOwner()) {
Martin Christoph Hierholzer
committed
other.pdata->direction = {VariableDirection::consuming, false};
if(other.getType() == NodeType::Device) { // special treatment for Device-type variables:
// consumers are push-type
other.pdata->mode = UpdateMode::push;
}
}
else {
if(getOwner().hasFeedingNode()) {
other.pdata->direction = {VariableDirection::consuming, false};
if(other.getType() == NodeType::Device) { // special treatment for Device-type variables:
// consumers are push-type
other.pdata->mode = UpdateMode::push;
}
}
else {
other.pdata->direction = {VariableDirection::feeding, false};
}
Martin Christoph Hierholzer
committed
}
}
Application::getInstance().connect(*this, other);
return *this;
Martin Christoph Hierholzer
committed
}
/*********************************************************************************************************************/
VariableNetworkNode VariableNetworkNode::operator[](VariableNetworkNode trigger) {
// check if node already has a trigger
if(pdata->externalTrigger.getType() != NodeType::invalid) {
throw ChimeraTK::logic_error("Only one external trigger per variable network is allowed.");
}
// force direction of the node we are operating on to be feeding
if(pdata->direction.dir == VariableDirection::invalid) pdata->direction = {VariableDirection::feeding, false};
assert(pdata->direction.dir == VariableDirection::feeding);
// set direction of the triggering node to be feeding, if not yet defined
if(trigger.pdata->direction.dir == VariableDirection::invalid)
trigger.pdata->direction = {VariableDirection::feeding, false};
// check if already existing in map
if(pdata->nodeWithTrigger.count(trigger) > 0) {
return pdata->nodeWithTrigger[trigger];
}
Martin Christoph Hierholzer
committed
// create copy of the node
pdata->nodeWithTrigger[trigger].pdata = boost::make_shared<VariableNetworkNode_data>(*pdata);
// add ourselves as a trigger receiver to the other network
if(!trigger.hasOwner()) {
Application::getInstance().createNetwork().addNode(trigger);
}
trigger.getOwner().addNodeToTrigger(pdata->nodeWithTrigger[trigger]);
// set flag and store pointer to other network
pdata->nodeWithTrigger[trigger].pdata->externalTrigger = trigger;
Martin Christoph Hierholzer
committed
// return the new node
return pdata->nodeWithTrigger[trigger];
}
/*********************************************************************************************************************/
void VariableNetworkNode::setValueType(const std::type_info& newType) const {
assert(*pdata->valueType == typeid(AnyType));
pdata->valueType = &newType;
}
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
void VariableNetworkNode::setDirection(VariableDirection newDirection) const {
assert(pdata->type == NodeType::ControlSystem);
assert(pdata->direction.dir == VariableDirection::feeding);
pdata->direction = newDirection;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
bool VariableNetworkNode::hasExternalTrigger() const { return pdata->externalTrigger.getType() != NodeType::invalid; }
/*********************************************************************************************************************/
VariableNetworkNode VariableNetworkNode::getExternalTrigger() {
assert(pdata->externalTrigger.getType() != NodeType::invalid);
return pdata->externalTrigger;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
void VariableNetworkNode::dump(std::ostream& stream) const {
VariableNetworkNodeDumpingVisitor visitor(stream, " ");
visitor.dispatch(*this);
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
bool VariableNetworkNode::hasOwner() const { return pdata->network != nullptr; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
NodeType VariableNetworkNode::getType() const {
if(!pdata) return NodeType::invalid;
return pdata->type;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
UpdateMode VariableNetworkNode::getMode() const { return pdata->mode; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
VariableDirection VariableNetworkNode::getDirection() const { return pdata->direction; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::type_info& VariableNetworkNode::getValueType() const { return *(pdata->valueType); }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
std::string VariableNetworkNode::getName() const { return pdata->name; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
std::string VariableNetworkNode::getQualifiedName() const { return pdata->qualifiedName; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::string& VariableNetworkNode::getUnit() const { return pdata->unit; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::string& VariableNetworkNode::getDescription() const { return pdata->description; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
VariableNetwork& VariableNetworkNode::getOwner() const {
assert(pdata->network != nullptr);
return *(pdata->network);
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
VariableNetworkNode VariableNetworkNode::getNodeToTrigger() {
assert(pdata->nodeToTrigger.getType() != NodeType::invalid);
return pdata->nodeToTrigger;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::string& VariableNetworkNode::getPublicName() const {
assert(pdata->type == NodeType::ControlSystem);
return pdata->publicName;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::string& VariableNetworkNode::getDeviceAlias() const {
assert(pdata->type == NodeType::Device);
return pdata->deviceAlias;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
const std::string& VariableNetworkNode::getRegisterName() const {
assert(pdata->type == NodeType::Device);
return pdata->registerName;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
void VariableNetworkNode::setNumberOfElements(size_t nElements) { pdata->nElements = nElements; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
size_t VariableNetworkNode::getNumberOfElements() const { return pdata->nElements; }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
ChimeraTK::TransferElementAbstractor& VariableNetworkNode::getAppAccessorNoType() { return *(pdata->appNode); }
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
Martin Christoph Hierholzer
committed
void VariableNetworkNode::setMetaData(
const std::string& name, const std::string& unit, const std::string& description) {
if(getType() != NodeType::Application) {
throw ChimeraTK::logic_error("Calling VariableNetworkNode::updateMetaData() is not allowed for "
"non-application type nodes.");
}
pdata->name = name;
pdata->qualifiedName = pdata->owningModule->getQualifiedName() + "/" + name;
pdata->unit = unit;
pdata->description = description;
Martin Christoph Hierholzer
committed
}
/*********************************************************************************************************************/
void VariableNetworkNode::setMetaData(const std::string& name, const std::string& unit,
const std::string& description, const std::unordered_set<std::string>& tags) {
setMetaData(name, unit, description);
pdata->tags = tags;
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
void VariableNetworkNode::addTag(const std::string& tag) { pdata->tags.insert(tag); }
/*********************************************************************************************************************/
const std::unordered_set<std::string>& VariableNetworkNode::getTags() const { return pdata->tags; }
/*********************************************************************************************************************/
void VariableNetworkNode::setAppAccessorPointer(ChimeraTK::TransferElementAbstractor* accessor) {
assert(getType() == NodeType::Application);
pdata->appNode = accessor;
}
/*********************************************************************************************************************/
EntityOwner* VariableNetworkNode::getOwningModule() const { return pdata->owningModule; }
/*********************************************************************************************************************/
void VariableNetworkNode::setOwningModule(EntityOwner* newOwner) const { pdata->owningModule = newOwner; }
/*********************************************************************************************************************/
void VariableNetworkNode::setPublicName(const std::string& name) const { pdata->publicName = name; }