add background assets loader

This commit is contained in:
MihailRis 2026-01-23 22:40:57 +03:00
parent 245e040a1c
commit 0cf7d9b1ed
9 changed files with 104 additions and 46 deletions

View file

@ -319,28 +319,27 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
} }
bool AssetsLoader::loadExternalTexture( bool AssetsLoader::loadExternalTexture(
Assets* assets, AssetsLoader& loader,
const std::string& name, const std::string& name,
const std::vector<io::path>& alternatives const std::vector<io::path>& alternatives
) { ) {
if (assets->get<Texture>(name) != nullptr) { if (loader.getAssets().get<Texture>(name) != nullptr) {
return true; return true;
} }
for (auto& path : alternatives) { for (auto& path : alternatives) {
if (io::exists(path)) { logger.info() << (path.string() + ".png");
try { if (io::exists(path.string() + ".png")) {
auto image = imageio::read(path); loader.add(AssetType::TEXTURE, path.string(), name, nullptr);
assets->store(Texture::from(image.get()), name); return true; // TODO: fallbacks support
return true;
} catch (const std::exception& err) {
logger.error() << "error while loading external "
<< path.string() << ": " << err.what();
}
} }
} }
return false; return false;
} }
Assets& AssetsLoader::getAssets() {
return assets;
}
Engine& AssetsLoader::getEngine() { Engine& AssetsLoader::getEngine() {
return engine; return engine;
} }
@ -376,6 +375,15 @@ std::shared_ptr<Task> AssetsLoader::startTask(runnable onDone) {
[this](const assetload::postfunc& func) { func(&assets); } [this](const assetload::postfunc& func) { func(&assets); }
); );
pool->setOnComplete(std::move(onDone)); pool->setOnComplete(std::move(onDone));
pool->setJobsSource([this]() -> std::optional<aloader_entry> {
if (entries.empty()) {
return std::nullopt;
}
aloader_entry entry = std::move(entries.front());
entries.pop();
return entry;
});
while (!entries.empty()) { while (!entries.empty()) {
aloader_entry entry = std::move(entries.front()); aloader_entry entry = std::move(entries.front());
entries.pop(); entries.pop();

View file

@ -124,10 +124,11 @@ public:
static void addDefaults(AssetsLoader& loader, const Content* content); static void addDefaults(AssetsLoader& loader, const Content* content);
static bool loadExternalTexture( static bool loadExternalTexture(
Assets* assets, AssetsLoader& loader,
const std::string& name, const std::string& name,
const std::vector<io::path>& alternatives const std::vector<io::path>& alternatives
); );
Assets& getAssets();
Engine& getEngine(); Engine& getEngine();
}; };

View file

@ -1,13 +1,12 @@
#include "AssetsManagement.hpp" #include "AssetsManagement.hpp"
#include "assets/Assets.hpp"
#include "assets/AssetsLoader.hpp" #include "assets/AssetsLoader.hpp"
#include "engine/Engine.hpp"
#include "debug/Logger.hpp"
#include "content/Content.hpp"
#include "graphics/core/Shader.hpp"
#include "EnginePaths.hpp"
#include "coders/GLSLExtension.hpp" #include "coders/GLSLExtension.hpp"
#include "content/Content.hpp"
#include "debug/Logger.hpp"
#include "engine/Engine.hpp"
#include "EnginePaths.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/render/ModelsGenerator.hpp" #include "graphics/render/ModelsGenerator.hpp"
#include "graphics/ui/GUI.hpp" #include "graphics/ui/GUI.hpp"
@ -15,6 +14,10 @@ static debug::Logger logger("assets-management");
AssetsManagement::AssetsManagement(Engine& engine) : engine(engine) {} AssetsManagement::AssetsManagement(Engine& engine) : engine(engine) {}
AssetsManagement::~AssetsManagement() {
finishBackgroundLoader();
}
const Assets* AssetsManagement::getStorage() const { const Assets* AssetsManagement::getStorage() const {
return assets.get(); return assets.get();
} }
@ -23,7 +26,23 @@ Assets* AssetsManagement::getStorage() {
return assets.get(); return assets.get();
} }
AssetsLoader& AssetsManagement::acquireBackgroundLoader() {
if (backgroundLoader) {
return *backgroundLoader;
}
if (assets == nullptr) {
throw std::runtime_error("no assets storage available");
}
backgroundLoader = std::make_unique<AssetsLoader>(
engine, *assets, engine.getResPaths()
);
backgroundLoaderTask = backgroundLoader->startTask(nullptr);
return *backgroundLoader;
}
void AssetsManagement::loadAssets(Content* content) { void AssetsManagement::loadAssets(Content* content) {
finishBackgroundLoader();
const auto& paths = engine.getPaths(); const auto& paths = engine.getPaths();
logger.info() << "loading assets"; logger.info() << "loading assets";
Shader::preprocessor->setPaths(&paths.resPaths); Shader::preprocessor->setPaths(&paths.resPaths);
@ -51,3 +70,17 @@ void AssetsManagement::loadAssets(Content* content) {
assets->setup(); assets->setup();
engine.getGUI().onAssetsLoad(assets.get()); engine.getGUI().onAssetsLoad(assets.get());
} }
void AssetsManagement::update() {
if (backgroundLoaderTask) {
backgroundLoaderTask->update();
}
}
void AssetsManagement::finishBackgroundLoader() {
if (backgroundLoaderTask == nullptr) {
return;
}
backgroundLoaderTask.reset();
backgroundLoader.reset();
}

View file

@ -1,22 +1,31 @@
#pragma once #pragma once
#include "assets/Assets.hpp"
#include <memory> #include <memory>
class Assets;
class AssetsLoader; class AssetsLoader;
class Engine; class Engine;
class Content; class Content;
class Task;
class AssetsManagement { class AssetsManagement final {
public: public:
AssetsManagement(Engine& engine); AssetsManagement(Engine& engine);
~AssetsManagement();
void loadAssets(Content* content); void loadAssets(Content* content);
void update();
Assets* getStorage(); Assets* getStorage();
const Assets* getStorage() const; const Assets* getStorage() const;
AssetsLoader& acquireBackgroundLoader();
private: private:
void finishBackgroundLoader();
Engine& engine; Engine& engine;
std::unique_ptr<Assets> assets; std::unique_ptr<Assets> assets;
std::unique_ptr<AssetsLoader> backgroundLoader; std::unique_ptr<AssetsLoader> backgroundLoader;
std::shared_ptr<Task> backgroundLoaderTask;
}; };

View file

@ -4,48 +4,45 @@
#define GLEW_STATIC #define GLEW_STATIC
#endif #endif
#include "debug/Logger.hpp" #include "AssetsManagement.hpp"
#include "assets/AssetsLoader.hpp"
#include "audio/audio.hpp" #include "audio/audio.hpp"
#include "coders/commons.hpp"
#include "coders/GLSLExtension.hpp" #include "coders/GLSLExtension.hpp"
#include "coders/toml.hpp" #include "coders/toml.hpp"
#include "coders/commons.hpp"
#include "devtools/Editor.hpp"
#include "devtools/Project.hpp"
#include "devtools/DebuggingServer.hpp"
#include "content/ContentControl.hpp" #include "content/ContentControl.hpp"
#include "core_defs.hpp" #include "core_defs.hpp"
#include "io/io.hpp" #include "debug/Logger.hpp"
#include "io/settings_io.hpp" #include "devtools/DebuggingServer.hpp"
#include "devtools/Editor.hpp"
#include "devtools/Project.hpp"
#include "EnginePaths.hpp"
#include "frontend/locale.hpp" #include "frontend/locale.hpp"
#include "frontend/menu.hpp" #include "frontend/menu.hpp"
#include "frontend/screens/Screen.hpp" #include "frontend/screens/Screen.hpp"
#include "graphics/render/ModelsGenerator.hpp"
#include "graphics/core/DrawContext.hpp" #include "graphics/core/DrawContext.hpp"
#include "graphics/core/Shader.hpp" #include "graphics/core/Shader.hpp"
#include "graphics/ui/GUI.hpp"
#include "graphics/ui/elements/Menu.hpp" #include "graphics/ui/elements/Menu.hpp"
#include "logic/EngineController.hpp" #include "graphics/ui/GUI.hpp"
#include "io/io.hpp"
#include "io/settings_io.hpp"
#include "logic/CommandsInterpreter.hpp" #include "logic/CommandsInterpreter.hpp"
#include "logic/scripting/scripting.hpp" #include "logic/EngineController.hpp"
#include "logic/scripting/scripting_hud.hpp" #include "logic/scripting/scripting_hud.hpp"
#include "logic/scripting/scripting.hpp"
#include "Mainloop.hpp"
#include "network/Network.hpp" #include "network/Network.hpp"
#include "ServerMainloop.hpp"
#include "util/platform.hpp" #include "util/platform.hpp"
#include "util/stringutil.hpp"
#include "window/input.hpp" #include "window/input.hpp"
#include "window/Window.hpp" #include "window/Window.hpp"
#include "world/Level.hpp"
#include "AssetsManagement.hpp"
#include "Mainloop.hpp"
#include "ServerMainloop.hpp"
#include "WindowControl.hpp" #include "WindowControl.hpp"
#include "EnginePaths.hpp" #include "world/Level.hpp"
#include <iostream>
#include <assert.h> #include <assert.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <unordered_set> #include <unordered_set>
#include <functional> #include <functional>
#include <utility>
static debug::Logger logger("engine"); static debug::Logger logger("engine");
@ -266,6 +263,7 @@ void Engine::applicationTick() {
void Engine::updateFrontend() { void Engine::updateFrontend() {
double delta = time.getDelta(); double delta = time.getDelta();
assets->update();
updateHotkeys(); updateHotkeys();
audio::update(delta); audio::update(delta);
gui->act(delta, window->getSize()); gui->act(delta, window->getSize());
@ -421,6 +419,10 @@ Assets* Engine::getAssets() {
return assets->getStorage(); return assets->getStorage();
} }
AssetsLoader& Engine::acquireBackgroundLoader() {
return assets->acquireBackgroundLoader();
}
EnginePaths& Engine::getPaths() { EnginePaths& Engine::getPaths() {
return *paths; return *paths;
} }

View file

@ -10,6 +10,7 @@
#include <string> #include <string>
class Assets; class Assets;
class AssetsLoader;
class AssetsManagement; class AssetsManagement;
class ContentControl; class ContentControl;
class EngineController; class EngineController;
@ -110,6 +111,8 @@ public:
/// @brief Get active assets storage instance /// @brief Get active assets storage instance
Assets* getAssets(); Assets* getAssets();
AssetsLoader& acquireBackgroundLoader();
/// @brief Get writeable engine settings structure instance /// @brief Get writeable engine settings structure instance
EngineSettings& getSettings(); EngineSettings& getSettings();

View file

@ -274,6 +274,9 @@ ResPaths::ResPaths(std::vector<PathsRoot> roots)
} }
io::path ResPaths::find(const std::string& filename) const { io::path ResPaths::find(const std::string& filename) const {
if (filename.find(':') != std::string::npos) {
return filename;
}
for (int i = roots.size() - 1; i >= 0; i--) { for (int i = roots.size() - 1; i >= 0; i--) {
auto& root = roots[i]; auto& root = roots[i];
auto file = root.path / filename; auto file = root.path / filename;

View file

@ -87,10 +87,10 @@ static int l_pack_get_info(
lua::setfield(L, "path"); lua::setfield(L, "path");
if (!engine->isHeadless()) { if (!engine->isHeadless()) {
auto assets = engine->getAssets(); auto& assetsLoader = engine->acquireBackgroundLoader();
std::string icon = pack.id + ".icon"; std::string icon = pack.id + ".icon";
if (!AssetsLoader::loadExternalTexture( if (!AssetsLoader::loadExternalTexture(
assets, icon, {pack.folder / "icon.png"} assetsLoader, icon, {pack.folder / "icon"}
)) { )) {
icon = "gui/no_icon"; icon = "gui/no_icon";
} }

View file

@ -56,13 +56,12 @@ static int l_get_list(lua::State* L) {
lua::pushstring(L, name); lua::pushstring(L, name);
lua::setfield(L, "name"); lua::setfield(L, "name");
auto assets = engine->getAssets();
std::string icon = "world#" + name + ".icon"; std::string icon = "world#" + name + ".icon";
if (!engine->isHeadless() && !AssetsLoader::loadExternalTexture( if (!engine->isHeadless() && !AssetsLoader::loadExternalTexture(
assets, engine->acquireBackgroundLoader(),
icon, icon,
{worlds[i] / "icon.png", {worlds[i] / "icon",
worlds[i] / "preview.png"} worlds[i] / "preview"}
)) { )) {
icon = "gui/no_world_icon"; icon = "gui/no_world_icon";
} }