feat: start loading some stuff async

This commit is contained in:
2026-10-24 01:29:00 +02:00
parent 9c5a97cfbd
commit aa3eef259c
6 changed files with 53 additions and 8 deletions
+1
View File
@@ -89,6 +89,7 @@ protected:
bool cleanedUp{false}; bool cleanedUp{false};
private: private:
void initDevices();
void processEvents(); void processEvents();
void runFixedSteps(); void runFixedSteps();
void handleSwapchainResize(bool& skipFrame); void handleSwapchainResize(bool& skipFrame);
+26 -3
View File
@@ -70,13 +70,11 @@ void App::init(const AppParams& params)
.maximized = params.startMaximized, .maximized = params.startMaximized,
}); });
gfxDevice.init(window.GetHandle(), params.appName, false); initDevices();
imguiPass.init(window.GetHandle(), gfxDevice); imguiPass.init(window.GetHandle(), gfxDevice);
resources.init(gfxDevice); resources.init(gfxDevice);
renderer.init(gfxDevice, resources, params.renderSize); renderer.init(gfxDevice, resources, params.renderSize);
InputManager::GetInstance().Init();
AudioSystem::GetInstance().Init();
Time::GetInstance().Update(); Time::GetInstance().Update();
customInitStarted = true; customInitStarted = true;
@@ -90,6 +88,31 @@ void App::init(const AppParams& params)
} }
} }
void App::initDevices()
{
ZoneScopedN("App::initDevices");
auto& jobs = JobSystem::GetInstance();
auto gfxInit = jobs.Async([this] { gfxDevice.init(window.GetHandle(), m_params.appName, false); });
auto audioInit = jobs.Async([] { AudioSystem::GetInstance().Init(); });
// SDL wants its subsystems initialised on the main thread
std::exception_ptr inputError;
try {
InputManager::GetInstance().Init();
} catch (...) {
inputError = std::current_exception();
}
// Wait for both before rethrowing anything, cleanup must not race a running init
gfxInit.wait();
audioInit.wait();
if (inputError) {
std::rethrow_exception(inputError);
}
gfxInit.get();
audioInit.get();
}
void App::attachLayer(std::unique_ptr<AppLayer> newLayer) void App::attachLayer(std::unique_ptr<AppLayer> newLayer)
{ {
if (layer) { if (layer) {
@@ -15,6 +15,7 @@
#include <destrum/Serialization/GlmJson.h> #include <destrum/Serialization/GlmJson.h>
#include <destrum/Serialization/MaterialSerialization.h> #include <destrum/Serialization/MaterialSerialization.h>
#include <destrum/Serialization/ObjectSerialization.h> #include <destrum/Serialization/ObjectSerialization.h>
#include <destrum/Threading/JobSystem.h>
using json = nlohmann::json; using json = nlohmann::json;
@@ -349,7 +350,5 @@ bool SceneSerializer::LoadFromJson(Scene& scene, const json& root) {
std::future<SceneSerializer::LoadResult> SceneSerializer::LoadSceneFileAsync( std::future<SceneSerializer::LoadResult> SceneSerializer::LoadSceneFileAsync(
const std::filesystem::path& path) { const std::filesystem::path& path) {
return std::async(std::launch::async, [path]() { return JobSystem::GetInstance().Async([path] { return LoadSceneFile(path); });
return LoadSceneFile(path);
});
} }
+2 -1
View File
@@ -15,6 +15,7 @@
#include <destrum/FS/AssetFS.h> #include <destrum/FS/AssetFS.h>
#include <destrum/Graphics/Material.h> #include <destrum/Graphics/Material.h>
#include <destrum/Serialization/MaterialSerialization.h> #include <destrum/Serialization/MaterialSerialization.h>
#include <destrum/Threading/JobSystem.h>
#include <destrum/Util/ImGuiUtils.h> #include <destrum/Util/ImGuiUtils.h>
namespace { namespace {
@@ -219,7 +220,7 @@ void AssetBrowser::StartCook()
return; return;
} }
m_Cook = std::async(std::launch::async, [commands = std::move(commands)] { m_Cook = JobSystem::GetInstance().Async([commands = std::move(commands)] {
bool succeeded = true; bool succeeded = true;
for (const std::string& command : commands) { for (const std::string& command : commands) {
succeeded = std::system(command.c_str()) == 0 && succeeded; succeeded = std::system(command.c_str()) == 0 && succeeded;
+3 -1
View File
@@ -6,6 +6,8 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <destrum/Threading/JobSystem.h>
namespace { namespace {
constexpr float PollInterval = 0.5f; constexpr float PollInterval = 0.5f;
@@ -48,7 +50,7 @@ void ShaderHotReload::StartCook()
// cmd.exe strips the outer quotes, the inner ones keep paths with spaces intact // cmd.exe strips the outer quotes, the inner ones keep paths with spaces intact
const std::string command = "\"\"" + m_Cooker.string() + "\" --input \"" + m_SourceRoot.string() + const std::string command = "\"\"" + m_Cooker.string() + "\" --input \"" + m_SourceRoot.string() +
"\" --output \"" + m_RuntimeRoot.string() + "\"\""; "\" --output \"" + m_RuntimeRoot.string() + "\"\"";
m_Cook = std::async(std::launch::async, [command] { return std::system(command.c_str()); }); m_Cook = JobSystem::GetInstance().Async([command] { return std::system(command.c_str()); });
spdlog::info("Shader sources changed, cooking engine assets"); spdlog::info("Shader sources changed, cooking engine assets");
} }
+19
View File
@@ -1,9 +1,12 @@
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
#include <filesystem>
#include <fstream>
#include <stdexcept> #include <stdexcept>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <destrum/Serialization/SceneSerializer.h>
#include <destrum/Threading/JobSystem.h> #include <destrum/Threading/JobSystem.h>
#include "TestUtils.h" #include "TestUtils.h"
@@ -143,6 +146,21 @@ namespace {
check(!Jobs().IsRunning(), "job system should be stopped"); check(!Jobs().IsRunning(), "job system should be stopped");
} }
void testLoadSceneFileAsync()
{
Jobs().Init(2);
const auto path = std::filesystem::temp_directory_path() / "destrum_async_scene.json";
std::ofstream{path} << R"({"version":2,"name":"async","objects":[]})";
auto good = SceneSerializer::LoadSceneFileAsync(path);
auto missing = SceneSerializer::LoadSceneFileAsync(path.parent_path() / "destrum_no_such_scene.json");
check(good.get().success, "async scene load should parse a valid file");
check(!missing.get().success, "async scene load should report a missing file");
std::filesystem::remove(path);
Jobs().Shutdown();
}
void testRunsInlineWhenStopped() void testRunsInlineWhenStopped()
{ {
check(!Jobs().IsRunning(), "job system should start stopped"); check(!Jobs().IsRunning(), "job system should start stopped");
@@ -164,4 +182,5 @@ void RunJobsTests()
testAsyncRethrows(); testAsyncRethrows();
testMainThreadQueue(); testMainThreadQueue();
testShutdownDrainsPendingJobs(); testShutdownDrainsPendingJobs();
testLoadSceneFileAsync();
} }