Skip to content

Commit

Permalink
WIP: Async load models
Browse files Browse the repository at this point in the history
  • Loading branch information
375gnu committed Dec 24, 2023
1 parent 59af3e1 commit ba86331
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/celengine/meshmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ inline bool operator<(const GeometryInfo::ResourceKey& k0,
std::tie(k1.resolvedPath, k1.center.x(), k1.center.y(), k1.center.z(), k1.scale, k1.isNormalized);
}

using GeometryManager = ResourceManager<GeometryInfo>;
using GeometryManager = ResourceManager<GeometryInfo, true>;

extern GeometryManager* GetGeometryManager();
51 changes: 46 additions & 5 deletions src/celutil/resmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#pragma once

#include <map>
#include <future>
#include <memory>
#include <utility>
#include <vector>
Expand All @@ -18,16 +19,19 @@
#include <celutil/reshandle.h>


enum class ResourceState {
enum class ResourceState
{
NotLoaded = 0,
Loaded = 1,
LoadingFailed = 2,
LoadingAsync = 3,
};


template<class T> class ResourceManager
template<class T, bool A = false> class ResourceManager
{
public:
static constexpr bool async = A;
public:
explicit ResourceManager(const fs::path& _baseDir) : baseDir(_baseDir) {};
~ResourceManager() = default;

Expand Down Expand Up @@ -63,20 +67,25 @@ template<class T> class ResourceManager
{
loadResource(resources[h]);
}
else if (resources[h].state == ResourceState::LoadingAsync)
{
handleAsyncLoad(resources[h]);
}

return resources[h].state == ResourceState::Loaded
? resources[h].resource.get()
: nullptr;
}

private:
private:
using KeyType = typename T::ResourceKey;

struct InfoType
{
T info;
ResourceState state{ ResourceState::NotLoaded };
std::shared_ptr<ResourceType> resource{ nullptr };
std::future<bool> future;

explicit InfoType(T _info) : info(std::move(_info)) {}
InfoType(const InfoType&) = delete;
Expand Down Expand Up @@ -113,7 +122,39 @@ template<class T> class ResourceManager
info.resource = std::move(resource);
info.state = ResourceState::Loaded;
}
else if (info.load(resolvedKey))
else
{
if constexpr (async)
{
info.future = std::async(std::launch::async, [&info, resolvedKey]()
{
return info.load(resolvedKey);
});
info.state = ResourceState::LoadingAsync;
}
else
{
bool good = info.load(resolvedKey);
finish(good, info, resolvedKey);
}
}
}

void handleAsyncLoad(InfoType& info)
{
if constexpr (async)
{
if (info.future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
bool good = info.future.get();
finish(good, info, info.resolve(baseDir));
}
}
}

void finish(bool good, InfoType& info, const KeyType &resolvedKey)
{
if (good)
{
info.state = ResourceState::Loaded;
if (auto [iter, inserted] = loadedResources.try_emplace(std::move(resolvedKey), info.resource); !inserted)
Expand Down

0 comments on commit ba86331

Please sign in to comment.