#pragma once #include "../Types.h" #include namespace RTW { class Data : public Object { public: static size_t GetElementSize(RTWDataType type) { switch (type) { case RTW_UCHAR: return 1; case RTW_VEC2UC: case RTW_SHORT: case RTW_USHORT: return 2; case RTW_VEC3UC: return 3; case RTW_VEC4UC: case RTW_INT: case RTW_UINT: case RTW_FLOAT: return 4; case RTW_VEC2I: case RTW_VEC2UI: case RTW_VEC2F: case RTW_DOUBLE: return 8; case RTW_VEC3I: case RTW_VEC3UI: case RTW_VEC3F: return 12; case RTW_VEC4I: case RTW_VEC4UI: case RTW_VEC4F: return 16; default: if(type >= RTW_OBJECT && type <= RTW_WORLD) return sizeof(Object *); else return 0; } } public: Data(const void *source, RTWDataType type, size_t width, bool shared = false) : Data(source, type, width, 1, 1, shared) {}; Data(const void *source, RTWDataType type, size_t width, size_t height, bool shared = false) : Data(source, type, width, height, 1, shared) {}; Data(const void *source, RTWDataType type, size_t width, size_t height, size_t depth, bool shared = false) : Object(RTW_DATA) { this->width = width; this->height = height; this->depth = depth; this->type = type; this->elementSize = GetElementSize(type); this->shared = shared; if (this->shared) { this->data = reinterpret_cast(const_cast(source)); } else { size_t size = GetNumElements() * this->elementSize; this->data = new uint8_t[size]; memcpy(this->data, source, size); } // Increase references if(type >= RTW_OBJECT && type <= RTW_WORLD) { for (size_t i = 0; i < GetNumElements(); ++i) { Object* obj = reinterpret_cast(this->data)[i]; if (obj) obj->AddRef(); } } this->dirty = true; } ~Data() { // Release references if(type >= RTW_OBJECT && type <= RTW_WORLD) { for (size_t i = 0; i < GetNumElements(); ++i) { Object* obj = reinterpret_cast(this->data)[i]; if (obj) obj->Release(); } } if (!this->shared) delete[] this->data; } void Commit() override { // Committing data marks it as dirty (useful for shared memory) this->dirty = true; } size_t GetNumElements() const { return this->width * this->height * this->depth; } size_t GetWidth() const { return this->width; } size_t GetHeight() const { return this->height; } size_t GetDepth() const { return this->depth; } RTWDataType GetElementDataType() const { return this->type; } size_t GetElementSize() const { return GetElementSize(this->type); } void* GetData() const { return reinterpret_cast(this->data); } bool IsShared() const { return this->shared; } bool CheckDirty() { bool d = this->dirty; this->dirty = false; return d; } private: size_t width = 0, height = 1, depth = 1; RTWDataType type; size_t elementSize = 0; uint8_t* data = nullptr; bool shared = false; bool dirty = true; }; }