Newer
Older
Martin Christoph Hierholzer
committed
* ArrayAccessor.h
*
* Created on: Jun 07, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_ARRAY_ACCESSOR_H
#define CHIMERATK_ARRAY_ACCESSOR_H
#include <string>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/thread.hpp>
Martin Christoph Hierholzer
committed
#include <mtca4u/OneDRegisterAccessor.h>
#include "VariableNetworkNode.h"
Martin Christoph Hierholzer
committed
/** Accessor for array variables (i.e. vectors). Note for users: Use the convenience classes
Martin Christoph Hierholzer
committed
* ArrayPollInput, ArrayPushInput, ArrayOutput instead of this class directly. */
Martin Christoph Hierholzer
committed
class ArrayAccessor : public mtca4u::OneDRegisterAccessor<UserType> {
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Change meta data (name, unit, description and optionally tags). This function may only be used on
* Application-type nodes. If the optional argument tags is omitted, the tags will not be changed. To clear the
* tags, an empty set can be passed. */
Martin Christoph Hierholzer
committed
void setMetaData(const std::string &name, const std::string &unit, const std::string &description) {
node.setMetaData(name,unit,description);
}
Martin Christoph Hierholzer
committed
void setMetaData(const std::string &name, const std::string &unit, const std::string &description,
const std::unordered_set<std::string> &tags) {
node.setMetaData(name,unit,description,tags);
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Convert into VariableNetworkNode */
operator VariableNetworkNode() {
return node;
Martin Christoph Hierholzer
committed
/** Connect with other node */
VariableNetworkNode operator>>(const VariableNetworkNode &otherNode) {
return node >> otherNode;
Martin Christoph Hierholzer
committed
/** Replace with other ScalarRegisterAccessor */
void replace(const ArrayAccessor<UserType> &newAccessor) {
Martin Christoph Hierholzer
committed
if(_owner != newAccessor._owner && _owner != nullptr) {
_owner->unregisterAccessor(node);
}
mtca4u::NDRegisterAccessorBridge<UserType>::replace(newAccessor);
node = VariableNetworkNode(this, newAccessor.node.getName(), newAccessor.node.getDirection(), newAccessor.node.getUnit(),
newAccessor.node.getNumberOfElements(), newAccessor.node.getMode(), newAccessor.node.getDescription(),
&newAccessor.node.getValueType());
if(_owner != newAccessor._owner) {
Martin Christoph Hierholzer
committed
_owner = newAccessor._owner;
Martin Christoph Hierholzer
committed
if(_owner != nullptr) _owner->registerAccessor(node);
}
Martin Christoph Hierholzer
committed
}
void replace(const mtca4u::NDRegisterAccessorBridge<UserType> &newAccessor) = delete;
Martin Christoph Hierholzer
committed
/** Move-assignment operator as an alternative for replace where applicable. This is needed to allow late
* initialisation of ApplicationModules using ArrayAccessors */
ArrayAccessor<UserType>& operator=(ArrayAccessor<UserType> &&rhs) {
mtca4u::NDRegisterAccessorBridge<UserType>::replace(rhs);
node.pdata = rhs.node.pdata;
node.pdata->appNode = this;
return *this;
}
Martin Christoph Hierholzer
committed
using mtca4u::OneDRegisterAccessor<UserType>::operator=;
Martin Christoph Hierholzer
committed
~ArrayAccessor() {
Martin Christoph Hierholzer
committed
if(_owner != nullptr) _owner->unregisterAccessor(*this);
Martin Christoph Hierholzer
committed
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Add a tag. Valid names for tags only contain alpha-numeric characters (i.e. no spaces and no special
* characters). */
void addTag(const std::string &tag) {
node.addTag(tag);
}
Martin Christoph Hierholzer
committed
protected:
Martin Christoph Hierholzer
committed
ArrayAccessor(Module *owner, const std::string &name, VariableDirection direction, std::string unit,
Martin Christoph Hierholzer
committed
size_t nElements, UpdateMode mode, const std::string &description,
const std::unordered_set<std::string> &tags={})
: node(this, name, direction, unit, nElements, mode, description, &typeid(UserType), tags), _owner(owner)
Martin Christoph Hierholzer
committed
{
owner->registerAccessor(*this);
}
/** Default constructor creates a dysfunction accessor (to be assigned with a real accessor later) */
ArrayAccessor() {}
Martin Christoph Hierholzer
committed
VariableNetworkNode node;
Martin Christoph Hierholzer
committed
Module *_owner{nullptr};
Martin Christoph Hierholzer
committed
/** Convenience class for input array accessors with UpdateMode::push */
template< typename UserType >
struct ArrayPushInput : public ArrayAccessor<UserType> {
Martin Christoph Hierholzer
committed
ArrayPushInput(Module *owner, const std::string &name, std::string unit, size_t nElements,
const std::string &description, const std::unordered_set<std::string> &tags={})
: ArrayAccessor<UserType>(owner, name, VariableDirection::consuming, unit, nElements, UpdateMode::push,
description, tags)
Martin Christoph Hierholzer
committed
{}
ArrayPushInput() : ArrayAccessor<UserType>() {}
using ArrayAccessor<UserType>::operator=;
};
/** Convenience class for input array accessors with UpdateMode::poll */
template< typename UserType >
struct ArrayPollInput : public ArrayAccessor<UserType> {
Martin Christoph Hierholzer
committed
ArrayPollInput(Module *owner, const std::string &name, std::string unit, size_t nElements,
const std::string &description, const std::unordered_set<std::string> &tags={})
: ArrayAccessor<UserType>(owner, name, VariableDirection::consuming, unit, nElements, UpdateMode::poll,
description, tags)
Martin Christoph Hierholzer
committed
{}
ArrayPollInput() : ArrayAccessor<UserType>() {}
Martin Christoph Hierholzer
committed
void doReadTransfer() override { this->doReadTransferLatest(); }
void read() { this->readLatest(); }
Martin Christoph Hierholzer
committed
using ArrayAccessor<UserType>::operator=;
};
/** Convenience class for output array accessors (always UpdateMode::push) */
template< typename UserType >
struct ArrayOutput : public ArrayAccessor<UserType> {
Martin Christoph Hierholzer
committed
ArrayOutput(Module *owner, const std::string &name, std::string unit, size_t nElements,
const std::string &description, const std::unordered_set<std::string> &tags={})
: ArrayAccessor<UserType>(owner, name, VariableDirection::feeding, unit, nElements, UpdateMode::push,
description, tags)
Martin Christoph Hierholzer
committed
{}
ArrayOutput() : ArrayAccessor<UserType>() {}
using ArrayAccessor<UserType>::operator=;
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_ARRAY_ACCESSOR_H */