cleanup ContentControl

This commit is contained in:
MihailRis 2025-03-21 11:56:15 +03:00
parent f99d909f34
commit 3486cbd4c9
10 changed files with 59 additions and 114 deletions

View File

@ -30,7 +30,13 @@ ContentControl::ContentControl(
: paths(paths), : paths(paths),
input(input), input(input),
postContent(std::move(postContent)), postContent(std::move(postContent)),
basePacks(io::read_list("res:config/builtins.list")) { basePacks(io::read_list("res:config/builtins.list")),
manager(std::make_unique<PacksManager>()) {
manager->setSources({
"world:content",
"user:content",
"res:content",
});
} }
ContentControl::~ContentControl() = default; ContentControl::~ContentControl() = default;
@ -57,29 +63,22 @@ void ContentControl::resetContent() {
resRoots.push_back({"core", pack.folder}); resRoots.push_back({"core", pack.folder});
load_configs(input, pack.folder); load_configs(input, pack.folder);
} }
PacksManager manager; manager->scan();
manager.setSources({ for (const auto& pack : manager->getAll(basePacks)) {
"user:content",
"res:content",
});
manager.scan();
for (const auto& pack : manager.getAll(basePacks)) {
resRoots.push_back({pack.id, pack.folder}); resRoots.push_back({pack.id, pack.folder});
} }
paths.resPaths = ResPaths(resRoots); paths.resPaths = ResPaths(resRoots);
content.reset(); content.reset();
contentPacks.clear(); contentPacks.clear();
contentPacks = manager.getAll(basePacks); contentPacks = manager->getAll(basePacks);
postContent(); postContent();
} }
void ContentControl::loadContent(const std::vector<std::string>& names) { void ContentControl::loadContent(const std::vector<std::string>& names) {
PacksManager manager; manager->scan();
manager.setSources(getDefaultSources()); contentPacks = manager->getAll(manager->assemble(names));
manager.scan();
contentPacks = manager.getAll(manager.assemble(names));
loadContent(); loadContent();
} }
@ -90,12 +89,9 @@ void ContentControl::loadContent() {
for (auto& pack : contentPacks) { for (auto& pack : contentPacks) {
names.push_back(pack.id); names.push_back(pack.id);
} }
manager->scan();
PacksManager manager; names = manager->assemble(names);
manager.setSources(getDefaultSources()); contentPacks = manager->getAll(names);
manager.scan();
names = manager.assemble(names);
contentPacks = manager.getAll(names);
std::vector<PathsRoot> entryPoints; std::vector<PathsRoot> entryPoints;
for (auto& pack : contentPacks) { for (auto& pack : contentPacks) {
@ -130,14 +126,6 @@ void ContentControl::loadContent() {
postContent(); postContent();
} }
std::vector<io::path> ContentControl::getDefaultSources() {
return {
"world:content",
"user:content",
"res:content",
};
}
std::vector<ContentPack>& ContentControl::getContentPacks() { std::vector<ContentPack>& ContentControl::getContentPacks() {
return contentPacks; return contentPacks;
} }
@ -147,3 +135,8 @@ std::vector<ContentPack> ContentControl::getAllContentPacks() {
packs.insert(packs.begin(), ContentPack::createCore(paths)); packs.insert(packs.begin(), ContentPack::createCore(paths));
return packs; return packs;
} }
PacksManager& ContentControl::scan() {
manager->scan();
return *manager;
}

View File

@ -8,7 +8,7 @@
#include "ContentPack.hpp" #include "ContentPack.hpp"
class Content; class Content;
struct ContentPack; class PacksManager;
class EnginePaths; class EnginePaths;
class Input; class Input;
@ -36,14 +36,16 @@ public:
void loadContent(); void loadContent();
std::vector<io::path> getDefaultSources();
std::vector<ContentPack>& getContentPacks(); std::vector<ContentPack>& getContentPacks();
std::vector<ContentPack> getAllContentPacks(); std::vector<ContentPack> getAllContentPacks();
PacksManager& scan();
private: private:
EnginePaths& paths; EnginePaths& paths;
Input& input; Input& input;
std::unique_ptr<Content> content; std::unique_ptr<Content> content;
std::function<void()> postContent; std::function<void()> postContent;
std::vector<std::string> basePacks; std::vector<std::string> basePacks;
std::unique_ptr<PacksManager> manager;
std::vector<ContentPack> contentPacks; std::vector<ContentPack> contentPacks;
}; };

View File

@ -15,12 +15,13 @@ namespace fs = std::filesystem;
ContentPack ContentPack::createCore(const EnginePaths& paths) { ContentPack ContentPack::createCore(const EnginePaths& paths) {
return ContentPack { return ContentPack {
"core", "Core", ENGINE_VERSION_STRING, "", "", "res:", "res:", {} "core", "Core", ENGINE_VERSION_STRING, "", "", "res:", {}
}; };
} }
const std::vector<std::string> ContentPack::RESERVED_NAMES = { const std::vector<std::string> ContentPack::RESERVED_NAMES = {
"res", "abs", "local", "core", "user", "world", "none", "null"}; "res", "abs", "local", "core", "user", "world", "none", "null"
};
contentpack_error::contentpack_error( contentpack_error::contentpack_error(
std::string packId, io::path folder, const std::string& message std::string packId, io::path folder, const std::string& message
@ -70,7 +71,7 @@ static void checkContentPackId(const std::string& id, const io::path& folder) {
} }
} }
ContentPack ContentPack::read(const std::string& path, const io::path& folder) { ContentPack ContentPack::read(const io::path& folder) {
auto root = io::read_json(folder / PACKAGE_FILENAME); auto root = io::read_json(folder / PACKAGE_FILENAME);
ContentPack pack; ContentPack pack;
root.at("id").get(pack.id); root.at("id").get(pack.id);
@ -90,7 +91,6 @@ ContentPack ContentPack::read(const std::string& path, const io::path& folder) {
root.at("description").get(pack.description); root.at("description").get(pack.description);
root.at("source").get(pack.source); root.at("source").get(pack.source);
pack.folder = folder; pack.folder = folder;
pack.path = path;
if (auto found = root.at("dependencies")) { if (auto found = root.at("dependencies")) {
const auto& dependencies = *found; const auto& dependencies = *found;
@ -133,7 +133,7 @@ void ContentPack::scanFolder(
if (!io::is_directory(packFolder)) continue; if (!io::is_directory(packFolder)) continue;
if (!is_pack(packFolder)) continue; if (!is_pack(packFolder)) continue;
try { try {
packs.push_back(read(packFolder.string(), packFolder)); packs.push_back(read(packFolder));
} catch (const contentpack_error& err) { } catch (const contentpack_error& err) {
std::cerr << "package.json error at " << err.getFolder().string(); std::cerr << "package.json error at " << err.getFolder().string();
std::cerr << ": " << err.what() << std::endl; std::cerr << ": " << err.what() << std::endl;

View File

@ -43,7 +43,6 @@ struct ContentPack {
std::string creator = ""; std::string creator = "";
std::string description = "no description"; std::string description = "no description";
io::path folder; io::path folder;
std::string path;
std::vector<DependencyPack> dependencies; std::vector<DependencyPack> dependencies;
std::string source = ""; std::string source = "";
@ -58,7 +57,7 @@ struct ContentPack {
static const std::vector<std::string> RESERVED_NAMES; static const std::vector<std::string> RESERVED_NAMES;
static bool is_pack(const io::path& folder); static bool is_pack(const io::path& folder);
static ContentPack read(const std::string& path, const io::path& folder); static ContentPack read(const io::path& folder);
static void scanFolder( static void scanFolder(
const io::path& folder, std::vector<ContentPack>& packs const io::path& folder, std::vector<ContentPack>& packs

View File

@ -133,16 +133,14 @@ void Engine::initialize(CoreParameters coreParameters) {
bool langNotSet = settings.ui.language.get() == "auto"; bool langNotSet = settings.ui.language.get() == "auto";
if (langNotSet) { if (langNotSet) {
settings.ui.language.set(langs::locale_by_envlocale( settings.ui.language.set(
platform::detect_locale(), langs::locale_by_envlocale(platform::detect_locale())
"res:" );
));
} }
content = std::make_unique<ContentControl>(paths, *input, [this]() { content = std::make_unique<ContentControl>(paths, *input, [this]() {
langs::setup("res:", langs::get_current(), paths.resPaths.collectRoots()); langs::setup(langs::get_current(), paths.resPaths.collectRoots());
if (!isHeadless()) { if (!isHeadless()) {
loadAssets(); loadAssets();
onAssetsLoaded();
} }
}); });
scripting::initialize(this); scripting::initialize(this);
@ -150,7 +148,7 @@ void Engine::initialize(CoreParameters coreParameters) {
gui->setPageLoader(scripting::create_page_loader()); gui->setPageLoader(scripting::create_page_loader());
} }
keepAlive(settings.ui.language.observe([this](auto lang) { keepAlive(settings.ui.language.observe([this](auto lang) {
setLanguage(lang); langs::setup(lang, paths.resPaths.collectRoots());
}, true)); }, true));
} }
@ -179,11 +177,6 @@ void Engine::loadControls() {
} }
} }
void Engine::onAssetsLoaded() {
assets->setup();
gui->onAssetsLoad(assets.get());
}
void Engine::updateHotkeys() { void Engine::updateHotkeys() {
if (input->jpressed(keycode::F2)) { if (input->jpressed(keycode::F2)) {
saveScreenshot(); saveScreenshot();
@ -319,6 +312,9 @@ void Engine::loadAssets() {
if (content) { if (content) {
ModelsGenerator::prepare(*content, *assets); ModelsGenerator::prepare(*content, *assets);
} }
assets->setup();
gui->onAssetsLoad(assets.get());
} }
void Engine::setScreen(std::shared_ptr<Screen> screen) { void Engine::setScreen(std::shared_ptr<Screen> screen) {
@ -328,10 +324,6 @@ void Engine::setScreen(std::shared_ptr<Screen> screen) {
this->screen = std::move(screen); this->screen = std::move(screen);
} }
void Engine::setLanguage(std::string locale) {
langs::setup("res:", std::move(locale), paths.resPaths.collectRoots());
}
void Engine::onWorldOpen(std::unique_ptr<Level> level, int64_t localPlayer) { void Engine::onWorldOpen(std::unique_ptr<Level> level, int64_t localPlayer) {
logger.info() << "world open"; logger.info() << "world open";
levelConsumer(std::move(level), localPlayer); levelConsumer(std::move(level), localPlayer);

View File

@ -17,12 +17,8 @@ class Window;
class Assets; class Assets;
class Level; class Level;
class Screen; class Screen;
class EnginePaths;
class ResPaths;
class ContentControl; class ContentControl;
class EngineController; class EngineController;
class SettingsHandler;
struct EngineSettings;
class Input; class Input;
namespace gui { namespace gui {
@ -97,19 +93,12 @@ public:
void renderFrame(); void renderFrame();
void nextFrame(); void nextFrame();
/// @brief Called after assets loading when all engine systems are initialized
void onAssetsLoaded();
/// @brief Set screen (scene). /// @brief Set screen (scene).
/// nullptr may be used to delete previous screen before creating new one, /// nullptr may be used to delete previous screen before creating new one,
/// not-null value must be set before next frame /// not-null value must be set before next frame
/// @param screen nullable screen /// @param screen nullable screen
void setScreen(std::shared_ptr<Screen> screen); void setScreen(std::shared_ptr<Screen> screen);
/// @brief Change locale to specified
/// @param locale isolanguage_ISOCOUNTRY (example: en_US)
void setLanguage(std::string locale);
/// @brief Get active assets storage instance /// @brief Get active assets storage instance
Assets* getAssets(); Assets* getAssets();

View File

@ -63,8 +63,8 @@ namespace {
}; };
} }
static void load_locales_info(const io::path& resdir, std::string& fallback) { static void load_locales_info(std::string& fallback) {
auto file = resdir / langs::TEXTS_FOLDER / "langs.json"; auto file = io::path("res:") / langs::TEXTS_FOLDER / "langs.json";
auto root = io::read_json(file); auto root = io::read_json(file);
::locales_info.clear(); ::locales_info.clear();
@ -89,13 +89,12 @@ static void load_locales_info(const io::path& resdir, std::string& fallback) {
} }
static void load( static void load(
const io::path& resdir,
const std::string& locale, const std::string& locale,
const std::vector<io::path>& roots, const std::vector<io::path>& roots,
Lang& lang Lang& lang
) { ) {
io::path filename = io::path(TEXTS_FOLDER) / (locale + LANG_FILE_EXT); io::path filename = io::path(TEXTS_FOLDER) / (locale + LANG_FILE_EXT);
io::path core_file = resdir / filename; io::path core_file = io::path("res:") / filename;
if (io::is_regular_file(core_file)) { if (io::is_regular_file(core_file)) {
std::string text = io::read_string(core_file); std::string text = io::read_string(core_file);
@ -112,15 +111,14 @@ static void load(
} }
} }
static void load( static void load(
const io::path& resdir,
const std::string& locale, const std::string& locale,
const std::string& fallback, const std::string& fallback,
const std::vector<io::path>& roots const std::vector<io::path>& roots
) { ) {
auto lang = std::make_unique<Lang>(locale); auto lang = std::make_unique<Lang>(locale);
load(resdir, fallback, roots, *lang.get()); load(fallback, roots, *lang.get());
if (locale != fallback) { if (locale != fallback) {
load(resdir, locale, roots, *lang.get()); load(locale, roots, *lang.get());
} }
current = std::move(lang); current = std::move(lang);
} }
@ -136,10 +134,10 @@ const std::unordered_map<std::string, LocaleInfo>& langs::get_locales_info() {
return ::locales_info; return ::locales_info;
} }
std::string langs::locale_by_envlocale(const std::string& envlocale, const io::path& resdir){ std::string langs::locale_by_envlocale(const std::string& envlocale){
std::string fallback = FALLBACK_DEFAULT; std::string fallback = FALLBACK_DEFAULT;
if (locales_info.size() == 0) { if (locales_info.size() == 0) {
load_locales_info(resdir, fallback); load_locales_info(fallback);
} }
if (locales_info.find(envlocale) != locales_info.end()) { if (locales_info.find(envlocale) != locales_info.end()) {
logger.info() << "locale " << envlocale << " is automatically selected"; logger.info() << "locale " << envlocale << " is automatically selected";
@ -158,16 +156,15 @@ std::string langs::locale_by_envlocale(const std::string& envlocale, const io::p
} }
void langs::setup( void langs::setup(
const io::path& resdir,
std::string locale, std::string locale,
const std::vector<io::path>& roots const std::vector<io::path>& roots
) { ) {
std::string fallback = langs::FALLBACK_DEFAULT; std::string fallback = langs::FALLBACK_DEFAULT;
load_locales_info(resdir, fallback); load_locales_info(fallback);
if (::locales_info.find(locale) == ::locales_info.end()) { if (locales_info.find(locale) == locales_info.end()) {
locale = fallback; locale = fallback;
} }
load(resdir, locale, fallback, roots); load(locale, fallback, roots);
} }
const std::wstring& langs::get(const std::wstring& key) { const std::wstring& langs::get(const std::wstring& key) {

View File

@ -39,9 +39,7 @@ namespace langs {
std::string name; std::string name;
}; };
std::string locale_by_envlocale( std::string locale_by_envlocale(const std::string& envlocale);
const std::string& envlocale, const io::path& resdir
);
const std::string& get_current(); const std::string& get_current();
const std::unordered_map<std::string, LocaleInfo>& get_locales_info(); const std::unordered_map<std::string, LocaleInfo>& get_locales_info();
@ -51,9 +49,7 @@ namespace langs {
const std::wstring& key, const std::wstring& context const std::wstring& key, const std::wstring& context
); );
void setup( /// @brief Change locale to specified
const io::path& resdir, /// @param locale isolanguage_ISOCOUNTRY (example: en_US)
std::string locale, void setup(std::string locale, const std::vector<io::path>& roots);
const std::vector<io::path>& roots
);
} }

View File

@ -324,12 +324,10 @@ void EngineController::reconfigPacks(
} }
} }
runnable removeFunc = [this, controller, packsToAdd, packsToRemove]() { runnable removeFunc = [this, controller, packsToAdd, packsToRemove, &contentControl]() {
auto& manager = contentControl.scan();
if (controller == nullptr) { if (controller == nullptr) {
try { try {
PacksManager manager;
manager.setSources(engine.getContentControl().getDefaultSources());
manager.scan();
auto names = PacksManager::getNames( auto names = PacksManager::getNames(
engine.getContentControl().getContentPacks() engine.getContentControl().getContentPacks()
); );
@ -352,10 +350,6 @@ void EngineController::reconfigPacks(
auto& wfile = *world->wfile; auto& wfile = *world->wfile;
controller->saveWorld(); controller->saveWorld();
PacksManager manager;
manager.setSources(engine.getContentControl().getDefaultSources());
manager.scan();
auto names = PacksManager::getNames(world->getPacks()); auto names = PacksManager::getNames(world->getPacks());
for (const auto& id : packsToAdd) { for (const auto& id : packsToAdd) {
names.push_back(id); names.push_back(id);

View File

@ -45,10 +45,7 @@ static int l_pack_get_installed(lua::State* L) {
/// @brief pack.get_available() -> array<string> /// @brief pack.get_available() -> array<string>
static int l_pack_get_available(lua::State* L) { static int l_pack_get_available(lua::State* L) {
PacksManager manager; auto& manager = content_control->scan();
manager.setSources(content_control->getDefaultSources());
manager.scan();
const auto& installed = content_control->getContentPacks(); const auto& installed = content_control->getContentPacks();
for (auto& pack : installed) { for (auto& pack : installed) {
manager.exclude(pack.id); manager.exclude(pack.id);
@ -83,7 +80,7 @@ static int l_pack_get_info(
lua::pushstring(L, pack.version); lua::pushstring(L, pack.version);
lua::setfield(L, "version"); lua::setfield(L, "version");
lua::pushstring(L, pack.path); lua::pushstring(L, pack.folder.string());
lua::setfield(L, "path"); lua::setfield(L, "path");
if (!engine->isHeadless()) { if (!engine->isHeadless()) {
@ -147,9 +144,7 @@ static int pack_get_infos(lua::State* L) {
} }
} }
if (!ids.empty()) { if (!ids.empty()) {
PacksManager manager; auto& manager = content_control->scan();
manager.setSources(content_control->getDefaultSources());
manager.scan();
auto vec = auto vec =
manager.getAll(std::vector<std::string>(ids.begin(), ids.end())); manager.getAll(std::vector<std::string>(ids.begin(), ids.end()));
for (const auto& pack : vec) { for (const auto& pack : vec) {
@ -185,13 +180,7 @@ static int l_pack_get_info(lua::State* L) {
return pack.id == packid; return pack.id == packid;
}); });
if (found == packs.end()) { if (found == packs.end()) {
io::path worldFolder; auto& manager = content_control->scan();
if (level) {
worldFolder = level->getWorld()->wfile->getFolder();
}
PacksManager manager;
manager.setSources(content_control->getDefaultSources());
manager.scan();
auto vec = manager.getAll({packid}); auto vec = manager.getAll({packid});
if (!vec.empty()) { if (!vec.empty()) {
return l_pack_get_info(L, vec[0], content); return l_pack_get_info(L, vec[0], content);
@ -223,13 +212,7 @@ static int l_pack_assemble(lua::State* L) {
ids.push_back(lua::require_string(L, -1)); ids.push_back(lua::require_string(L, -1));
lua::pop(L); lua::pop(L);
} }
io::path worldFolder; auto& manager = content_control->scan();
if (level) {
worldFolder = level->getWorld()->wfile->getFolder();
}
PacksManager manager;
manager.setSources(content_control->getDefaultSources());
manager.scan();
try { try {
ids = manager.assemble(ids); ids = manager.assemble(ids);
} catch (const contentpack_error& err) { } catch (const contentpack_error& err) {