diff --git a/src/assets/Assets.cpp b/src/assets/Assets.cpp index 993e7360c..3e0776747 100644 --- a/src/assets/Assets.cpp +++ b/src/assets/Assets.cpp @@ -1,6 +1,19 @@ #include "Assets.hpp" -Assets::~Assets() = default; +Assets::Assets(util::ObjectsKeeper* vault) : vault(vault) { +} + +Assets::~Assets() { + if (vault == nullptr) { + return; + } + for (auto& [_, map] : assets) { + for (auto& [__, asset] : map) { + vault->keepAlive(std::move(asset)); + } + map.clear(); + } +} const std::vector& Assets::getAnimations() { return animations; diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index ea0753aec..b9faa877f 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -12,6 +12,7 @@ #include #include "util/stringutil.hpp" +#include "util/ObjectsKeeper.hpp" #include "graphics/core/TextureAnimation.hpp" class Assets; @@ -64,13 +65,14 @@ namespace assetload { } class Assets { + util::ObjectsKeeper* vault; std::vector animations; using assets_map = std::unordered_map>; std::unordered_map assets; std::vector setupFuncs; public: - Assets() = default; + Assets(util::ObjectsKeeper* vault); Assets(const Assets&) = delete; ~Assets(); @@ -79,12 +81,20 @@ public: template void store(std::unique_ptr asset, const std::string& name) { - assets[typeid(T)][name].reset(asset.release()); + auto& dst = assets[typeid(T)][name]; + if (vault != nullptr && dst != nullptr) { + vault->keepAlive(std::move(dst)); + } + dst.reset(asset.release()); } template void store(std::shared_ptr asset, const std::string& name) { - assets[typeid(T)][name] = std::move(asset); + auto& dst = assets[typeid(T)][name]; + if (vault != nullptr && dst != nullptr) { + vault->keepAlive(std::move(dst)); + } + dst = std::move(asset); } template diff --git a/src/engine/AssetsManagement.cpp b/src/engine/AssetsManagement.cpp index 578a0e45b..1ca1935c9 100644 --- a/src/engine/AssetsManagement.cpp +++ b/src/engine/AssetsManagement.cpp @@ -51,7 +51,9 @@ void AssetsManagement::loadAssets(Content* content) { logger.info() << "loading assets"; Shader::preprocessor->setPaths(&paths.resPaths); - auto new_assets = std::make_unique(); + auto new_assets = std::make_unique( + settings.system.preserveAssetsDuringFrame.get() ? &assetsVault : nullptr + ); AssetsLoader loader(engine, *new_assets, paths.resPaths); AssetsLoader::addDefaults(loader, content); @@ -78,6 +80,7 @@ void AssetsManagement::loadAssets(Content* content) { } void AssetsManagement::update() { + assetsVault.clearKeepedObjects(); if (backgroundLoaderTask) { backgroundLoaderTask->update(); } diff --git a/src/engine/AssetsManagement.hpp b/src/engine/AssetsManagement.hpp index 4e14c9305..81c33bef8 100644 --- a/src/engine/AssetsManagement.hpp +++ b/src/engine/AssetsManagement.hpp @@ -1,6 +1,7 @@ #pragma once #include "assets/Assets.hpp" +#include "util/ObjectsKeeper.hpp" #include @@ -30,4 +31,5 @@ private: std::unique_ptr assets; std::unique_ptr backgroundLoader; std::shared_ptr backgroundLoaderTask; + util::ObjectsKeeper assetsVault; }; diff --git a/src/io/settings_io.cpp b/src/io/settings_io.cpp index af4547a14..c66b5c451 100644 --- a/src/io/settings_io.cpp +++ b/src/io/settings_io.cpp @@ -100,6 +100,7 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { builder.addSection("system"); builder.add("max-bg-asset-loaders", &settings.system.maxBgAssetLoaders); + builder.add("preserve-assets-during-frame", &settings.system.preserveAssetsDuringFrame); } dv::value SettingsHandler::getValue(const std::string& name) const { diff --git a/src/settings.hpp b/src/settings.hpp index 331ff3ee8..782330f14 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -122,7 +122,10 @@ struct NetworkSettings { }; struct SystemSettings { + /// @brief Max background assets loaders IntegerSetting maxBgAssetLoaders {3, -4, 16}; + /// @brief Preserve assets during current frame from being destroyed + FlagSetting preserveAssetsDuringFrame {true}; }; struct EngineSettings {