[ox] Add Reader_c and make MetalClawReader use it
This commit is contained in:
85
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
85
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
@@ -8,21 +8,77 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/array.hpp>
|
||||
#include <ox/std/bit.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
#include <ox/std/reader.hpp>
|
||||
|
||||
#include "err.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T>
|
||||
template<Reader_c Reader>
|
||||
class FieldBitmapReader {
|
||||
protected:
|
||||
mutable std::size_t m_mapBlockIdx = ~std::size_t{0};
|
||||
mutable uint64_t m_mapBlock = 0;
|
||||
std::size_t m_mapStart = 0;
|
||||
Reader &m_reader;
|
||||
|
||||
public:
|
||||
explicit constexpr FieldBitmapReader(Reader &reader) noexcept;
|
||||
|
||||
constexpr Result<bool> get(std::size_t i) const noexcept;
|
||||
|
||||
private:
|
||||
constexpr ox::Error loadMapBlock(std::size_t id) const noexcept;
|
||||
|
||||
};
|
||||
|
||||
template<Reader_c Reader>
|
||||
constexpr FieldBitmapReader<Reader>::FieldBitmapReader(Reader &reader) noexcept:
|
||||
m_mapStart(reader.tellg()),
|
||||
m_reader(reader) {
|
||||
}
|
||||
|
||||
template<Reader_c Reader>
|
||||
constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noexcept {
|
||||
constexpr auto blockBits = sizeof(m_mapBlock);
|
||||
auto const blockIdx = idx / blockBits;
|
||||
if (m_mapBlockIdx != blockIdx) [[unlikely]] {
|
||||
oxReturnError(loadMapBlock(blockIdx));
|
||||
}
|
||||
idx %= blockBits;
|
||||
return (m_mapBlock >> idx) & 1;
|
||||
}
|
||||
|
||||
template<Reader_c Reader>
|
||||
constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept {
|
||||
oxRequire(g, m_reader.tellg());
|
||||
oxReturnError(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
|
||||
ox::Array<char, sizeof(m_mapBlock)> mapBlock{};
|
||||
oxReturnError(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
|
||||
// Warning: narrow-conv
|
||||
oxReturnError(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
|
||||
m_mapBlock = 0;
|
||||
for (auto i = 0ull; auto b : mapBlock) {
|
||||
m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i;
|
||||
i += 8;
|
||||
}
|
||||
m_mapBlockIdx = idx;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
class FieldBitmapWriterBase {
|
||||
protected:
|
||||
T m_map = nullptr;
|
||||
std::size_t m_mapLen = 0;
|
||||
|
||||
public:
|
||||
constexpr FieldBitmapReader(T map, std::size_t maxLen) noexcept;
|
||||
constexpr FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept;
|
||||
|
||||
constexpr auto setBuffer(T map, std::size_t maxLen) noexcept;
|
||||
|
||||
@@ -38,45 +94,45 @@ class FieldBitmapReader {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr FieldBitmapReader<T>::FieldBitmapReader(T map, std::size_t maxLen) noexcept {
|
||||
constexpr FieldBitmapWriterBase<T>::FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept {
|
||||
m_map = map;
|
||||
m_mapLen = maxLen;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr auto FieldBitmapReader<T>::setBuffer(T map, std::size_t maxLen) noexcept {
|
||||
constexpr auto FieldBitmapWriterBase<T>::setBuffer(T map, std::size_t maxLen) noexcept {
|
||||
m_map = map;
|
||||
m_mapLen = maxLen;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<bool> FieldBitmapReader<T>::get(std::size_t i) const noexcept {
|
||||
constexpr Result<bool> FieldBitmapWriterBase<T>::get(std::size_t i) const noexcept {
|
||||
if (i / 8 < m_mapLen) {
|
||||
return (m_map[i / 8] >> (i % 8)) & 1;
|
||||
} else {
|
||||
return OxError(MC_PRESENCEMASKOUTBOUNDS);
|
||||
return OxError(McPresenceMapOverflow);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void FieldBitmapReader<T>::setFields(int fields) noexcept {
|
||||
constexpr void FieldBitmapWriterBase<T>::setFields(int fields) noexcept {
|
||||
m_mapLen = static_cast<std::size_t>((fields / 8 + 1) - (fields % 8 == 0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void FieldBitmapReader<T>::setMaxLen(int maxLen) noexcept {
|
||||
constexpr void FieldBitmapWriterBase<T>::setMaxLen(int maxLen) noexcept {
|
||||
m_mapLen = static_cast<std::size_t>(maxLen);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr int64_t FieldBitmapReader<T>::getMaxLen() const noexcept {
|
||||
constexpr int64_t FieldBitmapWriterBase<T>::getMaxLen() const noexcept {
|
||||
return static_cast<int64_t>(m_mapLen);
|
||||
}
|
||||
|
||||
extern template class FieldBitmapReader<uint8_t*>;
|
||||
extern template class FieldBitmapReader<const uint8_t*>;
|
||||
extern template class FieldBitmapWriterBase<uint8_t*>;
|
||||
extern template class FieldBitmapWriterBase<const uint8_t*>;
|
||||
|
||||
class FieldBitmap: public FieldBitmapReader<uint8_t*> {
|
||||
class FieldBitmap: public FieldBitmapWriterBase<uint8_t*> {
|
||||
|
||||
public:
|
||||
constexpr FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept;
|
||||
@@ -85,7 +141,8 @@ class FieldBitmap: public FieldBitmapReader<uint8_t*> {
|
||||
|
||||
};
|
||||
|
||||
constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept: FieldBitmapReader<uint8_t*>(map, maxLen) {
|
||||
constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept:
|
||||
FieldBitmapWriterBase<uint8_t*>(map, maxLen) {
|
||||
}
|
||||
|
||||
constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
|
||||
@@ -97,7 +154,7 @@ constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
|
||||
}
|
||||
return {};
|
||||
} else {
|
||||
return OxError(MC_PRESENCEMASKOUTBOUNDS);
|
||||
return OxError(McPresenceMapOverflow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user