15 boost::shared_ptr<TransferElement> dataConsistencyDecorator;
17 using UserType = decltype(t);
20 for(auto& e : acc.getInternalElements()) {
21 auto dec = boost::dynamic_pointer_cast<DataConsistencyDecorator<UserType>>(e);
23 throw ChimeraTK::logic_error(
24 "accessor is already in historized DataConsistencyGroup, cannot add it to another one: " + acc.getName());
30 auto factoryF = [&](
const boost::shared_ptr<NDRegisterAccessor<UserType>>& toBeDecorated) {
31 return boost::make_shared<DataConsistencyDecorator<UserType>>(toBeDecorated,
this);
35 dataConsistencyDecorator = accImpl->decorateDeepInside(factoryF);
36 if(!dataConsistencyDecorator) {
38 dataConsistencyDecorator = factoryF(accImpl);
39 acc.
replace(dataConsistencyDecorator);
42 return dataConsistencyDecorator;
48 auto it = _targetElements.find(transferElementID);
49 assert(it != _targetElements.end());
51 auto& pElem = it->second;
52 auto vn = pElem.acc.getVersionNumber();
53 if(pElem.histLen > 0 && vn == pElem.versionNumbers[0]) {
59 bool consistent = findMatch(transferElementID);
67 if(_handleMissingPreReadsCalled) {
70 _handleMissingPreReadsCalled =
true;
71 auto resetFlag = cppext::finally([
this] { _handleMissingPreReadsCalled =
false; });
74 if(_decoratorsNeedPreRead) {
76 if(lastUpdateCall() != callerId) {
77 throw ChimeraTK::logic_error(
"updates from ReadAnyGroup must be processed by DataConsistencyGroup::update");
81 for(
auto& e : _pushElements) {
82 if(e.first != callerId) {
87 _decoratorsNeedPreRead =
false;
92 void HistorizedMatcher::handleMissingPostReads(
TransferElementID callerId,
bool updateBuffer) {
94 if(_handleMissingPostReadsCalled) {
97 _handleMissingPostReadsCalled =
true;
98 auto resetFlag = cppext::finally([
this] { _handleMissingPostReadsCalled =
false; });
105 for(
auto& e : _pushElements) {
106 if(e.first != callerId) {
107 auto& acc = e.second;
111 _decoratorsNeedPreRead =
true;
118 auto id = acc.
getId();
120 auto dataConsistencyDecorator = decorateAccessor(acc);
121 auto target = dataConsistencyDecorator->getInternalElements().front();
124 _pushElements[id] = acc;
127 for(
auto& pe : rag->push_elements) {
128 if(pe.getId() == id) {
139 if(_targetElements.find(
id) != _targetElements.end()) {
146 using UserType = decltype(argForType);
147 using UserBufferType = std::vector<std::vector<UserType>>;
149 TargetElement element0 = {acc, histLen, nullptr, typeid(UserType), {}, {}};
150 _targetElements.insert({id, element0});
152 auto* mem =
new std::vector<UserBufferType>(histLen);
154 auto& buf = getUserBuffer<UserType>(
id);
155 unsigned nChannels = buf.size();
156 assert(nChannels > 0);
157 unsigned nSamples = buf[0].size();
158 for(UserBufferType& historyElement : *mem) {
159 historyElement.resize(nChannels);
160 for(
auto& historyElementChannel : historyElement) {
161 historyElementChannel.resize(nSamples);
176 HistorizedMatcher::~HistorizedMatcher() {
177 for(
auto& x : _targetElements) {
183 using UserType = decltype(arg);
184 using UserBufferType = std::vector<std::vector<UserType>>;
185 delete getBufferVector<UserBufferType>(id);
188 catch(std::bad_cast& e) {
199 auto it = _targetElements.find(transferElementID);
200 if(it == _targetElements.end()) {
207 for(
auto& pair : _targetElements) {
208 if(pair.first == transferElementID) {
219 auto pos = std::find(versionNumVector.begin(), versionNumVector.end(), vn);
220 if(pos == versionNumVector.end()) {
231 _lastMatchingVersionNumber = vn;
238 TargetElement& element = _targetElements.at(transferElementID);
248 using UserType = decltype(arg);
249 using UserBufferType = std::vector<std::vector<UserType>>;
250 auto& buf = getUserBuffer<UserType>(transferElementID);
253 auto& bufferVector = *getBufferVector<UserBufferType>(transferElementID);
254 unsigned histLen = bufferVector.size();
255 auto& versionNumVector = element.versionNumbers;
256 auto& datavalidityVector = element.dataValidities;
261 if(versionNumVector[0] > VersionNumber(nullptr)) {
262 for(unsigned i = histLen - 1; i > 0; i--) {
263 bufferVector[i].swap(bufferVector[i - 1]);
264 versionNumVector[i] = versionNumVector[i - 1];
265 datavalidityVector[i] = datavalidityVector[i - 1];
268 bufferVector[0].swap(buf);
269 versionNumVector[0] = vn;
270 datavalidityVector[0] = dv;
boost::shared_ptr< TransferElement > decorateAccessor(TransferElementAbstractor &acc)
decorate accessor by replacing its target => DataConsistencyDecorator(target), possibly at an inner l...
N-dimensional register accessor.
Base class for register accessors abstractors independent of the UserType.
ChimeraTK::VersionNumber getVersionNumber() const
Returns the version number that is associated with the last transfer (i.e.
const boost::shared_ptr< TransferElement > & getHighLevelImplElement()
Obtain the highest level implementation TransferElement.
const std::type_info & getValueType() const
Returns the std::type_info for the value type of this transfer element.
ReadAnyGroup * getReadAnyGroup() const
Obtain the ReadAnyGroup this TransferElement is part of, or nullptr if not in a ReadAnyGroup.
DataValidity dataValidity() const
Return current validity of the data.
void replace(const TransferElementAbstractor &newAccessor)
Assign a new accessor to this TransferElementAbstractor.
TransferElementID getId() const
Obtain unique ID for the actual implementation of this TransferElement.
Simple class holding a unique ID for a TransferElement.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
void callForType(const std::type_info &type, LAMBDATYPE lambda)
Helper function for running code which uses some compile-time type that is specified at runtime as a ...
DataValidity
The current state of the data.
std::vector< VersionNumber > versionNumbers
TransferElementAbstractor acc
target of DataConsistencyDecorator
const std::type_info & histBufferType
unsigned lastMatchingIndex
match indices set by findMatch() in case it returns true.
std::vector< DataValidity > dataValidities