Newer
Older
Martin Christoph Hierholzer
committed
/*
* EntityOwner.h
*
* Created on: Nov 15, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_ENTITY_OWNER_H
#define CHIMERATK_ENTITY_OWNER_H
#include <string>
#include <list>
Martin Christoph Hierholzer
committed
#include "VariableNetworkNode.h"
Martin Christoph Hierholzer
committed
namespace ChimeraTK {
class AccessorBase;
class Module;
Martin Christoph Hierholzer
committed
class VirtualModule;
Martin Christoph Hierholzer
committed
/** Base class for owners of other EntityOwners (e.g. Modules) and Accessors.
* @todo Rename this class to "Owner" and make it more generic. It should basically just implement the
* "Composite Pattern". The classes AccessorBase, Module and Owner should have a common base class called
* "Component".
*/
Martin Christoph Hierholzer
committed
class EntityOwner {
public:
/** Constructor: register the EntityOwner with its owner */
EntityOwner(EntityOwner *owner, const std::string &name, const std::string &description,
bool eliminateHierarchy=false, const std::unordered_set<std::string> &tags={});
Martin Christoph Hierholzer
committed
/** Virtual destructor to make the type polymorphic */
Martin Christoph Hierholzer
committed
virtual ~EntityOwner();
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Get the name of the module instance */
const std::string& getName() const { return _name; }
Martin Christoph Hierholzer
committed
/** Get the fully qualified name of the module instance, i.e. the name containing all module names further up in
* the hierarchy. */
std::string getQualifiedName() const {
return ( _owner != nullptr ? _owner->getQualifiedName() : "" ) + "/" + _name;
}
Martin Christoph Hierholzer
committed
/** Get the decription of the module instance */
const std::string& getDescription() const { return _description; }
Martin Christoph Hierholzer
committed
/** Obtain the list of accessors/variables directly associated with this instance */
Martin Christoph Hierholzer
committed
std::list<VariableNetworkNode>& getAccessorList() { return accessorList; }
Martin Christoph Hierholzer
committed
const std::list<VariableNetworkNode>& getAccessorList() const { return accessorList; }
Martin Christoph Hierholzer
committed
/** Obtain the list of submodules associated with this instance */
Martin Christoph Hierholzer
committed
const std::list<Module*>& getSubmoduleList() const { return moduleList; }
Martin Christoph Hierholzer
committed
/** Obtain the list of accessors/variables associated with this instance and any variable groups. If the optional
* argument is set to true, also submodules (which have their own thread) are included. In that case, the
* accessors in the returned list may not be used (i.e. write or read data or initiate transfers) from the same
* thread and only connections may be registered between the accessors. */
std::list<VariableNetworkNode> getAccessorListRecursive(bool includeSubmodules = false);
Martin Christoph Hierholzer
committed
/** Obtain the list of submodules associated with this instance and any submodules */
std::list<Module*> getSubmoduleListRecursive();
Martin Christoph Hierholzer
committed
/** Return a VirtualModule containing the part of the tree structure matching the given tag. The resulting
* VirtualModule might have virtual sub-modules, if this EntityOwner contains sub-EntityOwners with
* entities matchting the tag. */
VirtualModule findTag(const std::string &tag, bool eliminateAllHierarchies=false) const;
/** Add the part of the tree structure matching the given tag to a VirtualModule. Users normally will use
* findTag() instead. */
void findTagAndAppendToModule(VirtualModule &module, const std::string &tag, bool eliminateAllHierarchies=false,
bool eliminateFirstHierarchy=false) const;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
/** Called inside the constructor of Accessor: adds the accessor to the list */
Martin Christoph Hierholzer
committed
void registerAccessor(VariableNetworkNode accessor) {
for(auto &tag : _tags) accessor.addTag(tag);
Martin Christoph Hierholzer
committed
accessorList.push_back(accessor);
}
Martin Christoph Hierholzer
committed
/** Called inside the destructor of Accessor: removes the accessor from the list */
Martin Christoph Hierholzer
committed
void unregisterAccessor(VariableNetworkNode accessor) {
Martin Christoph Hierholzer
committed
accessorList.remove(accessor);
}
Martin Christoph Hierholzer
committed
/** Register another module as a sub-mdoule. Will be called automatically by all modules in their constructors. */
void registerModule(Module* module);
Martin Christoph Hierholzer
committed
/** Unregister another module as a sub-mdoule. Will be called automatically by all modules in their destructors. */
void unregisterModule(Module* module);
/** Add a tag to all Application-type nodes inside this group. It will recurse into any subgroups. See
* VariableNetworkNode::addTag() for additional information about tags. */
void addTag(const std::string &tag);
Martin Christoph Hierholzer
committed
/** Eliminate the level of hierarchy represented by this EntityOwner. This is e.g. used when building the
* hierarchy of VirtualModules in findTag(). Eliminating one level of hierarchy will make all childs of that
* hierarchy level to appear as if there were direct childs of the next higher hierarchy level. If e.g. there is
* a variable on the third level "A.B.C" and one selects to eliminate the second level of hierarchy (e.g. calls
* B.eliminateHierarchy()), the structure would look like "A.C". This of course only affects the "dynamic" data
* model, while the static C++ model is fixed at compile time.
* @todo Also use in VariableGroup::operator() and VariableGroup::operator[] ??? */
Martin Christoph Hierholzer
committed
void setEliminateHierarchy() { _eliminateHierarchy = true; }
Martin Christoph Hierholzer
committed
/** Returns the flag whether this level of hierarchy should be eliminated */
bool getEliminateHierarchy() const { return _eliminateHierarchy; }
Martin Christoph Hierholzer
committed
/** Create a VirtualModule which contains all variables of this EntityOwner in a flat hierarchy. It will recurse
* through all sub-modules and add all found variables directly to the VirtualModule. */
VirtualModule flatten();
Martin Christoph Hierholzer
committed
/** Print the full hierarchy to stdout. */
void dump(const std::string &prefix="") const;
Martin Christoph Hierholzer
committed
protected:
/** The name of this instance */
std::string _name;
/** The description of this instance */
std::string _description;
Martin Christoph Hierholzer
committed
/** Owner of this instance */
EntityOwner *_owner{nullptr};
/** List of accessors owned by this instance */
Martin Christoph Hierholzer
committed
std::list<VariableNetworkNode> accessorList;
Martin Christoph Hierholzer
committed
/** List of modules owned by this instance */
std::list<Module*> moduleList;
Martin Christoph Hierholzer
committed
/** Flag whether this level of hierarchy should be eliminated or not */
bool _eliminateHierarchy{false};
/** List of tags to be added to all accessors and modules inside this module */
std::unordered_set<std::string> _tags;
Martin Christoph Hierholzer
committed
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_ENTITY_OWNER_H */