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();
61 template<
typename UserType>
67 size_t nElements,
UpdateMode mode,
const std::string& description,
const std::type_info* valueType,
68 const std::unordered_set<std::string>& tags = {});
94 bool _initCalled{
false};
95 bool _deinitCalled{
false};
101 template<
typename Derived>
105 assert(_deinitCalled);
111 template<
typename Derived>
113 const std::optional<std::string>& unit,
const std::optional<std::string>& description,
114 const std::optional<std::unordered_set<std::string>>& tags) {
115 std::optional<std::string> description_ = description;
116 if(description.has_value()) {
117 description_ = completeDescription(getOwner(), description.value());
119 _node.setMetaData(name, unit, description_, tags);
124 template<
typename Derived>
126 for(
const auto& tag : tags) {
133 template<
typename Derived>
135 return _node.getTags();
140 template<
typename Derived>
142 if(
static_cast<Derived*
>(
this)->_impl !=
nullptr || other._impl !=
nullptr) {
144 throw ChimeraTK::logic_error(
145 "Variable has been destroyed with active connections while application is still running");
147 catch(ChimeraTK::logic_error& ex) {
153 if(getOwner() !=
nullptr) {
154 getOwner()->unregisterAccessor(_node);
158 if(getModel().isValid()) {
159 getModel().removeNode(_node);
163 _node = std::move(other._node);
168 _node.setAppAccessorPointer(
static_cast<Derived*
>(
this));
175 _initCalled = other._initCalled;
176 _deinitCalled = other._deinitCalled;
181 template<
typename Derived>
183 EntityOwner* owner,
const std::string& description)
const {
185 if(ownerDescription.empty()) {
188 if(description.empty()) {
189 return ownerDescription;
191 return ownerDescription +
" - " + description;
196 template<
typename Derived>
199 const std::type_info* valueType,
const std::unordered_set<std::string>& tags)
200 : _node(owner, nullptr,
ChimeraTK::Utilities::raiseIftrailingSlash(name, false), direction, unit, nElements, mode,
201 completeDescription(owner, description), valueType, tags) {
202 static_assert(std::is_base_of<InversionOfControlAccessor<Derived>, Derived>::value,
203 "InversionOfControlAccessor<> must be used in a curiously recurring template pattern!");
212 template<
typename Derived>
221 _node.setAppAccessorPointer(
static_cast<Derived*
>(
this));
226 template<
typename Derived>
228 _deinitCalled =
true;
234 if(getOwner() !=
nullptr) {
235 if(
static_cast<Derived*
>(
this)->_impl !=
nullptr) {
236 auto* entity = getOwner();
238 if(entity !=
nullptr) {
239 auto* owner =
dynamic_cast<Module*
>(entity);
240 while(owner->getOwner() !=
nullptr) {
241 owner =
dynamic_cast<Module*
>(owner->getOwner());
244 auto* application =
dynamic_cast<Application*
>(owner);
245 assert(application !=
nullptr);
249 throw ChimeraTK::logic_error(
250 "Variable has been destroyed with active connections while application is "
251 "still running. Maybe the Application did not call shutdown() in its destructor?");
253 catch(ChimeraTK::logic_error&) {
259 getOwner()->unregisterAccessor(_node);
261 if(getModel().isValid()) {
263 getModel().removeNode(_node);
265 catch(ChimeraTK::logic_error& e) {
266 std::cerr <<
"ChimeraTK::logic_error caught: " << e.what() << std::endl;
274 template<
typename Derived>
276 _node.registerInModel();
281 template<
typename Derived>
282 template<
typename UserType>
284 auto& ndra =
dynamic_cast<NDRegisterAccessorAbstractor<UserType>&
>(*this);
287 if(ndra.getVersionNumber() == VersionNumber(
nullptr)) {
294 const auto& targetMetaDataPropagatingDecorator =
298 if(targetMetaDataPropagatingDecorator.getDisableDataValidityPropagation()) {
299 return targetMetaDataPropagatingDecorator.
getTargetValidity() != ndra.dataValidity();
303 if(ndra.dataValidity() == DataValidity::faulty) {
305 return targetMetaDataPropagatingDecorator.getTargetValidity() != DataValidity::faulty;
309 return targetMetaDataPropagatingDecorator.getTargetValidity() != this->getOwner()->getDataValidity();
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 deinit()
Early deinitialisation of stuff we cannot do in our destructor.
void init()
Late initialisation of stuff we cannot do in our constructor.
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.
bool checkMetadataWriteDifference()
Checks whether a writeIfDifferent would have to issue a write, even if the payload data is unchanged.
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.
virtual ~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.