Newer
Older
Martin Christoph Hierholzer
committed
/*
* VariableNetwork.h
*
* Created on: Jun 14, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_VARIABLE_NETWORK_H
#define CHIMERATK_VARIABLE_NETWORK_H
#include <boost/mpl/for_each.hpp>
#include <iostream>
Martin Christoph Hierholzer
committed
#include <list>
#include <string>
#include <typeinfo>
#include <ChimeraTK/ControlSystemAdapter/ProcessVariable.h>
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
#include "Flags.h"
Martin Christoph Hierholzer
committed
#include "VariableNetworkNode.h"
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
namespace ChimeraTK {
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
66
67
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
class AccessorBase;
/** This class describes a network of variables all connected to each other. */
class VariableNetwork {
VariableNetwork(const VariableNetwork& other) = delete; // non construction-copyable
VariableNetwork& operator=(const VariableNetwork&) = delete; // non copyable
public:
VariableNetwork() {}
/** Define trigger types. The trigger decides when values are fed into the
* network and distributed to the consumers. */
enum class TriggerType {
feeder, ///< The feeder has an UpdateMode::push and thus decides when new
///< values are fed
pollingConsumer, ///< If there is exacly one consumer with UpdateMode::poll,
///< it will trigger the feeding
external, ///< another variable network can trigger the feeding of this
///< network
none ///< no trigger has yet been selected
};
/** Add an node to the network. The node must not yet be part of any network.
*/
void addNode(VariableNetworkNode& a);
/** Add a trigger receiver node. The node must not yet be part of any network.
*/
void addNodeToTrigger(VariableNetworkNode& nodeToTrigger);
/** Remove a node from the network. The node must be part of the given
* network. */
void removeNode(VariableNetworkNode& a);
/** Remove a trigger receiver node from the network. The node must be part of
* the given network. */
void removeNodeToTrigger(const VariableNetworkNode& nodeToNoLongerTrigger);
/** Check if the network already has a feeding node connected to it. */
bool hasFeedingNode() const;
/** Count the number of consuming nodes in the network */
size_t countConsumingNodes() const;
/** Obtain the type info of the UserType. If the network type has not yet been
* determined (i.e. if no output accessor has been assigned yet), the typeid
* of void will be returned. */
const std::type_info& getValueType() const { return *valueType; }
/** Return the feeding node */
VariableNetworkNode getFeedingNode() const;
/** Return list of consuming nodes */
std::list<VariableNetworkNode> getConsumingNodes() const;
/** Check whether the network has a consuming application node */
bool hasApplicationConsumer() const;
/** Dump the network structure to std::cout. The optional linePrefix will be
* prepended to all lines. */
void dump(const std::string& linePrefix = "", std::ostream& stream = std::cout) const;
void accept(Visitor<VariableNetwork>& visitor) const;
/** Compare two networks */
bool operator==(const VariableNetwork& other) const {
if(other.valueType != valueType) return false;
if(other.nodeList != nodeList) return false;
return true;
}
bool operator!=(const VariableNetwork& other) const { return !operator==(other); }
/** Return the trigger type. This function will also do some checking if the
* network confguration is valid under the aspect of the trigger type. The
* optional argument is only internally used to prevent endless recursive
* calls if getTriggerType() is called inside dump(). */
TriggerType getTriggerType(bool verboseExceptions = true) const;
/** Return the enginerring unit */
const std::string& getUnit() const { return engineeringUnit; }
Martin Christoph Hierholzer
committed
/** Return the description */
const std::string& getDescription() const { return description; }
Martin Christoph Hierholzer
committed
/** Return the network providing the external trigger to this network, if
* TriggerType::external. If the network has another trigger type, an
* exception will be thrown. */
// VariableNetwork& getExternalTrigger();
Martin Christoph Hierholzer
committed
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/** Add an accessor belonging to another node as an external trigger to this
* network. Whenever the VariableNetwork of the given node will be fed with a
* new value, feeding of this network will be triggered as well. */
// void addTrigger(VariableNetworkNode trigger);
/** Check if the network is legally configured */
void check() const;
/** Check the flag if the network connections has been created already */
bool isCreated() const { return flagIsCreated; }
/** Set the flag that the network connections are created */
void markCreated() { flagIsCreated = true; }
/** Assign a ProcessVariable as implementation for the external trigger */
void setExternalTriggerImpl(boost::shared_ptr<ChimeraTK::ProcessVariable> impl) { externalTriggerImpl = impl; }
/** */
boost::shared_ptr<ChimeraTK::ProcessVariable> getExternalTriggerImpl() const { return externalTriggerImpl; }
/** Merge with another VaraibleNetwork. The other network will become invalid
* and gets removed from the
* application. If merging is not possible, false is returned and no change
* is made. */
bool merge(VariableNetwork& other);
protected:
/** List of nodes in the network */
std::list<VariableNetworkNode> nodeList;
/** The network value type id. Since in C++, std::type_info is non-copyable
* and typeid() returns a reference to
* an object with static storage duration, we have to (and can safely) store
* a pointer here. */
const std::type_info* valueType{&typeid(AnyType)};
/** Engineering unit */
std::string engineeringUnit{ChimeraTK::TransferElement::unitNotSet};
/** User-provided description */
std::string description;
/** Flag if an external trigger has been added to this network */
// bool hasExternalTrigger{false};
/** Pointer to the network providing the external trigger */
// VariableNetwork *externalTrigger{nullptr};
/** Pointer to ProcessVariable providing the trigger (if external trigger is
* enabled) */
boost::shared_ptr<ChimeraTK::ProcessVariable> externalTriggerImpl;
/** Flag if the network connections have been created already */
bool flagIsCreated{false};
};
Martin Christoph Hierholzer
committed
} /* namespace ChimeraTK */
#endif /* CHIMERATK_VARIABLE_NETWORK_H */