16namespace ChimeraTK::detail {
27 class ReadCoordinator {
35 int32_t nFractionalBits{};
38 std::type_index userType{
typeid(std::nullptr_t)};
41 auto operator<=>(
const GroupKey&)
const =
default;
47 template<
typename UserType>
49 Consumer(
size_t offset,
size_t pitch,
size_t count, std::vector<UserType>& stagingBuffer);
54 std::vector<UserType>& staging;
64 [[nodiscard]]
virtual bool consumersEmpty()
const = 0;
67 virtual void rawCopy(
const std::vector<uint8_t>& rawBuffer) = 0;
69 virtual ~GroupBase() =
default;
72 std::unique_ptr<RawConverter::ConverterLoopHelper> converterLoopHelper;
79 template<
typename UserType>
80 struct Group : GroupBase {
81 [[nodiscard]]
bool consumersEmpty()
const override;
84 void rawCopy(
const std::vector<uint8_t>& rawBuffer)
override;
86 std::list<Consumer<UserType>> consumers;
95 template<
typename UserType>
98 Registration() =
default;
106 Registration(ReadCoordinator* owner,
const NumericAddressedRegisterInfo& info,
bool isRaw,
size_t byteOffset,
111 Registration(
const Registration&) =
delete;
112 Registration& operator=(
const Registration&) =
delete;
114 Registration(Registration&& other)
noexcept;
115 Registration& operator=(Registration&& other)
noexcept;
121 [[nodiscard]] std::vector<UserType>& staging();
124 friend class ReadCoordinator;
126 ReadCoordinator* _owner{
nullptr};
128 std::list<Consumer<UserType>>::iterator _it;
132 std::unique_ptr<std::vector<UserType>> _staging;
135 ReadCoordinator() =
default;
137 ReadCoordinator(
const ReadCoordinator&) =
delete;
138 ReadCoordinator(ReadCoordinator&&) noexcept = delete;
139 ReadCoordinator& operator=(const ReadCoordinator&) = delete;
140 ReadCoordinator& operator=(ReadCoordinator&&) noexcept = delete;
142 ~ReadCoordinator() = default;
145 [[nodiscard]]
bool empty() const;
151 void run(const
std::vector<uint8_t>& rawBuffer);
158 template<class UserType, typename RawType, RawConverter::SignificantBitsCase sc, RawConverter::FractionalCase fc,
160 void doPostReadImpl(RawConverter::Converter<UserType, RawType, sc, fc, isSigned> converter,
size_t groupId);
166 template<class UserType, typename RawType, RawConverter::SignificantBitsCase sc, RawConverter::FractionalCase fc,
168 void doPreWriteImpl(RawConverter::Converter<UserType, RawType, sc, fc, isSigned> converter,
size_t groupId);
172 friend class Registration;
179 std::map<
size_t,
std::unique_ptr<GroupBase>> _groups;
180 std::map<GroupKey,
size_t> _groupIndex;
181 size_t _nextGroupId{};
183 const std::vector<uint8_t>* _rawBuffer{
nullptr};
188 template<
typename UserType>
189 inline ReadCoordinator::Consumer<UserType>::Consumer(
190 size_t offset,
size_t pitch,
size_t count, std::vector<UserType>& stagingBuffer)
191 : byteOffset(offset), stride(pitch),
nSamples(count), staging(stagingBuffer) {}
195 template<
typename UserType>
196 inline bool ReadCoordinator::Group<UserType>::consumersEmpty()
const {
197 return consumers.empty();
202 template<
typename UserType>
203 inline void ReadCoordinator::Group<UserType>::rawCopy(
const std::vector<uint8_t>& rawBuffer) {
204 for(
const auto& consumer : consumers) {
205 if(consumer.nSamples == 0) {
208 auto* cooked = consumer.staging.data();
209 const auto*
raw = rawBuffer.data() + consumer.byteOffset;
217 if constexpr(std::is_integral_v<UserType>) {
218 if constexpr(ChimeraTK::isRawType<std::make_unsigned_t<UserType>>) {
219 for(
size_t i = 0; i < consumer.nSamples; ++i) {
220 std::memcpy(cooked + i, raw + i * consumer.stride,
sizeof(UserType));
#define DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
Type
Enum descibing the data interpretation:
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
constexpr size_t nSamples