147 lines
4.8 KiB
C++
147 lines
4.8 KiB
C++
#pragma once
|
|
#include <QVector>
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <vector>
|
|
#include "Core/Base/RingBuffer.hpp"
|
|
namespace YSG {
|
|
class Bounded_Input_Buffer {
|
|
public:
|
|
static constexpr std::size_t Default_Max_Packet_Count = 64;
|
|
void push(const void* data, std::size_t size, std::size_t maxPacketCount = Default_Max_Packet_Count) {
|
|
configure(size, maxPacketCount);
|
|
while (!mBuffer.write(data, size)) {
|
|
if (!mBuffer.skip_one())
|
|
return;
|
|
++mDroppedCount;
|
|
if (mPendingCount)
|
|
--mPendingCount;
|
|
}
|
|
++mPendingCount;
|
|
++mPushedCount;
|
|
}
|
|
template <typename Handler>
|
|
void read_all(Handler handler) {
|
|
std::size_t packetSize{};
|
|
while (mBuffer.peek_len(packetSize)) {
|
|
mReadBuffer.resize(packetSize);
|
|
std::size_t readSize = packetSize;
|
|
if (!mBuffer.read(mReadBuffer.data(), readSize))
|
|
return;
|
|
if (mPendingCount)
|
|
--mPendingCount;
|
|
handler(mReadBuffer.data(), readSize);
|
|
}
|
|
}
|
|
void clear() {
|
|
while (mBuffer.skip_one()) {
|
|
}
|
|
mPendingCount = 0;
|
|
}
|
|
[[nodiscard]] std::uint64_t pending_count() const {
|
|
return mPendingCount;
|
|
}
|
|
[[nodiscard]] std::uint64_t dropped_count() const {
|
|
return mDroppedCount;
|
|
}
|
|
[[nodiscard]] std::uint64_t pushed_count() const {
|
|
return mPushedCount;
|
|
}
|
|
private:
|
|
void configure(std::size_t maxPacketSize, std::size_t maxPacketCount) {
|
|
maxPacketCount = std::max<std::size_t>(1, maxPacketCount);
|
|
maxPacketSize = std::max<std::size_t>(1, maxPacketSize);
|
|
if (mInited && maxPacketSize <= mMaxPacketSize && maxPacketCount == mMaxPacketCount)
|
|
return;
|
|
mMaxPacketSize = maxPacketSize;
|
|
mMaxPacketCount = maxPacketCount;
|
|
mPendingCount = 0;
|
|
mBuffer.init((Psc::RingBuffer_ST::HEADER_SIZE + mMaxPacketSize) * mMaxPacketCount);
|
|
mInited = true;
|
|
}
|
|
bool mInited = false;
|
|
std::size_t mMaxPacketSize{};
|
|
std::size_t mMaxPacketCount{};
|
|
std::uint64_t mPendingCount{};
|
|
std::uint64_t mDroppedCount{};
|
|
std::uint64_t mPushedCount{};
|
|
Psc::RingBuffer_ST mBuffer;
|
|
std::vector<std::uint8_t> mReadBuffer;
|
|
};
|
|
class Bounded_Vector_Double_Input_Buffer {
|
|
public:
|
|
void push(const QVector<double>& data, std::size_t maxPacketCount = Bounded_Input_Buffer::Default_Max_Packet_Count) {
|
|
mBuffer.push(data.constData(), static_cast<std::size_t>(data.size()) * sizeof(double), maxPacketCount);
|
|
}
|
|
template <typename Handler>
|
|
void read_all(Handler handler) {
|
|
mBuffer.read_all([this, &handler](const void* data, std::size_t size) {
|
|
mVectorBuffer.resize(static_cast<int>(size / sizeof(double)));
|
|
std::memcpy(mVectorBuffer.data(), data, size);
|
|
handler(mVectorBuffer);
|
|
});
|
|
}
|
|
template <typename Handler>
|
|
void read_all_reverse(Handler handler) {
|
|
mReverseVectors.clear();
|
|
read_all([this](const QVector<double>& data) {
|
|
mReverseVectors.append(data);
|
|
});
|
|
for (int i = mReverseVectors.size() - 1; i >= 0; --i) {
|
|
handler(mReverseVectors[i]);
|
|
}
|
|
}
|
|
void clear() {
|
|
mBuffer.clear();
|
|
}
|
|
[[nodiscard]] std::uint64_t pending_count() const {
|
|
return mBuffer.pending_count();
|
|
}
|
|
[[nodiscard]] std::uint64_t dropped_count() const {
|
|
return mBuffer.dropped_count();
|
|
}
|
|
[[nodiscard]] std::uint64_t pushed_count() const {
|
|
return mBuffer.pushed_count();
|
|
}
|
|
private:
|
|
Bounded_Input_Buffer mBuffer;
|
|
QVector<double> mVectorBuffer;
|
|
QVector<QVector<double>> mReverseVectors;
|
|
};
|
|
class Bounded_Double_Input_Buffer {
|
|
public:
|
|
void push(double data, std::size_t maxPacketCount = Bounded_Input_Buffer::Default_Max_Packet_Count) {
|
|
mBuffer.push(&data, sizeof(data), maxPacketCount);
|
|
}
|
|
template <typename Handler>
|
|
void read_all_reverse(Handler handler) {
|
|
mReverseValues.clear();
|
|
mBuffer.read_all([this](const void* data, std::size_t size) {
|
|
(void)size;
|
|
double value;
|
|
std::memcpy(&value, data, sizeof(value));
|
|
mReverseValues.append(value);
|
|
});
|
|
for (int i = mReverseValues.size() - 1; i >= 0; --i) {
|
|
handler(mReverseValues[i]);
|
|
}
|
|
}
|
|
void clear() {
|
|
mBuffer.clear();
|
|
}
|
|
[[nodiscard]] std::uint64_t pending_count() const {
|
|
return mBuffer.pending_count();
|
|
}
|
|
[[nodiscard]] std::uint64_t dropped_count() const {
|
|
return mBuffer.dropped_count();
|
|
}
|
|
[[nodiscard]] std::uint64_t pushed_count() const {
|
|
return mBuffer.pushed_count();
|
|
}
|
|
private:
|
|
Bounded_Input_Buffer mBuffer;
|
|
QVector<double> mReverseValues;
|
|
};
|
|
} // namespace YSG
|