cleanup AssetsLoader a bit

This commit is contained in:
MihailRis 2026-08-25 22:30:09 +03:00
parent ab3c1e1b0c
commit ce068790c1
6 changed files with 86 additions and 80 deletions

View file

@ -1,5 +1,9 @@
#pragma once #pragma once
#include "util/stringutil.hpp"
#include "util/ObjectsKeeper.hpp"
#include "graphics/core/TextureAnimation.hpp"
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -11,10 +15,6 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "util/stringutil.hpp"
#include "util/ObjectsKeeper.hpp"
#include "graphics/core/TextureAnimation.hpp"
class Assets; class Assets;
enum class AssetType { enum class AssetType {
@ -31,12 +31,12 @@ enum class AssetType {
namespace assetload { namespace assetload {
/// @brief final work to do in the main thread /// @brief final work to do in the main thread
using postfunc = std::function<void(Assets*)>; using postfunc = std::function<void(Assets&)>;
using setupfunc = std::function<void(const Assets*)>; using setupfunc = std::function<void(const Assets&)>;
template <class T> template <class T>
void assets_setup(const Assets*); void assets_setup(const Assets&);
class error : public std::runtime_error { class error : public std::runtime_error {
AssetType type; AssetType type;
@ -145,7 +145,7 @@ public:
void setup() { void setup() {
for (auto& setupFunc : setupFuncs) { for (auto& setupFunc : setupFuncs) {
setupFunc(this); setupFunc(*this);
} }
} }
@ -155,8 +155,8 @@ public:
}; };
template <class T> template <class T>
void assetload::assets_setup(const Assets* assets) { void assetload::assets_setup(const Assets& assets) {
if (auto mapPtr = assets->getMap<T>()) { if (auto mapPtr = assets.getMap<T>()) {
for (const auto& entry : **mapPtr) { for (const auto& entry : **mapPtr) {
static_cast<T*>(entry.second.get())->setup(); static_cast<T*>(entry.second.get())->setup();
} }

View file

@ -79,8 +79,8 @@ void AssetsLoader::loadNext() {
try { try {
aloader_func loader = getLoader(entry.tag); aloader_func loader = getLoader(entry.tag);
auto postfunc = auto postfunc =
loader(this, paths, entry.filename, entry.alias, entry.config); loader(*this, paths, entry.filename, entry.alias, entry.config);
postfunc(&assets); postfunc(assets);
} catch (const parsing_error& err) { } catch (const parsing_error& err) {
error = err.errorLog(); error = err.errorLog();
} catch (const std::runtime_error& err) { } catch (const std::runtime_error& err) {
@ -361,17 +361,17 @@ const ResPaths& AssetsLoader::getPaths() const {
} }
class LoaderWorker : public util::Worker<aloader_entry, assetload::postfunc> { class LoaderWorker : public util::Worker<aloader_entry, assetload::postfunc> {
AssetsLoader* loader; AssetsLoader& loader;
public: public:
LoaderWorker(AssetsLoader* loader) : loader(loader) { LoaderWorker(AssetsLoader& loader) : loader(loader) {
} }
assetload::postfunc operator()(const aloader_entry& entry assetload::postfunc operator()(const aloader_entry& entry
) override { ) override {
aloader_func loadfunc = loader->getLoader(entry.tag); aloader_func loadfunc = loader.getLoader(entry.tag);
return loadfunc( return loadfunc(
loader, loader,
loader->getPaths(), loader.getPaths(),
entry.filename, entry.filename,
entry.alias, entry.alias,
entry.config entry.config
@ -383,8 +383,8 @@ std::shared_ptr<Task> AssetsLoader::startTask(runnable onDone, int maxWorkers) {
auto pool = auto pool =
std::make_shared<util::ThreadPool<aloader_entry, assetload::postfunc>>( std::make_shared<util::ThreadPool<aloader_entry, assetload::postfunc>>(
"assets-loader-pool", "assets-loader-pool",
[=]() { return std::make_unique<LoaderWorker>(this); }, [=]() { return std::make_unique<LoaderWorker>(*this); },
[this](const assetload::postfunc& func) { func(&assets); }, [this](const assetload::postfunc& func) { func(assets); },
maxWorkers maxWorkers
); );
pool->setOnComplete(std::move(onDone)); pool->setOnComplete(std::move(onDone));

View file

@ -72,7 +72,7 @@ struct ModelCfg : AssetCfg {
using aloader_func = std::function< using aloader_func = std::function<
assetload:: assetload::
postfunc(AssetsLoader*, const ResPaths&, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>; postfunc(AssetsLoader&, const ResPaths&, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>;
struct aloader_entry { struct aloader_entry {
AssetType tag; AssetType tag;
@ -99,6 +99,8 @@ class AssetsLoader {
void processPreloadConfigs(const Content* content); void processPreloadConfigs(const Content* content);
public: public:
AssetsLoader(Engine& engine, Assets& assets, const ResPaths& paths); AssetsLoader(Engine& engine, Assets& assets, const ResPaths& paths);
AssetsLoader(const AssetsLoader&) = delete;
void addLoader(AssetType tag, aloader_func func); void addLoader(AssetType tag, aloader_func func);
/// @brief Enqueue asset load /// @brief Enqueue asset load

View file

@ -35,8 +35,8 @@ static debug::Logger logger("assetload-funcs");
namespace fs = std::filesystem; namespace fs = std::filesystem;
static bool load_animation( static bool load_animated_texture(
Assets* assets, Assets& assets,
const ResPaths& paths, const ResPaths& paths,
const std::string& atlasName, const std::string& atlasName,
const std::string& directory, const std::string& directory,
@ -45,7 +45,7 @@ static bool load_animation(
); );
assetload::postfunc assetload::texture( assetload::postfunc assetload::texture(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
@ -54,12 +54,12 @@ assetload::postfunc assetload::texture(
auto actualFile = paths.find(filename + ".png"); auto actualFile = paths.find(filename + ".png");
try { try {
std::shared_ptr<ImageData> image(imageio::read(actualFile)); std::shared_ptr<ImageData> image(imageio::read(actualFile));
return [name, image, actualFile](auto assets) { return [name, image, actualFile](auto& assets) {
assets->store(Texture::from(image.get()), name); assets.store(Texture::from(image.get()), name);
}; };
} catch (const std::runtime_error& err) { } catch (const std::runtime_error& err) {
logger.error() << actualFile.string() << ": " << err.what(); logger.error() << actualFile.string() << ": " << err.what();
return [](auto) {}; return [](auto&) {};
} }
} }
@ -86,7 +86,7 @@ static auto read_program(const ResPaths& paths, const std::string& filename) {
} }
assetload::postfunc assetload::shader( assetload::postfunc assetload::shader(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
@ -99,8 +99,8 @@ assetload::postfunc assetload::shader(
io::path vertexFile = paths.find(filename + ".glslv"); io::path vertexFile = paths.find(filename + ".glslv");
io::path fragmentFile = paths.find(filename + ".glslf"); io::path fragmentFile = paths.find(filename + ".glslf");
return [=](auto assets) { return [=](auto& assets) {
assets->store( assets.store(
Shader::create( Shader::create(
{vertexFile.string(), vertex}, {vertexFile.string(), vertex},
{fragmentFile.string(), fragment} {fragmentFile.string(), fragment}
@ -111,7 +111,7 @@ assetload::postfunc assetload::shader(
} }
assetload::postfunc assetload::posteffect( assetload::postfunc assetload::posteffect(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
@ -131,7 +131,7 @@ assetload::postfunc assetload::posteffect(
std::string vertexSource = std::move(vertex.code); std::string vertexSource = std::move(vertex.code);
std::string fragmentSource = std::move(fragment.code); std::string fragmentSource = std::move(fragment.code);
return [=](auto assets) { return [=](auto& assets) {
auto program = Shader::create( auto program = Shader::create(
{effectFile.string(), vertexSource}, {effectFile.string(), vertexSource},
{effectFile.string(), fragmentSource} {effectFile.string(), fragmentSource}
@ -140,7 +140,7 @@ assetload::postfunc assetload::posteffect(
if (settings) { if (settings) {
advanced = dynamic_cast<const PostEffectCfg*>(settings.get())->advanced; advanced = dynamic_cast<const PostEffectCfg*>(settings.get())->advanced;
} }
assets->store( assets.store(
std::make_shared<PostEffect>(advanced, std::move(program), params), std::make_shared<PostEffect>(advanced, std::move(program), params),
name name
); );
@ -160,7 +160,7 @@ static bool append_atlas(AtlasBuilder& atlas, const io::path& file) {
} }
assetload::postfunc assetload::atlas( assetload::postfunc assetload::atlas(
AssetsLoader* loader, AssetsLoader& loader,
const ResPaths& paths, const ResPaths& paths,
const std::string& directory, const std::string& directory,
const std::string& name, const std::string& name,
@ -171,13 +171,13 @@ assetload::postfunc assetload::atlas(
for (const auto& file : paths.listdir(directory)) { for (const auto& file : paths.listdir(directory)) {
if (!imageio::is_read_supported(file.extension())) if (!imageio::is_read_supported(file.extension()))
continue; continue;
loader->add( loader.add(
AssetType::TEXTURE, AssetType::TEXTURE,
directory + "/" + file.stem(), directory + "/" + file.stem(),
name + "/" + file.stem() name + "/" + file.stem()
); );
} }
return [](auto){}; return [](auto&){};
} }
AtlasBuilder builder; AtlasBuilder builder;
for (const auto& file : paths.listdir(directory)) { for (const auto& file : paths.listdir(directory)) {
@ -186,17 +186,17 @@ assetload::postfunc assetload::atlas(
} }
std::set<std::string> names = builder.getNames(); std::set<std::string> names = builder.getNames();
Atlas* atlas = builder.build(ATLAS_EXTRUSION, false).release(); Atlas* atlas = builder.build(ATLAS_EXTRUSION, false).release();
return [=](auto assets) { return [=](Assets& assets) {
atlas->prepare(); atlas->prepare();
assets->store(std::unique_ptr<Atlas>(atlas), name); assets.store(std::unique_ptr<Atlas>(atlas), name);
for (const auto& file : names) { for (const auto& file : names) {
load_animation(assets, paths, name, directory, file, atlas); load_animated_texture(assets, paths, name, directory, file, atlas);
} }
}; };
} }
assetload::postfunc assetload::font( assetload::postfunc assetload::font(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
@ -206,15 +206,15 @@ assetload::postfunc assetload::font(
auto ext = fs::path(filename).extension().string(); auto ext = fs::path(filename).extension().string();
if (ext == ".ttf" || ext == ".otf") { if (ext == ".ttf" || ext == ".otf") {
logger.info() << "loading vector font " << util::quote(filename); logger.info() << "loading vector font " << util::quote(filename);
return [=](Assets* assets) { return [=](Assets& assets) {
using FontFile = vector_fonts::FontFile; using FontFile = vector_fonts::FontFile;
FontFile* fontFile; FontFile* fontFile;
if ((fontFile = assets->get<FontFile>(filename)) == nullptr) { if ((fontFile = assets.get<FontFile>(filename)) == nullptr) {
auto fontFilePtr = vector_fonts::load_font(paths.find(filename).string()); auto fontFilePtr = vector_fonts::load_font(paths.find(filename).string());
fontFile = fontFilePtr.get(); fontFile = fontFilePtr.get();
assets->store(fontFilePtr, filename); assets.store(fontFilePtr, filename);
} }
assets->store(fontFile->createInstance(cfg ? cfg->size : 16), name); assets.store(fontFile->createInstance(cfg ? cfg->size : 16), name);
}; };
} }
@ -230,24 +230,24 @@ assetload::postfunc assetload::font(
pages->push_back(nullptr); pages->push_back(nullptr);
} }
} }
return [=](auto assets) { return [=](auto& assets) {
assets->store(Font::createBitmapFont(std::move(*pages)), name); assets.store(Font::createBitmapFont(std::move(*pages)), name);
}; };
} }
assetload::postfunc assetload::layout( assetload::postfunc assetload::layout(
AssetsLoader*, AssetsLoader&,
const ResPaths&, const ResPaths&,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& config const std::shared_ptr<AssetCfg>& config
) { ) {
return [=](auto assets) { return [=](auto& assets) {
try { try {
auto cfg = std::dynamic_pointer_cast<LayoutCfg>(config); auto cfg = std::dynamic_pointer_cast<LayoutCfg>(config);
size_t pos = name.find(':'); size_t pos = name.find(':');
auto prefix = name.substr(0, pos); auto prefix = name.substr(0, pos);
assets->store( assets.store(
UiDocument::read( UiDocument::read(
*cfg->gui, *cfg->gui,
cfg->env, cfg->env,
@ -265,7 +265,7 @@ assetload::postfunc assetload::layout(
}; };
} }
assetload::postfunc assetload::sound( assetload::postfunc assetload::sound(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
@ -307,17 +307,17 @@ assetload::postfunc assetload::sound(
} }
auto sound = baseSound.release(); auto sound = baseSound.release();
return [=](auto assets) { return [=](auto& assets) {
assets->store(std::unique_ptr<audio::Sound>(sound), name); assets.store(std::unique_ptr<audio::Sound>(sound), name);
}; };
} }
static void request_textures(AssetsLoader* loader, const model::Model& model) { static void request_textures(AssetsLoader& loader, const model::Model& model) {
for (auto& mesh : model.meshes) { for (auto& mesh : model.meshes) {
if (mesh.texture.find('$') == std::string::npos && if (mesh.texture.find('$') == std::string::npos &&
mesh.texture.find(':') == std::string::npos) { mesh.texture.find(':') == std::string::npos) {
auto filename = TEXTURES_FOLDER + "/" + mesh.texture; auto filename = TEXTURES_FOLDER + "/" + mesh.texture;
loader->add( loader.add(
AssetType::TEXTURE, filename, mesh.texture, nullptr AssetType::TEXTURE, filename, mesh.texture, nullptr
); );
} }
@ -325,7 +325,7 @@ static void request_textures(AssetsLoader* loader, const model::Model& model) {
} }
assetload::postfunc assetload::model( assetload::postfunc assetload::model(
AssetsLoader* loader, AssetsLoader& loader,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
@ -337,7 +337,9 @@ assetload::postfunc assetload::model(
if (io::exists(path)) { if (io::exists(path)) {
auto bytes = io::read_bytes_buffer(path); auto bytes = io::read_bytes_buffer(path);
auto modelVEC3 = std::make_shared<vec3::File>(vec3::load(path.string(), bytes)); auto modelVEC3 = std::make_shared<vec3::File>(vec3::load(path.string(), bytes));
return [loader, name, cfg, modelVEC3=std::move(modelVEC3)](Assets* assets) { return [&loader, name, cfg, modelVEC3 = std::move(modelVEC3)](
Assets& assets
) {
if (cfg && cfg->squashed) { if (cfg && cfg->squashed) {
model::Model fullModel; model::Model fullModel;
for (auto& entry : modelVEC3->models) { for (auto& entry : modelVEC3->models) {
@ -347,7 +349,7 @@ assetload::postfunc assetload::model(
fullModel.merge(std::move(model)); fullModel.merge(std::move(model));
} }
request_textures(loader, fullModel); request_textures(loader, fullModel);
assets->store( assets.store(
std::make_unique<model::Model>(fullModel), std::make_unique<model::Model>(fullModel),
name name
); );
@ -360,7 +362,7 @@ assetload::postfunc assetload::model(
if (name != modelName) { if (name != modelName) {
fullName += "." + modelName; fullName += "." + modelName;
} }
assets->store( assets.store(
std::make_unique<model::Model>(model.model), std::make_unique<model::Model>(model.model),
fullName fullName
); );
@ -374,9 +376,9 @@ assetload::postfunc assetload::model(
auto text = io::read_string(path); auto text = io::read_string(path);
try { try {
auto model = obj::parse(path.string(), text).release(); auto model = obj::parse(path.string(), text).release();
return [=](Assets* assets) { return [=, &loader](Assets& assets) {
request_textures(loader, *model); request_textures(loader, *model);
assets->store(std::unique_ptr<model::Model>(model), name); assets.store(std::unique_ptr<model::Model>(model), name);
}; };
} catch (const parsing_error& err) { } catch (const parsing_error& err) {
std::cerr << err.errorLog() << std::endl; std::cerr << err.errorLog() << std::endl;
@ -409,22 +411,22 @@ assetload::postfunc assetload::model(
if (vcmModel.parts.size() == 1 || (cfg && cfg->squashed)) { if (vcmModel.parts.size() == 1 || (cfg && cfg->squashed)) {
auto modelPtr = std::make_unique<model::Model>(std::move(vcmModel.squash())).release(); auto modelPtr = std::make_unique<model::Model>(std::move(vcmModel.squash())).release();
return [=](Assets* assets) { return [=, &loader](Assets& assets) {
auto model = std::unique_ptr<model::Model>(modelPtr); auto model = std::unique_ptr<model::Model>(modelPtr);
request_textures(loader, *model); request_textures(loader, *model);
assets->store(std::move(model), name); assets.store(std::move(model), name);
logger.info() << "store model " << util::quote(name); logger.info() << "store model " << util::quote(name);
}; };
} else { } else {
auto vcmModelPtr = std::make_unique<vcm::VcmModel>(std::move(vcmModel)).release(); auto vcmModelPtr = std::make_unique<vcm::VcmModel>(std::move(vcmModel)).release();
return [=](Assets* assets) { return [=](Assets& assets) {
auto vcmModel = std::unique_ptr<vcm::VcmModel>(vcmModelPtr); auto vcmModel = std::unique_ptr<vcm::VcmModel>(vcmModelPtr);
for (auto& [partName, model] : vcmModel->parts) { for (auto& [partName, model] : vcmModel->parts) {
auto fullName = name + "." + partName; auto fullName = name + "." + partName;
logger.info() logger.info()
<< "store model part " << util::quote(partName) << "store model part " << util::quote(partName)
<< " as " << util::quote(fullName); << " as " << util::quote(fullName);
assets->store( assets.store(
std::make_unique<model::Model>(std::move(model)), std::make_unique<model::Model>(std::move(model)),
fullName fullName
); );
@ -433,7 +435,7 @@ assetload::postfunc assetload::model(
bone->setModel(name + "." + bone->model.name); bone->setModel(name + "." + bone->model.name);
} }
logger.info() << "store skeleton " << util::quote(name); logger.info() << "store skeleton " << util::quote(name);
assets->store<rigging::SkeletonConfig>( assets.store<rigging::SkeletonConfig>(
std::make_unique<rigging::SkeletonConfig>( std::make_unique<rigging::SkeletonConfig>(
std::move(*vcmModel->skeleton) std::move(*vcmModel->skeleton)
), ),
@ -448,13 +450,13 @@ assetload::postfunc assetload::model(
} }
assetload::postfunc assetload::skeleton( assetload::postfunc assetload::skeleton(
AssetsLoader* loader, AssetsLoader& loader,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
) { ) {
return [=](auto assets) { return [&loader, &paths, file, name](auto& assets) {
auto path = paths.find(file + ".json"); auto path = paths.find(file + ".json");
std::string text = io::read_string(path); std::string text = io::read_string(path);
auto skeleton = rigging::SkeletonConfig::parse(text, file, name); auto skeleton = rigging::SkeletonConfig::parse(text, file, name);
@ -465,12 +467,12 @@ assetload::postfunc assetload::skeleton(
model = model.substr(0, pos); model = model.substr(0, pos);
} }
if (!model.empty()) { if (!model.empty()) {
loader->add( loader.add(
AssetType::MODEL, MODELS_FOLDER + "/" + model, model AssetType::MODEL, MODELS_FOLDER + "/" + model, model
); );
} }
} }
assets->store(std::move(skeleton), name); assets.store(std::move(skeleton), name);
}; };
} }
@ -552,8 +554,8 @@ inline bool contains(
return false; return false;
} }
static bool load_animation( static bool load_animated_texture(
Assets* assets, Assets& assets,
const ResPaths& paths, const ResPaths& paths,
const std::string& atlasName, const std::string& atlasName,
const std::string& directory, const std::string& directory,
@ -591,10 +593,10 @@ static bool load_animation(
auto animation = create_animation( auto animation = create_animation(
srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList
); );
assets->store( assets.store(
std::move(srcAtlas), atlasName + "/" + name + "_animation" std::move(srcAtlas), atlasName + "/" + name + "_animation"
); );
assets->store(animation); assets.store(animation);
return true; return true;
} }
return true; return true;

View file

@ -14,56 +14,56 @@ struct AssetCfg;
/// @brief see AssetsLoader.h: aloader_func /// @brief see AssetsLoader.h: aloader_func
namespace assetload { namespace assetload {
postfunc texture( postfunc texture(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc shader( postfunc shader(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc atlas( postfunc atlas(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& directory, const std::string& directory,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc font( postfunc font(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& filename, const std::string& filename,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc layout( postfunc layout(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc sound( postfunc sound(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc model( postfunc model(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
const std::shared_ptr<AssetCfg>& settings const std::shared_ptr<AssetCfg>& settings
); );
postfunc posteffect( postfunc posteffect(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,
@ -71,7 +71,7 @@ namespace assetload {
); );
postfunc skeleton( postfunc skeleton(
AssetsLoader*, AssetsLoader&,
const ResPaths& paths, const ResPaths& paths,
const std::string& file, const std::string& file,
const std::string& name, const std::string& name,

View file

@ -298,6 +298,8 @@ void scripting::on_content_load(Content* content) {
} catch (const std::exception&) { } catch (const std::exception&) {
lua::pushnil(L); lua::pushnil(L);
lua::setglobal(L, "__vc_app"); lua::setglobal(L, "__vc_app");
lua::pushnil(L);
lua::setglobal(L, "__vc_internals");
throw; throw;
} }
lua::pushnil(L); lua::pushnil(L);