Newer
Older
Martin Christoph Hierholzer
committed
/*
* VariableNetworkNode.h
*
* Created on: Jun 23, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_VARIABLE_NETWORK_NODE_H
#define CHIMERATK_VARIABLE_NETWORK_NODE_H
Martin Christoph Hierholzer
committed
#include <assert.h>
Martin Christoph Hierholzer
committed
#include <boost/shared_ptr.hpp>
Martin Christoph Hierholzer
committed
#include "Flags.h"
namespace xmlpp {
class Element;
}
namespace ChimeraTK {
class VariableNetwork;
class AccessorBase;
Martin Christoph Hierholzer
committed
/** Pseudo type to identify nodes which can have arbitrary types */
class AnyType {};
Martin Christoph Hierholzer
committed
/** Class describing a node of a variable network */
class VariableNetworkNode {
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
public:
Martin Christoph Hierholzer
committed
/** Copy-constructor: Just copy the pointer to the data storage object */
VariableNetworkNode(const VariableNetworkNode &other);
/** Copy by assignment operator: Just copy the pointer to the data storage object */
VariableNetworkNode& operator=(const VariableNetworkNode &rightHandSide);
Martin Christoph Hierholzer
committed
/** Constructor for an Application node */
VariableNetworkNode(AccessorBase &accessor);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Constructor for a Device node */
Martin Christoph Hierholzer
committed
VariableNetworkNode(const std::string &deviceAlias, const std::string ®isterName, UpdateMode mode,
Martin Christoph Hierholzer
committed
VariableDirection direction, const std::type_info &valTyp=typeid(AnyType), size_t nElements=0);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Constructor for a ControlSystem node */
Martin Christoph Hierholzer
committed
VariableNetworkNode(std::string publicName, VariableDirection direction,
Martin Christoph Hierholzer
committed
const std::type_info &valTyp=typeid(AnyType), size_t nElements=0);
Martin Christoph Hierholzer
committed
/** Constructor for a TriggerReceiver node triggering the data transfer of another network. The additional dummy
* argument is only there to discriminate the signature from the copy constructor and will be ignored. */
VariableNetworkNode(VariableNetworkNode& nodeToTrigger, int);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Default constructor for an invalid node */
Martin Christoph Hierholzer
committed
VariableNetworkNode() : pdata(new data) {}
Martin Christoph Hierholzer
committed
/** Set the owner network of this node. If an owner network is already set, an assertion will be raised */
void setOwner(VariableNetwork *network);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Set the value type for this node. Only possible of the current value type is undecided (i.e. AnyType). */
void setValueType(const std::type_info& newType) const {
assert(*pdata->valueType == typeid(AnyType));
pdata->valueType = &newType;
}
Martin Christoph Hierholzer
committed
/** Function checking if the node requires a fixed implementation */
bool hasImplementation() const;
/** Compare two nodes */
bool operator==(const VariableNetworkNode& other) const;
bool operator!=(const VariableNetworkNode& other) const;
Martin Christoph Hierholzer
committed
/** Connect two nodes */
// VariableNetworkNode& operator<<(const VariableNetworkNode &other);
VariableNetworkNode operator>>(VariableNetworkNode other);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add a trigger */
VariableNetworkNode operator[](VariableNetworkNode trigger);
/** Check for presence of an external trigger */
bool hasExternalTrigger() const { return pdata->externalTrigger != nullptr; }
/** Return the external trigger node. if no external trigger is present, an assertion will be raised. */
VariableNetworkNode& getExternalTrigger() const { assert(pdata->externalTrigger != nullptr); return *(pdata->externalTrigger); }
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Print node information to std::cout */
void dump() const;
/** Create an XML node describing this network node as seen by the control syste. If the type is not
* NodeType::ControlSystem, this function does nothing. Otherwise the correct directory hierarchy will be
* created (if not yet existing) and a variable tag will be created containing the externally visible
* properties of this variable. */
void createXML(xmlpp::Element *rootElement) const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Check if the node already has an owner */
Martin Christoph Hierholzer
committed
bool hasOwner() const { return pdata->network != nullptr; }
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Getter for the properties */
Martin Christoph Hierholzer
committed
NodeType getType() const { return pdata->type; }
UpdateMode getMode() const { return pdata->mode; }
VariableDirection getDirection() const { return pdata->direction; }
const std::type_info& getValueType() const { return *(pdata->valueType); }
const std::string& getUnit() const { return pdata->unit; }
const std::string& getDescription() const { return pdata->description; }
Martin Christoph Hierholzer
committed
VariableNetwork& getOwner() const { assert(pdata->network != nullptr); return *(pdata->network); }
AccessorBase& getAppAccessor() const { assert(pdata->appNode != nullptr); return *(pdata->appNode); }
VariableNetworkNode& getTriggerReceiver() const { assert(pdata->triggerReceiver != nullptr); return *(pdata->triggerReceiver); }
Martin Christoph Hierholzer
committed
const std::string& getPublicName() const { assert(pdata->type == NodeType::ControlSystem); return pdata->publicName; }
const std::string& getDeviceAlias() const { assert(pdata->type == NodeType::Device); return pdata->deviceAlias; }
const std::string& getRegisterName() const { assert(pdata->type == NodeType::Device); return pdata->registerName; }
void setNumberOfElements(size_t nElements) { pdata->nElements = nElements; }
size_t getNumberOfElements() const { return pdata->nElements; }
Martin Christoph Hierholzer
committed
protected:
/** We use a pimpl pattern so copied instances of VariableNetworkNode refer to the same instance of the data
* structure and thus stay consistent all the time. */
Martin Christoph Hierholzer
committed
struct data {
Martin Christoph Hierholzer
committed
data() {}
Martin Christoph Hierholzer
committed
/** Type of the node (Application, Device, ControlSystem, Trigger) */
NodeType type{NodeType::invalid};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Update mode: poll or push */
UpdateMode mode{UpdateMode::invalid};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Node direction: feeding or consuming */
VariableDirection direction{VariableDirection::invalid};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Value type of this node. If the type_info is the typeid of AnyType, the actual type can be decided when making
* the connections. */
const std::type_info* valueType{&typeid(AnyType)};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Engineering unit. If "arbitrary", no unit has been defined (and any unit is allowed). */
std::string unit{"arbitrary"};
Martin Christoph Hierholzer
committed
/** Description */
std::string description{""};
Martin Christoph Hierholzer
committed
/** The network this node belongs to */
VariableNetwork *network{nullptr};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Pointer to Accessor if type == Application */
AccessorBase *appNode{nullptr};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Pointer to network which should be triggered by this node */
VariableNetworkNode *triggerReceiver{nullptr};
/** Pointer to the network providing the external trigger. May only be used for feeding nodes with an
* update mode poll. When enabled, the update mode will be converted into push. */
VariableNetworkNode *externalTrigger{nullptr};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Public name if type == ControlSystem */
std::string publicName;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Device information if type == Device */
std::string deviceAlias;
std::string registerName;
/** Number of elements in the variable. 0 means not yet decided. */
size_t nElements{0};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
boost::shared_ptr<data> pdata;
Martin Christoph Hierholzer
committed
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_VARIABLE_NETWORK_NODE_H */