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>
#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 {
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 node to the network. */
void addNode(VariableNetworkNode &a);
Martin Christoph Hierholzer
committed
/** Add a trigger receiver node */
void addNodeToTrigger(VariableNetworkNode& nodeToTrigger);
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Remove a node from the network */
void removeNode(const VariableNetworkNode &a);
/** Remove a trigger receiver node from the network */
void removeNodeToTrigger(const VariableNetworkNode &nodeToNoLongerTrigger);
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;
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
VariableNetworkNode getFeedingNode() const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Return list of consuming nodes */
Martin Christoph Hierholzer
committed
std::list<VariableNetworkNode> getConsumingNodes() const;
/** Check whether the network has a consuming application node */
bool hasApplicationConsumer() const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Dump the network structure to std::cout. The optional linePrefix will be prepended to all lines. */
Martin Christoph Hierholzer
committed
void dump(const std::string& linePrefix="", std::ostream& stream=std::cout) const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Compare two networks */
bool operator==(const VariableNetwork &other) const {
if(other.valueType != valueType) return false;
Martin Christoph Hierholzer
committed
if(other.nodeList != nodeList) return false;
Martin Christoph Hierholzer
committed
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.
* The optional argument is only internally used to prevent endless recursive calls if getTriggerType() is
* called inside dump(). */
TriggerType getTriggerType(bool verboseExceptions=true) const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Return the enginerring unit */
const std::string& getUnit() const { return engineeringUnit; }
/** Return the description */
const std::string& getDescription() const { return description; }
Martin Christoph Hierholzer
committed
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
/** 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
Martin Christoph Hierholzer
committed
* triggered as well. */
//void addTrigger(VariableNetworkNode trigger);
Martin Christoph Hierholzer
committed
/** 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< ChimeraTK::ProcessVariable > impl) {
Martin Christoph Hierholzer
committed
externalTriggerImpl = impl;
}
/** */
boost::shared_ptr< ChimeraTK::ProcessVariable > getExternalTriggerImpl() const {
Martin Christoph Hierholzer
committed
return externalTriggerImpl;
}
Martin Christoph Hierholzer
committed
protected:
Martin Christoph Hierholzer
committed
/** List of nodes in the network */
std::list<VariableNetworkNode> nodeList;
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. */
Martin Christoph Hierholzer
committed
const std::type_info* valueType{&typeid(AnyType)};
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Engineering unit */
Martin Christoph Hierholzer
committed
std::string engineeringUnit{mtca4u::TransferElement::unitNotSet};
Martin Christoph Hierholzer
committed
/** User-provided description */
std::string description;
Martin Christoph Hierholzer
committed
/** Flag if an external trigger has been added to this network */
//bool hasExternalTrigger{false};
Martin Christoph Hierholzer
committed
/** Pointer to the network providing the external trigger */
//VariableNetwork *externalTrigger{nullptr};
Martin Christoph Hierholzer
committed
/** Pointer to ProcessVariable providing the trigger (if external trigger is enabled) */
boost::shared_ptr< ChimeraTK::ProcessVariable > externalTriggerImpl;
Martin Christoph Hierholzer
committed
/** Flag if the network connections have been created already */
bool flagIsCreated{false};
Martin Christoph Hierholzer
committed
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_VARIABLE_NETWORK_H */