11#include <boost/smart_ptr/shared_ptr.hpp>
22 template<
typename Derived>
33 void setMetaData(
const std::optional<std::string>& name,
const std::optional<std::string>& unit = {},
34 const std::optional<std::string>& description = {},
35 const std::optional<std::unordered_set<std::string>>& tags = {});
43 void addTags(
const std::unordered_set<std::string>& tags);
46 const std::unordered_set<std::string>&
getTags();
63 size_t nElements,
UpdateMode mode,
const std::string& description,
const std::type_info* valueType,
64 const std::unordered_set<std::string>& tags = {});
81 template<
typename Derived>
83 if(getOwner() !=
nullptr) {
84 if(
static_cast<Derived*
>(
this)->_impl !=
nullptr) {
85 auto* entity = getOwner();
87 if(entity !=
nullptr) {
88 auto* owner =
dynamic_cast<Module*
>(entity);
89 while(owner->getOwner() !=
nullptr) {
90 owner =
dynamic_cast<Module*
>(owner->getOwner());
93 auto* application =
dynamic_cast<Application*
>(owner);
94 assert(application !=
nullptr);
98 throw ChimeraTK::logic_error(
99 "Variable has been destroyed with active connections while application is "
100 "still running. Maybe the Application did not call shutdown() in its destructor?");
102 catch(ChimeraTK::logic_error&) {
108 getOwner()->unregisterAccessor(_node);
110 if(getModel().isValid()) {
112 getModel().removeNode(_node);
114 catch(ChimeraTK::logic_error& e) {
115 std::cerr <<
"ChimeraTK::logic_error caught: " << e.what() << std::endl;
123 template<
typename Derived>
125 const std::optional<std::string>& unit,
const std::optional<std::string>& description,
126 const std::optional<std::unordered_set<std::string>>& tags) {
127 std::optional<std::string> description_ = description;
128 if(description.has_value()) {
129 description_ = completeDescription(getOwner(), description.value());
131 _node.setMetaData(name, unit, description_, tags);
136 template<
typename Derived>
138 for(
const auto& tag : tags) {
145 template<
typename Derived>
147 return _node.getTags();
152 template<
typename Derived>
154 if(
static_cast<Derived*
>(
this)->_impl !=
nullptr || other._impl !=
nullptr) {
156 throw ChimeraTK::logic_error(
157 "Variable has been destroyed with active connections while application is still running");
159 catch(ChimeraTK::logic_error& ex) {
165 if(getOwner() !=
nullptr) {
166 getOwner()->unregisterAccessor(_node);
170 if(getModel().isValid()) {
171 getModel().removeNode(_node);
175 _node = std::move(other._node);
180 _node.setAppAccessorPointer(
static_cast<Derived*
>(
this));
190 template<
typename Derived>
192 EntityOwner* owner,
const std::string& description)
const {
194 if(ownerDescription.empty()) {
197 if(description.empty()) {
198 return ownerDescription;
200 return ownerDescription +
" - " + description;
205 template<
typename Derived>
208 const std::type_info* valueType,
const std::unordered_set<std::string>& tags)
209 : _node(owner, static_cast<Derived*>(this),
ChimeraTK::Utilities::raiseIftrailingSlash(name, false), direction, unit,
210 nElements, mode, completeDescription(owner, description), valueType, tags) {
211 static_assert(std::is_base_of<InversionOfControlAccessor<Derived>, Derived>::value,
212 "InversionOfControlAccessor<> must be used in a curiously recurring template pattern!");
221 template<
typename Derived>
223 _node.registerInModel();
Base class for owners of other EntityOwners (e.g.
void registerAccessor(VariableNetworkNode accessor)
Called inside the constructor of Accessor: adds the accessor to the list.
virtual std::string getFullDescription() const =0
Obtain the full description including the full description of the owner.
Adds features required for inversion of control to an accessor.
void setMetaData(const std::optional< std::string > &name, const std::optional< std::string > &unit={}, const std::optional< std::string > &description={}, const std::optional< std::unordered_set< std::string > > &tags={})
Change meta data (name, unit, description and optionally tags).
VariableNetworkNode _node
void replace(Derived &&other)
Replace with other accessor.
EntityOwner * getOwner() const
Return the owning module.
std::string completeDescription(EntityOwner *owner, const std::string &description) const
complete the description with the full description from the owner
void addTags(const std::unordered_set< std::string > &tags)
Add multiple tags.
const std::unordered_set< std::string > & getTags()
Return set of tags.
void registerInModel()
Register the variable in the model.
InversionOfControlAccessor()=default
Default constructor creates a dysfunctional accessor (to be assigned with a real accessor later)
InversionOfControlAccessor(Module *owner, const std::string &name, VariableDirection direction, std::string unit, size_t nElements, UpdateMode mode, const std::string &description, const std::type_info *valueType, const std::unordered_set< std::string > &tags={})
Constructor, only used by child class accessors.
~InversionOfControlAccessor()
Unregister at its owner when deleting.
void addTag(const std::string &tag)
Add a tag.
Model::ProcessVariableProxy getModel() const
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Class describing a node of a variable network.
Model::ProcessVariableProxy getModel() const
void addTag(const std::string &tag) const
Add a tag.
EntityOwner * getOwningModule() const
InvalidityTracer application module.
@ run
Actual run phase with full multi threading.
UpdateMode
Enum to define the update mode of variables.
Struct to define the direction of variables.