Newer
Older
Martin Christoph Hierholzer
committed
/*
* ConsumingFanOut.h
*
* Created on: Jun 15, 2016
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_CONSUMING_FAN_OUT_H
#define CHIMERATK_CONSUMING_FAN_OUT_H
#include <mtca4u/NDRegisterAccessor.h>
#include "FanOut.h"
namespace ChimeraTK {
/** FanOut implementation which acts as a read-only (i.e. consuming) NDRegisterAccessor. The values read through
* this accessor will be obtained from the given feeding implementation and distributed to any number of slaves. */
Martin Christoph Hierholzer
committed
template<typename UserType>
class ConsumingFanOut : public FanOut<UserType>, public mtca4u::NDRegisterAccessor<UserType> {
public:
ConsumingFanOut(boost::shared_ptr<mtca4u::NDRegisterAccessor<UserType>> feedingImpl)
: FanOut<UserType>(feedingImpl)
{
mtca4u::NDRegisterAccessor<UserType>::buffer_2D.resize( feedingImpl->getNumberOfChannels() );
for(size_t i=0; i<feedingImpl->getNumberOfChannels(); i++) {
mtca4u::NDRegisterAccessor<UserType>::buffer_2D[i].resize( feedingImpl->getNumberOfSamples() );
}
}
bool isReadable() const override {
return true;
Martin Christoph Hierholzer
committed
}
bool isReadOnly() const override {
return true;
Martin Christoph Hierholzer
committed
}
bool isWriteable() const override {
return false;
Martin Christoph Hierholzer
committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}
void doReadTransfer() override {
FanOut<UserType>::impl->read();
}
bool doReadTransferNonBlocking() override {
return FanOut<UserType>::impl->readNonBlocking();
}
void postRead() override {
mtca4u::NDRegisterAccessor<UserType>::buffer_2D[0].swap(FanOut<UserType>::impl->accessChannel(0));
for(auto &slave : slaves) { // send out copies to slaves
// do not send copy if no data is expected (e.g. trigger)
if(slave->getNumberOfSamples() != 0) {
slave->accessChannel(0) = mtca4u::NDRegisterAccessor<UserType>::buffer_2D[0];
}
slave->write();
}
}
void write() override {
throw std::logic_error("Write operation called on read-only variable.");
}
bool isSameRegister(const boost::shared_ptr<const mtca4u::TransferElement>& e) const override {
// only true if the very instance of the transfer element is the same
return e.get() == this;
}
std::vector<boost::shared_ptr<mtca4u::TransferElement> > getHardwareAccessingElements() override {
return { boost::enable_shared_from_this<mtca4u::TransferElement>::shared_from_this() };
}
void replaceTransferElement(boost::shared_ptr<mtca4u::TransferElement>) override {
// You can't replace anything here. Just do nothing.
}
protected:
boost::shared_ptr<mtca4u::NDRegisterAccessor<UserType>> impl;
std::list<boost::shared_ptr<mtca4u::NDRegisterAccessor<UserType>>> slaves;
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_CONSUMING_FAN_OUT_H */