Skip to content

Commit ba86331

Browse files
committed
WIP: Async load models
1 parent 59af3e1 commit ba86331

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

src/celengine/meshmanager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@ inline bool operator<(const GeometryInfo::ResourceKey& k0,
9797
std::tie(k1.resolvedPath, k1.center.x(), k1.center.y(), k1.center.z(), k1.scale, k1.isNormalized);
9898
}
9999

100-
using GeometryManager = ResourceManager<GeometryInfo>;
100+
using GeometryManager = ResourceManager<GeometryInfo, true>;
101101

102102
extern GeometryManager* GetGeometryManager();

src/celutil/resmanager.h

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma once
1111

1212
#include <map>
13+
#include <future>
1314
#include <memory>
1415
#include <utility>
1516
#include <vector>
@@ -18,16 +19,19 @@
1819
#include <celutil/reshandle.h>
1920

2021

21-
enum class ResourceState {
22+
enum class ResourceState
23+
{
2224
NotLoaded = 0,
2325
Loaded = 1,
2426
LoadingFailed = 2,
27+
LoadingAsync = 3,
2528
};
2629

2730

28-
template<class T> class ResourceManager
31+
template<class T, bool A = false> class ResourceManager
2932
{
30-
public:
33+
static constexpr bool async = A;
34+
public:
3135
explicit ResourceManager(const fs::path& _baseDir) : baseDir(_baseDir) {};
3236
~ResourceManager() = default;
3337

@@ -63,20 +67,25 @@ template<class T> class ResourceManager
6367
{
6468
loadResource(resources[h]);
6569
}
70+
else if (resources[h].state == ResourceState::LoadingAsync)
71+
{
72+
handleAsyncLoad(resources[h]);
73+
}
6674

6775
return resources[h].state == ResourceState::Loaded
6876
? resources[h].resource.get()
6977
: nullptr;
7078
}
7179

72-
private:
80+
private:
7381
using KeyType = typename T::ResourceKey;
7482

7583
struct InfoType
7684
{
7785
T info;
7886
ResourceState state{ ResourceState::NotLoaded };
7987
std::shared_ptr<ResourceType> resource{ nullptr };
88+
std::future<bool> future;
8089

8190
explicit InfoType(T _info) : info(std::move(_info)) {}
8291
InfoType(const InfoType&) = delete;
@@ -113,7 +122,39 @@ template<class T> class ResourceManager
113122
info.resource = std::move(resource);
114123
info.state = ResourceState::Loaded;
115124
}
116-
else if (info.load(resolvedKey))
125+
else
126+
{
127+
if constexpr (async)
128+
{
129+
info.future = std::async(std::launch::async, [&info, resolvedKey]()
130+
{
131+
return info.load(resolvedKey);
132+
});
133+
info.state = ResourceState::LoadingAsync;
134+
}
135+
else
136+
{
137+
bool good = info.load(resolvedKey);
138+
finish(good, info, resolvedKey);
139+
}
140+
}
141+
}
142+
143+
void handleAsyncLoad(InfoType& info)
144+
{
145+
if constexpr (async)
146+
{
147+
if (info.future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
148+
{
149+
bool good = info.future.get();
150+
finish(good, info, info.resolve(baseDir));
151+
}
152+
}
153+
}
154+
155+
void finish(bool good, InfoType& info, const KeyType &resolvedKey)
156+
{
157+
if (good)
117158
{
118159
info.state = ResourceState::Loaded;
119160
if (auto [iter, inserted] = loadedResources.try_emplace(std::move(resolvedKey), info.resource); !inserted)

0 commit comments

Comments
 (0)