Skip to content

Commit ac3db64

Browse files
committed
Work on async asset loading
1 parent e6d0431 commit ac3db64

28 files changed

+426
-127
lines changed

Mahakam/src/Mahakam/Asset/Asset.h

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#pragma once
22

3-
#include "AssetDatabase.h"
43

54
#include "Mahakam/Core/Allocator.h"
65
#include "Mahakam/Core/Log.h"
76

7+
#include "AssetDatabase.h"
8+
#include "AssetDataFunctions.h"
9+
810
#include <cstddef>
911
#include <filesystem>
1012
#include <memory>
@@ -23,8 +25,6 @@ namespace Mahakam
2325

2426
friend class AssetDatabase;
2527

26-
using AssetID = AssetDatabase::AssetID;
27-
using ControlBlock = AssetDatabase::ControlBlock;
2828
using ExtensionType = AssetDatabase::ExtensionType;
2929

3030
ControlBlock* m_Control;
@@ -176,6 +176,11 @@ namespace Mahakam
176176
return m_Control ? m_Control->UseCount : 0;
177177
}
178178

179+
AssetState GetState() const noexcept
180+
{
181+
return m_Control ? m_Control->State : AssetState::Failed;
182+
}
183+
179184
T* get() const noexcept
180185
{
181186
return m_Control ? reinterpret_cast<T*>(m_Control + 1) : nullptr;
@@ -202,7 +207,7 @@ namespace Mahakam
202207

203208
explicit operator bool() const noexcept
204209
{
205-
return m_Control;
210+
return m_Control ? (m_Control->State == AssetState::Loaded || m_Control->State == AssetState::Streaming) : false;
206211
}
207212

208213
private:
@@ -222,7 +227,7 @@ namespace Mahakam
222227
if (m_Control->ID)
223228
AssetDatabase::UnloadAsset(m_Control);
224229

225-
auto destroy = m_Control->DeleteData;
230+
auto destroy = m_Control->Functions->Delete;
226231

227232
MH_ASSERT(destroy, "Asset destructor encountered invalid control block");
228233

@@ -234,35 +239,10 @@ namespace Mahakam
234239
template<typename T, typename ... Args>
235240
constexpr Asset<T> CreateAsset(Args&& ... args)
236241
{
237-
struct DataBlock
238-
{
239-
AssetDatabase::ControlBlock Control;
240-
T Data;
241-
};
242-
243-
DataBlock* block = Allocator::Allocate<DataBlock>(1);
242+
DataBlock<T>* block = reinterpret_cast<DataBlock<T>*>(GetAssetDataFunctions<T>()->CreateControlBlock());
244243

245244
Allocator::Construct(&block->Data, std::forward<Args>(args)...);
246-
247-
auto mover = [](void* from, void* to)
248-
{
249-
*static_cast<T*>(to) = std::move(*static_cast<T*>(from));
250-
};
251-
252-
auto deleter = [](void* p)
253-
{
254-
DataBlock* block = static_cast<DataBlock*>(p);
255-
256-
Allocator::Deconstruct(&block->Data);
257-
258-
Allocator::Deallocate(block, 1);
259-
};
260-
261-
block->Control.UseCount = 0;
262-
block->Control.ID = 0;
263-
block->Control.State = AssetDatabase::AssetState::Loaded;
264-
block->Control.MoveData = mover;
265-
block->Control.DeleteData = deleter;
245+
block->Control.State = AssetState::Loaded;
266246

267247
return Asset<T>(&block->Control);
268248
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#pragma once
2+
3+
#include "Mahakam/Core/Allocator.h"
4+
5+
#include <cstdint>
6+
#include <type_traits>
7+
8+
namespace Mahakam
9+
{
10+
enum class AssetState
11+
{
12+
Failed = 0,
13+
Loaded,
14+
Processing,
15+
Streaming
16+
};
17+
18+
using AssetID = uint64_t;
19+
20+
struct ControlBlock;
21+
22+
struct AssetDataFunctions
23+
{
24+
ControlBlock* (*CreateControlBlock)();
25+
void (*MoveConstruct)(void*, void*);
26+
void (*MoveAssign)(void*, void*);
27+
void (*Delete)(void*);
28+
};
29+
30+
struct ControlBlock
31+
{
32+
// ID 0 is guaranteed to be invalid
33+
size_t UseCount;
34+
AssetID ID;
35+
AssetState State;
36+
AssetDataFunctions* Functions;
37+
};
38+
39+
template<typename T>
40+
struct DataBlock
41+
{
42+
ControlBlock Control;
43+
T Data;
44+
};
45+
46+
template<typename T>
47+
AssetDataFunctions* GetAssetDataFunctions()
48+
{
49+
auto control = []()
50+
{
51+
DataBlock<T>* block = Allocator::Allocate<DataBlock<T>>(1);
52+
53+
block->Control.UseCount = 0;
54+
block->Control.ID = 0;
55+
block->Control.State = AssetState::Processing;
56+
block->Control.Functions = GetAssetDataFunctions<T>();
57+
58+
return &block->Control;
59+
};
60+
61+
auto constructor = [](void* obj, void* other)
62+
{
63+
Allocator::Construct(static_cast<T*>(obj), std::move(*static_cast<T*>(other)));
64+
};
65+
66+
auto mover = [](void* from, void* to)
67+
{
68+
*static_cast<T*>(to) = std::move(*static_cast<T*>(from));
69+
};
70+
71+
auto deleter = [](void* p)
72+
{
73+
DataBlock<T>* block = static_cast<DataBlock<T>*>(p);
74+
75+
if (block->Control.State == AssetState::Loaded || block->Control.State == AssetState::Streaming)
76+
Allocator::Deconstruct(&block->Data);
77+
78+
Allocator::Deallocate(block, 1);
79+
};
80+
81+
static AssetDataFunctions static_functions
82+
{
83+
control,
84+
constructor,
85+
mover,
86+
deleter
87+
};
88+
89+
return &static_functions;
90+
}
91+
}

0 commit comments

Comments
 (0)