また、IDisposerを継承してファクトリメソッドからオブジェクトの構築をすることで、オブジェクト毎に異なるヒープからメモリの確保を行うクラスを作成することが可能です。
#include "gameheap.h"
using nlib_ns::heap::CentralHeap;
const int kGraphcisObjectHeap = 1;
const int kSoundObjectHeap = 2;
static char mymem[3][1024 * 1024 * 2];
static HeapHandle heap_handle[3];
void init_my_heap() {
nlib_printf(
"Graphics objects and Sound objects are allocated from different regions\n");
for (int i = 0; i < 3; ++i) {
heap_handle[i] = HeapHandle::createHeap(&mymem[i][0], 1024 * 1024 * 2);
NLIB_ASSERT(heap_handle[i].isValid());
(void*)&mymem[i][0], (void*)(&mymem[i][0] + 1024 * 1024 * 2));
}
nlib_printf(
"GraphicsObject <---- Heap%d\n", kGraphcisObjectHeap);
nlib_printf(
"SoundObject <---- Heap%d\n", kSoundObjectHeap);
}
void terminate_my_heap() {
for (int i = 0; i < 8; ++i) {
HeapHandle::destroyHeap(heap_handle[i]);
}
}
class GraphicsObject : public IDisposer {
public:
static GraphicsObject* Create() {
nlib_printf(
" GraphicsObject::Create begin, allocate GraphicsObject itself\n");
HeapHandle h = heap_handle[kGraphcisObjectHeap];
void* mem = h.alloc(
sizeof(GraphicsObject),
NLIB_ALIGNOF(GraphicsObject));
GraphicsObject* obj = new(mem)GraphicsObject();
return obj;
}
bool Init(const char* resource_path) {
nlib_printf(
" GraphicsObject::Init begin, allocate its data members\n");
NLIB_ASSERT(resource_path);
size_t n = strlen(resource_path);
HeapHandle h = GetHeapHandle();
void* path = h.alloc(n + 1);
if (!path) return false;
memcpy(path, resource_path, n + 1);
m_Path = reinterpret_cast<char*>(path);
m_Vertices = reinterpret_cast<float*>(h.alloc(1024 * 3 * sizeof(float)));
m_Triangles = reinterpret_cast<uint16_t*>(h.alloc(512 * 3 * sizeof(uint16_t)));
return m_Vertices && m_Triangles;
}
private:
GraphicsObject()
NLIB_NOEXCEPT : IDisposer(heap_handle[kGraphcisObjectHeap]) {
m_Path = NULL;
m_Vertices = NULL;
m_Triangles = NULL;
}
nlib_printf(
" GraphicsObject::~GraphicsObject() begin, free its data members\n");
HeapHandle h = GetHeapHandle();
h.free(const_cast<char*>(m_Path));
h.free(m_Vertices);
h.free(m_Triangles);
nlib_printf(
" GraphicsObject::~GraphicsObject() end\n");
}
private:
const char* m_Path;
float* m_Vertices;
uint16_t* m_Triangles;
};
class SoundObject : public IDisposer {
public:
static SoundObject* Create() {
nlib_printf(
" SoundObject::Crate() begin, allocate SoundObject itself\n");
HeapHandle h = heap_handle[kSoundObjectHeap];
void* mem = h.alloc(
sizeof(SoundObject),
NLIB_ALIGNOF(SoundObject));
SoundObject* obj = new(mem)SoundObject();
return obj;
}
bool Init(const char* resource_path) {
nlib_printf(
" SoundObject::Init() begin, allocate its data members\n");
NLIB_ASSERT(resource_path);
size_t n = strlen(resource_path);
HeapHandle h = GetHeapHandle();
void* path = h.alloc(n + 1);
if (!path) return false;
memcpy(path, resource_path, n + 1);
m_Path = reinterpret_cast<char*>(path);
m_WaveDataCnt = 2;
m_WaveData = (void**)h.alloc(n * sizeof(*m_WaveData));
if (!m_WaveData) return false;
for (size_t i = 0; i < m_WaveDataCnt; ++i) {
m_WaveData[i] = NULL;
}
for (size_t i = 0; i < m_WaveDataCnt; ++i) {
m_WaveData[i] = h.alloc(8192);
if (!m_WaveData[i]) return false;
}
return true;
}
private:
SoundObject()
NLIB_NOEXCEPT : IDisposer(heap_handle[kSoundObjectHeap]) {
m_WaveDataCnt = 0;
m_WaveData = NULL;
}
nlib_printf(
" SoundObject::~SoundObject() begin, free its data members\n");
HeapHandle h = GetHeapHandle();
h.free(const_cast<char*>(m_Path));
for (size_t i = 0; i < m_WaveDataCnt; ++i) {
h.free(m_WaveData[i]);
}
h.free(m_WaveData);
}
private:
const char* m_Path;
size_t m_WaveDataCnt;
void** m_WaveData;
};
class MiscObject : public IDisposer {
public:
static MiscObject* Create(HeapHandle h) {
nlib_printf(
" MiscObject::Create begin, allocate MiscObject itself\n");
void* mem = h.alloc(
sizeof(MiscObject),
NLIB_ALIGNOF(MiscObject));
if (!mem) return NULL;
MiscObject* obj = new(mem)MiscObject(h);
return obj;
}
bool Init() {
nlib_printf(
" MiscObject::Init begin, allocate its data members\n");
m_Data = GetHeapHandle().alloc(1024);
if (!m_Data) return false;
return true;
}
private:
m_Data = NULL;
}
nlib_printf(
" MiscObject::~MiscObject() begin, free its data members\n");
GetHeapHandle().free(m_Data);
}
private:
void* m_Data;
};
class CharacterObject : public IDisposer {
public:
static CharacterObject* Create() {
nlib_printf(
" CharacterObject::Create begin, allocate CharacterObject itself\n");
HeapHandle h = GetThreadDefaultHeapHandle();
void* mem = h.alloc(
sizeof(CharacterObject),
NLIB_ALIGNOF(CharacterObject));
CharacterObject* obj = new(mem)CharacterObject(h);
return obj;
}
bool Init(const char* graphics_res_path, const char* sound_res_path) {
m_GraphicsObject = GraphicsObject::Create();
if (!m_GraphicsObject || !m_GraphicsObject->Init(graphics_res_path)) return false;
m_SoundObject = SoundObject::Create();
if (!m_SoundObject || !m_SoundObject->Init(sound_res_path)) return false;
m_MiscObject = MiscObject::Create(GetHeapHandle());
if (!m_MiscObject || !m_MiscObject->Init()) return false;
return true;
}
private:
explicit CharacterObject(HeapHandle h)
NLIB_NOEXCEPT : IDisposer(h) {
m_GraphicsObject = NULL;
m_SoundObject = NULL;
m_MiscObject = NULL;
}
nlib_printf(
" CharacterObject::~CharacterObject() begin, free its data members\n");
if (m_GraphicsObject) m_GraphicsObject->Destroy();
if (m_SoundObject) m_SoundObject->Destroy();
if (m_MiscObject) m_MiscObject->Destroy();
nlib_printf(
" CharacterObject::~CharacterObject() end\n");
}
private:
GraphicsObject* m_GraphicsObject;
SoundObject* m_SoundObject;
MiscObject* m_MiscObject;
};
bool TestGraphicsObject() {
SetThreadDefaultHeapHandle(heap_handle[0]);
CharacterObject* cobj = CharacterObject::Create();
if (!cobj || !cobj->Init("graphics_resource.bin", "sound_resource.bin")) {
return false;
}
cobj->Destroy();
if (!heap_handle[0].isClean()) {
heap_handle[0].freeAll();
return false;
}
if (!heap_handle[1].isClean()) {
heap_handle[1].freeAll();
return false;
}
if (!heap_handle[2].isClean()) {
heap_handle[2].freeAll();
return false;
}
return true;
}
static bool SampleMain(int, char**) {
init_my_heap();
bool result = TestGraphicsObject();
terminate_my_heap();
return result;
}
NLIB_MAINFUNC