Files
Renderive/YSGraphic_Core/architecture/Bounded_Input_Buffer.h
T
2026-07-28 10:54:38 +08:00

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