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 <list>
#include <string>
Martin Christoph Hierholzer
committed
#include <iostream>
Martin Christoph Hierholzer
committed
#include <typeinfo>
#include <boost/mpl/for_each.hpp>
Martin Christoph Hierholzer
committed
#include <ControlSystemAdapter/ProcessVariable.h>
Martin Christoph Hierholzer
committed
#include "Flags.h"
Martin Christoph Hierholzer
committed
#include "VariableNetworkNode.h"
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
namespace ChimeraTK {
class AccessorBase;
/** This class describes a network of variables all connected to each other. */
class VariableNetwork {
Martin Christoph Hierholzer
committed
VariableNetwork( const VariableNetwork& other ) = delete; // non construction-copyable
VariableNetwork& operator=( const VariableNetwork& ) = delete; // non copyable
Martin Christoph Hierholzer
committed
public:
Martin Christoph Hierholzer
committed
VariableNetwork() {}
Martin Christoph Hierholzer
committed
/** 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
Martin Christoph Hierholzer
committed
};
Martin Christoph Hierholzer
committed
/** Add an application-side node (i.e. an Accessor) to the network. */
void addAppNode(AccessorBase &a);
Martin Christoph Hierholzer
committed
/** Add control-system-to-device publication. The given accessor will be used to derive the requred value type.
* The name will be the name of the process variable visible in the control system adapter. */
Martin Christoph Hierholzer
committed
void addFeedingPublication(AccessorBase &a, const std::string& name);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add control-system-to-device publication. The given accessor will be used to derive the requred value type.
* The name will be the name of the process variable visible in the control system adapter. */
Martin Christoph Hierholzer
committed
void addFeedingPublication(const std::type_info &typeInfo, const std::string& unit, const std::string& name);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add device-to-control-system publication. */
Martin Christoph Hierholzer
committed
void addConsumingPublication(const std::string& name);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add a device register as a consuming node (i.e. which will be written by this network) */
Martin Christoph Hierholzer
committed
void addConsumingDeviceRegister(const std::string &deviceAlias, const std::string ®isterName);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add a device register as a feeding node (i.e. which will be read from this network) */
void addFeedingDeviceRegister(AccessorBase &a, const std::string &deviceAlias, const std::string ®isterName,
Martin Christoph Hierholzer
committed
UpdateMode mode);
/** Add a device register as a feeding node (i.e. which will be read from this network) */
Martin Christoph Hierholzer
committed
void addFeedingDeviceRegister(const std::type_info &typeInfo, const std::string& unit,
const std::string &deviceAlias, const std::string ®isterName, UpdateMode mode);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add a trigger receiver node */
void addTriggerReceiver(VariableNetwork *network);
Martin Christoph Hierholzer
committed
/** Check if the network already has a feeding node connected to it. */
bool hasFeedingNode() const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Count the number of consuming nodes in the network */
size_t countConsumingNodes() const;
/** Count the number of nodes requiring a fixed implementation */
size_t countFixedImplementations() const;
Martin Christoph Hierholzer
committed
/** Check if either of the given accessors is part of this network. If the second argument is omitted, only
* the first accessor will be checked. */
Martin Christoph Hierholzer
committed
bool hasAppNode(AccessorBase *a, AccessorBase *b=nullptr) const;
Martin Christoph Hierholzer
committed
/** 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;
}
Martin Christoph Hierholzer
committed
/** Return the feeding node */
Martin Christoph Hierholzer
committed
const VariableNetworkNode& getFeedingNode() const { return feeder; }
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Return list of consuming nodes */
Martin Christoph Hierholzer
committed
const std::list<VariableNetworkNode>& getConsumingNodes() const { return consumerList; }
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Dump the network structure to std::cout. The optional linePrefix will be prepended to all lines. */
void dump(const std::string& linePrefix="") const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Compare two networks */
bool operator==(const VariableNetwork &other) const {
if(other.feeder != feeder) return false;
if(other.valueType != valueType) return false;
if(other.consumerList != consumerList) return false;
return true;
}
bool operator!=(const VariableNetwork &other) const {
return !operator==(other);
}
Martin Christoph Hierholzer
committed
/** Return the trigger type. This function will also do some checking if the network confguration is valid under
* the aspect of the trigger type. */
Martin Christoph Hierholzer
committed
TriggerType getTriggerType() const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Return the enginerring unit */
const std::string& getUnit() { return engineeringUnit; }
Martin Christoph Hierholzer
committed
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
/** 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();
/** Add an accessor belonging to another network as an external trigger to this network. Whenever the
* VariableNetwork of the given accessor will be fed with a new value, feeding of this network will be
* triggered as well. */
void addTrigger(AccessorBase &trigger);
/** Check if the network is legally configured */
void check();
/** 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< mtca4u::ProcessVariable > impl) {
externalTriggerImpl = impl;
}
/** */
boost::shared_ptr< mtca4u::ProcessVariable > getExternalTriggerImpl() const {
return externalTriggerImpl;
}
Martin Christoph Hierholzer
committed
protected:
Martin Christoph Hierholzer
committed
/** Feeding node (i.e. the node providing values to the network) */
Martin Christoph Hierholzer
committed
VariableNetworkNode feeder;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** List of consuming nodes (i.e. the nodes receiving values from the network) */
Martin Christoph Hierholzer
committed
std::list<VariableNetworkNode> consumerList;
Martin Christoph Hierholzer
committed
/** 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(void)};
Martin Christoph Hierholzer
committed
/** Engineering unit */
std::string engineeringUnit;
Martin Christoph Hierholzer
committed
/** 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< mtca4u::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 */