hazelnut/agent/CollabVMFbcAgent/Utils.hpp

133 lines
2.7 KiB
C++
Executable file

#pragma once
#include <cstdint>
#include <cstring>
#include <memory>
// common types
using u8 = std::uint8_t;
using i8 = std::int8_t;
using u16 = std::uint16_t;
using i16 = std::int16_t;
using u32 = std::uint32_t;
using i32 = std::int32_t;
using u64 = std::uint64_t;
using i64 = std::int64_t;
using usize = std::size_t;
using f32 = float;
using f64 = double;
struct tSize {
u32 width;
u32 height;
};
struct tRect {
u32 x;
u32 y;
u32 width;
u32 height;
};
struct cSurface {
private:
u32* pBuffer;
tSize size;
u32 stride;
bool owned { false };
struct OwnedTag {};
public:
cSurface(u32* pBuffer, const tSize& size, u32 stride = -1) {
if(stride == -1) {
this->stride = size.width;
} else {
this->stride = stride;
}
this->size = size;
this->pBuffer = pBuffer;
this->owned = false;
}
cSurface(u32* pBuffer, const tSize& size, OwnedTag) {
this->pBuffer = pBuffer;
this->size = size;
owned = true;
}
~cSurface() {
if(owned) {
delete[] pBuffer;
this->pBuffer = nullptr;
}
}
cSurface(const cSurface&) = delete;
cSurface(cSurface&& move) {
this->pBuffer = move.pBuffer;
move.pBuffer = nullptr;
this->size = {};
this->stride = -1;
this->owned = move.owned;
move.owned = false;
}
u32 Stride() const { return stride; }
u32 StrideBytes() const { return stride * sizeof(u32); }
const tSize& Size() const { return size; }
u32* Memory() { return &this->pBuffer[0]; }
// creates a new owned cSurface which owns this memory
std::unique_ptr<cSurface> ClonePiece(const tRect& rect) {
auto* pSurfaceMemory = new u32[rect.width * rect.height * sizeof(u32)];
for(u32 y = 0; y < rect.height; ++y) {
auto* pTileLineStart = &pBuffer[(rect.y + y) * this->stride + rect.x];
memcpy(&pSurfaceMemory[y * rect.width], pTileLineStart, rect.width * sizeof(u32));
}
return std::unique_ptr<cSurface>(new cSurface(pSurfaceMemory, { rect.width, rect.height }, OwnedTag {}));
}
};
/// like vector<T> but doesn't grow on its own
template <class T>
struct unique_buffer {
T* m_buffer;
size_t size;
public:
unique_buffer() {
m_buffer = nullptr;
size = 0;
}
// forbid copying or movement for now
unique_buffer(const unique_buffer&) = delete;
unique_buffer(unique_buffer&&) = delete;
~unique_buffer() { resize(0); }
size_t get_size() const { return this->size; }
void resize(size_t new_size) {
if(m_buffer) {
delete[] m_buffer;
m_buffer = nullptr;
size = 0;
}
if(new_size) {
m_buffer = new T[new_size];
size = new_size;
}
}
T* data() { return &m_buffer[0]; }
const T* data() const { return &m_buffer[0]; }
};