Skip to content

Commit

Permalink
Make manual resource reimport from UI asynchronous
Browse files Browse the repository at this point in the history
  • Loading branch information
Benualdo committed Jan 11, 2025
1 parent f39afb1 commit cc11b06
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/core/IResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ namespace vg::core
virtual void UpdateResources(bool _async = true) = 0;

// Force reimport specific resource
virtual void Reimport(IResource * _res) = 0;
virtual void Reimport(IResource * _res, bool _async = true) = 0;
};
}
4 changes: 2 additions & 2 deletions src/engine/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ namespace vg::engine
//--------------------------------------------------------------------------------------
void Engine::FlushLoading()
{
m_resourceManager->updateLoading();
m_resourceManager->updateLoadingMainThread();
}

//--------------------------------------------------------------------------------------
Expand Down Expand Up @@ -802,7 +802,7 @@ namespace vg::engine
}

m_resourceManager->flushUpdateResource();
m_resourceManager->updateLoading();
m_resourceManager->updateLoadingMainThread();

const float scaledDeltaTime = m_time.m_scaledDeltaTime;
const float realDeltaTime = m_time.m_realDeltaTime;
Expand Down
7 changes: 5 additions & 2 deletions src/engine/Resource/ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ namespace vg::engine
void SetResourceMeta (const core::string & _resourcePath, core::IResourceMeta * _meta) final override;

void UpdateResources (bool _async = true) final override;
void Reimport (core::IResource * _res) final override;
void Reimport (core::IResource * _res, bool _async) final override;

void LoadResourceAsync (core::IResource * _resource, const core::string & _oldPath, const core::string & _path) final override;
void UnloadResource (core::IResource * _resource, const core::string & _path) final override ;

void updateLoading ();
void updateLoadingMainThread ();
void flushPendingLoading ();

bool isLoadingThreadRunning () const { return m_isLoadingThreadRunning; }
Expand All @@ -67,6 +67,7 @@ namespace vg::engine
void loadOneResource (ResourceInfo & _info);

core::uint updateResources ();
void reimport (core::IResource * _res);

private:
std::thread m_loadingThread;
Expand All @@ -80,6 +81,8 @@ namespace vg::engine
core::vector<core::IResource*> m_resourcesLoaded;
core::vector<core::IResource *> m_resourcesLoadedAsync;

core::vector<core::IResource *> m_resourcesToReimport;

mutable core::RecursiveMutex m_addResourceToLoadRecursiveMutex = core::RecursiveMutex("RecursiveMutex - AddResourceToLoad");
mutable core::Mutex m_resourceLoadedAsyncMutex = core::Mutex("Mutex - ResourceLoaded");

Expand Down
118 changes: 66 additions & 52 deletions src/engine/Resource/ResourceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

using namespace vg::core;

#define VG_RESOURCE_MANAGER_ASYNC_LOADING 1

namespace vg::engine
{
VG_REGISTER_OBJECT_CLASS(ResourceManager, "Resource Manager");
Expand Down Expand Up @@ -195,8 +193,19 @@ namespace vg::engine
}

//--------------------------------------------------------------------------------------
void ResourceManager::Reimport(core::IResource * _res)
void ResourceManager::Reimport(core::IResource * _res, bool _async)
{
if (_async)
m_resourcesToReimport.push_back(_res);
else
reimport(_res);
}

//--------------------------------------------------------------------------------------
void ResourceManager::reimport(core::IResource * _res)
{
VG_ASSERT(Scheduler::get()->IsMainThread());

// Unloading resources will remove entries in the resourceMap so we need to copy the existing resources to iterate over
vector<ResourceInfo *> allResourceInfos;
for (auto pair : m_resourceInfosMap)
Expand Down Expand Up @@ -252,16 +261,13 @@ namespace vg::engine
//--------------------------------------------------------------------------------------
void ResourceManager::loading(ResourceManager * _this)
{
#if VG_RESOURCE_MANAGER_ASYNC_LOADING

Kernel::getScheduler()->RegisterCurrentThread("Loading", ThreadType::Loading, 0, 1);

while (_this->isLoadingThreadRunning())
{
_this->updateLoading(true);
Sleep(1);
}
#endif
}

//--------------------------------------------------------------------------------------
Expand All @@ -277,6 +283,8 @@ namespace vg::engine
//--------------------------------------------------------------------------------------
void ResourceManager::updateLoading(bool _async)
{
VG_ASSERT(Scheduler::get()->IsLoadingThread());

lock_guard lock(m_addResourceToLoadRecursiveMutex);

auto resourcesToLoad = std::move(m_resourcesToLoad);
Expand Down Expand Up @@ -305,8 +313,10 @@ namespace vg::engine
//--------------------------------------------------------------------------------------
void ResourceManager::LoadResourceAsync(IResource * _resource, const core::string & _oldPath, const string & _newPath)
{
VG_ASSERT(Scheduler::get()->IsMainThread() || Scheduler::get()->IsLoadingThread());
VG_ASSERT(_resource->GetParent() != nullptr);
VG_ASSERT(_resource->GetResourcePath() == _newPath); // TODO: get rid of the '_newPath' parameter?

lock_guard lock(m_addResourceToLoadRecursiveMutex);

const auto * options = EngineOptions::get();
Expand Down Expand Up @@ -352,44 +362,44 @@ namespace vg::engine

m_resourceInfosMap.insert(make_pair(_newPath, info));

if (options->useResourceLoadingPriority())
{
const Priority priority = _resource->GetClassDesc()->GetPriority();
uint index = -1;
for (uint i = 0; i < m_resourcesToLoad.size(); ++i)
{
const auto * res = m_resourcesToLoad[i];
if (priority < res->GetClassDesc()->GetPriority())
{
m_resourcesToLoad.insert(m_resourcesToLoad.begin() + i, _resource);
index = i;
break;
}
}
if (-1 == index)
{
m_resourcesToLoad.emplace_back(_resource);
index = (uint)(m_resourcesToLoad.size() - 1);
}

#if VG_DEBUG0
VG_DEBUGPRINT("\n");
VG_DEBUGPRINT("NEW | INDEX | PRIORITY | TYPE | PATH\n", m_resourcesToLoad.size());
VG_DEBUGPRINT("----+-------+----------+-----------+---------------------------------\n");
for (uint i = 0; i < m_resourcesToLoad.size(); ++i)
{
const auto * res = m_resourcesToLoad[i];
string shortTypeName = res->GetClassDesc()->GetClassName();
auto resPos = shortTypeName.find("Resource");
if (-1 != resPos)
shortTypeName = shortTypeName.substr(0, resPos);
VG_DEBUGPRINT("%s | %5u | %8i | %9s | \"%s\"\n", res == _resource ? "==>" : " ", i, res->GetClassDesc()->GetPriority(), shortTypeName.c_str(), res->GetResourcePath().c_str());
}
VG_DEBUGPRINT("\n");
#endif

}
else
//if (options->useResourceLoadingPriority())
//{
// const Priority priority = _resource->GetClassDesc()->GetPriority();
// uint index = -1;
// for (uint i = 0; i < m_resourcesToLoad.size(); ++i)
// {
// const auto * res = m_resourcesToLoad[i];
// if (priority < res->GetClassDesc()->GetPriority())
// {
// m_resourcesToLoad.insert(m_resourcesToLoad.begin() + i, _resource);
// index = i;
// break;
// }
// }
// if (-1 == index)
// {
// m_resourcesToLoad.emplace_back(_resource);
// index = (uint)(m_resourcesToLoad.size() - 1);
// }
//
// #if VG_DEBUG0
// VG_DEBUGPRINT("\n");
// VG_DEBUGPRINT("NEW | INDEX | PRIORITY | TYPE | PATH\n", m_resourcesToLoad.size());
// VG_DEBUGPRINT("----+-------+----------+-----------+---------------------------------\n");
// for (uint i = 0; i < m_resourcesToLoad.size(); ++i)
// {
// const auto * res = m_resourcesToLoad[i];
// string shortTypeName = res->GetClassDesc()->GetClassName();
// auto resPos = shortTypeName.find("Resource");
// if (-1 != resPos)
// shortTypeName = shortTypeName.substr(0, resPos);
// VG_DEBUGPRINT("%s | %5u | %8i | %9s | \"%s\"\n", res == _resource ? "==>" : " ", i, res->GetClassDesc()->GetPriority(), shortTypeName.c_str(), res->GetResourcePath().c_str());
// }
// VG_DEBUGPRINT("\n");
// #endif
//
//}
//else
{
m_resourcesToLoad.emplace_back(_resource);
}
Expand Down Expand Up @@ -465,6 +475,8 @@ namespace vg::engine
//--------------------------------------------------------------------------------------
void ResourceManager::loadOneResource(ResourceInfo & _info)
{
VG_ASSERT(Scheduler::get()->IsLoadingThread());

// get shared resource info
auto & clients = _info.m_clients;
const string & path = _info.m_path;
Expand Down Expand Up @@ -540,18 +552,25 @@ namespace vg::engine
}

//--------------------------------------------------------------------------------------
void ResourceManager::updateLoading()
void ResourceManager::updateLoadingMainThread()
{
VG_PROFILE_CPU("UpdateLoading");
VG_PROFILE_CPU("Loading");
VG_ASSERT(Scheduler::get()->IsMainThread());

static u32 skipFrames = 2;
if (skipFrames != 0)
{
--skipFrames;
return;
}

// Update resources to reimport
{
for (uint i = 0; i < m_resourcesToReimport.size(); ++i)
reimport(m_resourcesToReimport[i]);
m_resourcesToReimport.clear();
}

#if VG_RESOURCE_MANAGER_ASYNC_LOADING
// Add resources that were loaded async during previous frames
{
lock_guard lock(m_resourceLoadedAsyncMutex);
Expand All @@ -568,7 +587,6 @@ namespace vg::engine
m_resourcesLoadedAsync.clear();
}
}
#endif

// Sync point to notify resource loaded last frame
for (uint i = 0; i < m_resourcesLoaded.size(); ++i)
Expand Down Expand Up @@ -607,10 +625,6 @@ namespace vg::engine
}
}
}

#if !VG_RESOURCE_MANAGER_ASYNC_LOADING
updateLoading(false);
#endif
}

//--------------------------------------------------------------------------------------
Expand Down

0 comments on commit cc11b06

Please sign in to comment.