Newer
Older
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once
#include "Application.h"
#include "InversionOfControlAccessor.h"
#include <ChimeraTK/VoidRegisterAccessor.h>
#include <string>
namespace ChimeraTK {
/********************************************************************************************************************/
/** Accessor for void variables (i.e. no data, just the "trigger" information). Note for users: Use the
* convenience classes VoidInput and VoidOutput instead of this class directly. */
class VoidAccessor : public ChimeraTK::VoidRegisterAccessor, public InversionOfControlAccessor<VoidAccessor> {
public:
using InversionOfControlAccessor<VoidAccessor>::operator VariableNetworkNode;
using InversionOfControlAccessor<VoidAccessor>::operator>>;
void replace(const ChimeraTK::NDRegisterAccessorAbstractor<ChimeraTK::Void>& newAccessor) = delete;
using InversionOfControlAccessor<VoidAccessor>::replace;
VoidAccessor& operator=(VoidAccessor& other) = delete;
using ChimeraTK::VoidRegisterAccessor::operator=;
/** Move constructor */
VoidAccessor(VoidAccessor&& other) noexcept { InversionOfControlAccessor<VoidAccessor>::replace(std::move(other)); }
/** Move assignment. */
VoidAccessor& operator=(VoidAccessor&& other) noexcept;
bool write(ChimeraTK::VersionNumber versionNumber) = delete;
bool writeDestructively(ChimeraTK::VersionNumber versionNumber) = delete;
// void writeIfDifferent(UserType newValue, VersionNumber versionNumber) = delete;
bool writeDestructively();
protected:
friend class InversionOfControlAccessor<VoidAccessor>;
VoidAccessor(Module* owner, const std::string& name, VariableDirection direction, std::string& unit,
UpdateMode mode, const std::string& description, const std::unordered_set<std::string>& tags = {});
/** Default constructor creates a dysfunctional accessor (to be assigned with a real accessor later) */
VoidAccessor() = default;
};
/********************************************************************************************************************/
/** Convenience class for input accessors. For Void there is only UpdateMode::push */
struct VoidInput : public VoidAccessor {
VoidInput(Module* owner, const std::string& name, std::string unit, const std::string& description,
const std::unordered_set<std::string>& tags = {})
: VoidAccessor(owner, name, {VariableDirection::consuming, false}, unit, UpdateMode::push, description, tags) {}
VoidInput() = default;
using VoidAccessor::operator=;
};
/********************************************************************************************************************/
/** Convenience class for output void (always UpdateMode::push) */
struct VoidOutput : public VoidAccessor {
VoidOutput(Module* owner, const std::string& name, std::string unit, const std::string& description,
const std::unordered_set<std::string>& tags = {})
: VoidAccessor(owner, name, {VariableDirection::feeding, false}, unit, UpdateMode::push, description, tags) {}
VoidOutput() = default;
using VoidAccessor::operator=;
};
/********************************************************************************************************************/
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/********************************************************************************************************************/
/* Implementations below this point */
/********************************************************************************************************************/
/********************************************************************************************************************/
inline VoidAccessor& VoidAccessor::operator=(VoidAccessor&& other) noexcept {
// Having a move-assignment operator is required to use the move-assignment
// operator of a module containing an accessor.
InversionOfControlAccessor<VoidAccessor>::replace(std::move(other));
return *this;
}
/********************************************************************************************************************/
inline bool VoidAccessor::write() {
auto versionNumber = this->getOwner()->getCurrentVersionNumber();
bool dataLoss = ChimeraTK::VoidRegisterAccessor::write(versionNumber);
if(dataLoss) Application::incrementDataLossCounter(this->node.getQualifiedName());
return dataLoss;
}
/********************************************************************************************************************/
inline bool VoidAccessor::writeDestructively() {
auto versionNumber = this->getOwner()->getCurrentVersionNumber();
bool dataLoss = ChimeraTK::VoidRegisterAccessor::writeDestructively(versionNumber);
if(dataLoss) Application::incrementDataLossCounter(this->node.getQualifiedName());
return dataLoss;
}
/********************************************************************************************************************/
inline VoidAccessor::VoidAccessor(Module* owner, const std::string& name, VariableDirection direction,
std::string& unit, UpdateMode mode, const std::string& description, const std::unordered_set<std::string>& tags)
: InversionOfControlAccessor<VoidAccessor>(
owner, name, direction, unit, 1, mode, description, &typeid(ChimeraTK::Void), tags) {}
/********************************************************************************************************************/