Compare commits

...

4 commits

Author SHA1 Message Date
Rod
a7f15bcc01
Added pt-pt (#1158)
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
* Added Portuguese Portuguese

* sry i forgot this

---------

Co-authored-by: OmgRod <rlimafonseca2010@gmail.com>
2024-11-16 13:21:57 +01:00
altalk23
5919c7e09a i love tab! 2024-11-16 15:04:25 +03:00
altalk23
17bf7722c9 fix before/after priority stuff 2024-11-16 14:53:21 +03:00
altalk23
22210956bb fix nest issues on errors 2024-11-16 13:01:22 +03:00
9 changed files with 290 additions and 189 deletions

View file

@ -0,0 +1,16 @@
!insertmacro LANGFILE_EXT PortuguesePT
!pragma warning disable 6030
${LangFileString} MUI_TEXT_WELCOME_INFO_TEXT "O instalador irá guiá-lo através da instalação de $(^NameDA).$\r$\n$\r$\nAntes de iniciar a instalação, certifique-se de que o Geometry Dash não está aberto.$\r$\n$\r$\n$_CLICK"
${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "O instalador irá guiá-lo através da desinstalação de $(^NameDA).$\r$\n$\r$\nAntes de iniciar a desinstalação, certifique-se de que o Geometry Dash não está aberto.$\r$\n$\r$\n$_CLICK"
!pragma warning default 6030
; installer
${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nEsse caminho não tem o Geometry Dash instalado!"
${LangFileString} GEODE_TEXT_GD_OLD "$\r$\n$\r$\nA sua versão do Geometry Dash é demasiado antiga para esta versão do Geode!"
${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "Esse caminho já tem outros mods instalados!$\r$\nEles serão substituídos pelo Geode. (the dll trademark)"
; uninstaller
${LangFileString} GEODE_UNTEXT_GEODE_MISSING "Esse caminho não tem o Geode instalado!"

View file

@ -58,6 +58,7 @@
!insertmacro GEODE_LANGUAGE "Polish" !insertmacro GEODE_LANGUAGE "Polish"
!insertmacro GEODE_LANGUAGE "Russian" !insertmacro GEODE_LANGUAGE "Russian"
!insertmacro GEODE_LANGUAGE "PortugueseBR" !insertmacro GEODE_LANGUAGE "PortugueseBR"
!insertmacro GEODE_LANGUAGE "PortuguesePT"
!insertmacro GEODE_LANGUAGE "Ukrainian" !insertmacro GEODE_LANGUAGE "Ukrainian"
!insertmacro GEODE_LANGUAGE "Czech" !insertmacro GEODE_LANGUAGE "Czech"
!insertmacro GEODE_LANGUAGE "Turkish" !insertmacro GEODE_LANGUAGE "Turkish"

View file

@ -114,6 +114,37 @@ namespace geode {
popNest(getMod()); popNest(getMod());
} }
struct NestScope {
private:
bool m_active = true;
public:
NestScope() {
pushNest();
}
NestScope(NestScope const&) {
pushNest();
}
NestScope(NestScope&& other) {
other.m_active = false;
}
NestScope& operator=(NestScope const&) {
pushNest();
return *this;
}
NestScope& operator=(NestScope&& other) {
other.m_active = false;
return *this;
}
~NestScope() {
if (m_active) popNest();
}
};
class Nest final { class Nest final {
private: private:
class Impl; class Impl;

View file

@ -145,18 +145,19 @@ namespace geode::modifier {
/// @brief Get a hook by name /// @brief Get a hook by name
/// @param name The name of the hook to get /// @param name The name of the hook to get
/// @returns Ok if the hook was found, Err if the hook was not found /// @returns Ok if the hook was found, Err if the hook was not found
Result<Hook*> getHook(std::string const& name) { Result<Hook*> getHook(std::string_view name) {
if (m_hooks.find(name) == m_hooks.end()) { auto key = std::string(name);
if (m_hooks.find(key) == m_hooks.end()) {
return Err("Hook not in this modify"); return Err("Hook not in this modify");
} }
return Ok(m_hooks[name].get()); return Ok(m_hooks[key].get());
} }
/// @brief Set the priority of a hook /// @brief Set the priority of a hook
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to /// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriority(std::string const& name, int32_t priority = Priority::Normal) { Result<> setHookPriority(std::string_view name, int32_t priority = Priority::Normal) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name)); GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
hook->setPriority(priority); hook->setPriority(priority);
return Ok(); return Ok();
@ -166,7 +167,7 @@ namespace geode::modifier {
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to /// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityPre(std::string const& name, int32_t priority = Priority::Normal) { Result<> setHookPriorityPre(std::string_view name, int32_t priority = Priority::Normal) {
return this->setHookPriority(name, priority); return this->setHookPriority(name, priority);
} }
@ -174,104 +175,144 @@ namespace geode::modifier {
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param priority The priority to set the hook to /// @param priority The priority to set the hook to
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityPost(std::string const& name, int32_t priority = Priority::Normal) { Result<> setHookPriorityPost(std::string_view name, int32_t priority = Priority::Normal) {
return this->setHookPriority(name, -priority); return this->setHookPriority(name, -priority);
} }
/// @brief Set the priority of a hook to be after another hook in different mods /// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after /// @param after The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...) Result<> setHookPriorityAfter(std::string_view name, Mod* mod) {
Result<> setHookPriorityAfter(std::string const& name, C&&... after) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name)); GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
([&](){ auto func = [=](ModStateEvent* event){
auto mod = Loader::get()->getInstalledMod(after);
if (!mod) return;
auto hooks = mod->getHooks(); auto hooks = mod->getHooks();
auto func = [=](){ for (auto modHook : hooks) {
for (auto modHook : hooks) { if (modHook->getAddress() != hook->getAddress()) continue;
if (modHook->getAddress() != hook->getAddress()) continue; auto priority = modHook->getPriority();
auto priority = hook->getPriority(); if (hook->getPriority() <= priority) {
if (priority < modHook->getPriority()) { hook->setPriority(priority + 1);
hook->setPriority(modHook->getPriority() + 1);
}
} }
};
if (Loader::get()->isModLoaded(mod)) {
func();
} }
else { return ListenerResult::Propagate;
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded)); };
} if (mod->isEnabled()) {
} (), ...); func(nullptr);
return Ok(); }
} else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
/// @brief Set the priority of a hook to be before another hook in different mods }
/// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...)
Result<> setHookPriorityBefore(std::string const& name, C&&... before) {
GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
([&](){
auto mod = Loader::get()->getInstalledMod(before);
if (!mod) return;
auto hooks = mod->getHooks();
auto func = [=](){
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = hook->getPriority();
if (priority > modHook->getPriority()) {
hook->setPriority(modHook->getPriority() - 1);
}
}
};
if (Loader::get()->isModLoaded(mod)) {
func();
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
} (), ...);
return Ok(); return Ok();
} }
/// @brief Set the priority of a hook to be after another hook in different mods /// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after /// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...) Result<> setHookPriorityAfter(std::string_view name, std::string_view after) {
Result<> setHookPriorityAfterPre(std::string const& name, C&&... after) { auto mod = Loader::get()->getInstalledMod(std::string(after));
return this->setHookPriorityAfter(name, Priority::NormalPre, std::forward<C>(after)...); if (!mod) return Err("Mod not found");
return this->setHookPriorityAfter(name, mod);
} }
/// @brief Set the priority of a hook to be before another hook in different mods /// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before /// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...) Result<> setHookPriorityBefore(std::string_view name, Mod* mod) {
Result<> setHookPriorityBeforePre(std::string const& name, C&&... before) { GEODE_UNWRAP_INTO(auto hook, this->getHook(name));
return this->setHookPriorityBefore(name, Priority::NormalPre, std::forward<C>(before)...); auto func = [=](ModStateEvent* event){
auto hooks = mod->getHooks();
for (auto modHook : hooks) {
if (modHook->getAddress() != hook->getAddress()) continue;
auto priority = modHook->getPriority();
if (hook->getPriority() >= priority) {
hook->setPriority(priority - 1);
}
}
return ListenerResult::Propagate;
};
if (mod->isEnabled()) {
func(nullptr);
}
else {
new EventListener(func, ModStateFilter(mod, ModEventType::Loaded));
}
return Ok();
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBefore(std::string_view name, std::string_view before) {
auto mod = Loader::get()->getInstalledMod(std::string(before));
if (!mod) return Err("Mod not found");
return this->setHookPriorityBefore(name, mod);
} }
/// @brief Set the priority of a hook to be after another hook in different mods /// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param after The mod ids of the mods to set the priority after /// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...) Result<> setHookPriorityAfterPre(std::string_view name, std::string_view after) {
Result<> setHookPriorityAfterPost(std::string const& name, C&&... after) { return this->setHookPriorityAfter(name, after);
return this->setHookPriorityBefore(name, Priority::NormalPost, std::forward<C>(after)...); }
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPre(std::string_view name, Mod* mod) {
return this->setHookPriorityAfter(name, mod);
} }
/// @brief Set the priority of a hook to be before another hook in different mods /// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of /// @param name The name of the hook to set the priority of
/// @param before The mod ids of the mods to set the priority before /// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found /// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
template<class... C> requires (std::is_convertible_v<C, std::string> && ...) Result<> setHookPriorityBeforePre(std::string_view name, std::string_view before) {
Result<> setHookPriorityBeforePost(std::string const& name, C&&... before) { return this->setHookPriorityBefore(name, before);
return this->setHookPriorityAfter(name, Priority::NormalPost, std::forward<C>(before)...); }
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePre(std::string_view name, Mod* mod) {
return this->setHookPriorityBefore(name, mod);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param after The mod id of the mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPost(std::string_view name, std::string_view after) {
return this->setHookPriorityBefore(name, after);
}
/// @brief Set the priority of a hook to be after another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority after
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityAfterPost(std::string_view name, Mod* mod) {
return this->setHookPriorityBefore(name, mod);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod id of the mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePost(std::string_view name, std::string_view before) {
return this->setHookPriorityAfter(name, before);
}
/// @brief Set the priority of a hook to be before another hook in different mods
/// @param name The name of the hook to set the priority of
/// @param before The mod to set the priority before
/// @returns Ok if the hook was found and the priority was set, Err if the hook was not found
Result<> setHookPriorityBeforePost(std::string_view name, Mod* mod) {
return this->setHookPriorityAfter(name, mod);
} }
// unordered_map<handles> idea // unordered_map<handles> idea

View file

@ -8,7 +8,7 @@ using namespace geode::prelude;
namespace { namespace {
void saveModData() { void saveModData() {
log::info("Saving mod data..."); log::info("Saving mod data...");
log::pushNest(); log::NestScope nest;
auto begin = std::chrono::high_resolution_clock::now(); auto begin = std::chrono::high_resolution_clock::now();
@ -17,8 +17,6 @@ namespace {
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count(); auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
log::info("Took {}s", static_cast<float>(time) / 1000.f); log::info("Took {}s", static_cast<float>(time) / 1000.f);
log::popNest();
} }
} }

View file

@ -138,17 +138,18 @@ int geodeEntry(void* platformData) {
// set up internal mod, settings and data // set up internal mod, settings and data
log::info("Setting up internal mod"); log::info("Setting up internal mod");
log::pushNest(); {
auto internalSetupRes = LoaderImpl::get()->setupInternalMod(); log::NestScope nest;
log::popNest(); auto internalSetupRes = LoaderImpl::get()->setupInternalMod();
if (!internalSetupRes) { if (!internalSetupRes) {
console::messageBox( console::messageBox(
"Unable to Load Geode!", "Unable to Load Geode!",
"There was a fatal error setting up " "There was a fatal error setting up "
"the internal mod and Geode can not be loaded: " + internalSetupRes.unwrapErr() "the internal mod and Geode can not be loaded: " + internalSetupRes.unwrapErr()
); );
LoaderImpl::get()->forceReset(); LoaderImpl::get()->forceReset();
return 1; return 1;
}
} }
tryShowForwardCompat(); tryShowForwardCompat();
@ -161,26 +162,28 @@ int geodeEntry(void* platformData) {
// set up loader, load mods, etc. // set up loader, load mods, etc.
log::info("Setting up loader"); log::info("Setting up loader");
log::pushNest(); {
auto setupRes = LoaderImpl::get()->setup(); log::NestScope nest;
log::popNest(); auto setupRes = LoaderImpl::get()->setup();
if (!setupRes) { if (!setupRes) {
console::messageBox( console::messageBox(
"Unable to Load Geode!", "Unable to Load Geode!",
"There was an unknown fatal error setting up " "There was an unknown fatal error setting up "
"the loader and Geode can not be loaded. " "the loader and Geode can not be loaded. "
"(" + setupRes.unwrapErr() + ")" "(" + setupRes.unwrapErr() + ")"
); );
LoaderImpl::get()->forceReset(); LoaderImpl::get()->forceReset();
return 1; return 1;
}
} }
crashlog::setupPlatformHandlerPost(); crashlog::setupPlatformHandlerPost();
log::debug("Setting up IPC"); log::debug("Setting up IPC");
log::pushNest(); {
ipc::setup(); log::NestScope nest;
log::popNest(); ipc::setup();
}
// download and install new loader update in the background // download and install new loader update in the background

View file

@ -81,35 +81,32 @@ Result<> Loader::Impl::setup() {
if (this->supportsLaunchArguments()) { if (this->supportsLaunchArguments()) {
log::debug("Loading launch arguments"); log::debug("Loading launch arguments");
log::pushNest(); log::NestScope nest;
this->initLaunchArguments(); this->initLaunchArguments();
log::popNest();
} }
// on some platforms, using the crash handler overrides more convenient native handlers // on some platforms, using the crash handler overrides more convenient native handlers
if (!this->getLaunchFlag("disable-crash-handler")) { if (!this->getLaunchFlag("disable-crash-handler")) {
log::debug("Setting up crash handler"); log::debug("Setting up crash handler");
log::pushNest(); log::NestScope nest;
if (!crashlog::setupPlatformHandler()) { if (!crashlog::setupPlatformHandler()) {
log::debug("Failed to set up crash handler"); log::debug("Failed to set up crash handler");
} }
log::popNest();
} else { } else {
log::debug("Crash handler setup skipped"); log::debug("Crash handler setup skipped");
} }
log::debug("Loading hooks"); log::debug("Loading hooks");
log::pushNest(); if (log::NestScope nest; !this->loadHooks()) {
if (!this->loadHooks()) {
return Err("There were errors loading some hooks, see console for details"); return Err("There were errors loading some hooks, see console for details");
} }
log::popNest();
log::debug("Setting up directories"); log::debug("Setting up directories");
log::pushNest(); {
this->createDirectories(); log::NestScope nest;
this->addSearchPaths(); this->createDirectories();
log::popNest(); this->addSearchPaths();
}
// Trigger on_mod(Loaded) for the internal mod // Trigger on_mod(Loaded) for the internal mod
// this function is already on the gd thread, so this should be fine // this function is already on the gd thread, so this should be fine
@ -129,7 +126,7 @@ void Loader::Impl::addSearchPaths() {
void Loader::Impl::updateResources(bool forceReload) { void Loader::Impl::updateResources(bool forceReload) {
log::debug("Adding resources"); log::debug("Adding resources");
log::pushNest(); log::NestScope nest;
for (auto const& [_, mod] : m_mods) { for (auto const& [_, mod] : m_mods) {
if (!forceReload && ModImpl::getImpl(mod)->m_resourcesLoaded) if (!forceReload && ModImpl::getImpl(mod)->m_resourcesLoaded)
continue; continue;
@ -140,7 +137,6 @@ void Loader::Impl::updateResources(bool forceReload) {
// we have to call it in both places since setup is only called once ever, but updateResources is called // we have to call it in both places since setup is only called once ever, but updateResources is called
// on every texture reload // on every texture reload
CCFileUtils::get()->updatePaths(); CCFileUtils::get()->updatePaths();
log::popNest();
} }
std::vector<Mod*> Loader::Impl::getAllMods() { std::vector<Mod*> Loader::Impl::getAllMods() {
@ -178,24 +174,22 @@ bool Loader::Impl::isModVersionSupported(VersionInfo const& target) {
void Loader::Impl::saveData() { void Loader::Impl::saveData() {
for (auto& [id, mod] : m_mods) { for (auto& [id, mod] : m_mods) {
log::debug("{}", mod->getID()); log::debug("{}", mod->getID());
log::pushNest(); log::NestScope nest;
auto r = mod->saveData(); auto r = mod->saveData();
if (!r) { if (!r) {
log::warn("Unable to save data for mod \"{}\": {}", mod->getID(), r.unwrapErr()); log::warn("Unable to save data for mod \"{}\": {}", mod->getID(), r.unwrapErr());
} }
log::popNest();
} }
} }
void Loader::Impl::loadData() { void Loader::Impl::loadData() {
for (auto& [_, mod] : m_mods) { for (auto& [_, mod] : m_mods) {
log::debug("{}", mod->getID()); log::debug("{}", mod->getID());
log::pushNest(); log::NestScope nest;
auto r = mod->loadData(); auto r = mod->loadData();
if (!r) { if (!r) {
log::warn("Unable to load data for mod \"{}\": {}", mod->getID(), r.unwrapErr()); log::warn("Unable to load data for mod \"{}\": {}", mod->getID(), r.unwrapErr());
} }
log::popNest();
} }
} }
@ -238,7 +232,7 @@ void Loader::Impl::updateModResources(Mod* mod) {
return; return;
log::debug("{}", mod->getID()); log::debug("{}", mod->getID());
log::pushNest(); log::NestScope nest;
for (auto const& sheet : mod->getMetadata().getSpritesheets()) { for (auto const& sheet : mod->getMetadata().getSpritesheets()) {
log::debug("Adding sheet {}", sheet); log::debug("Adding sheet {}", sheet);
@ -258,8 +252,6 @@ void Loader::Impl::updateModResources(Mod* mod) {
CCSpriteFrameCache::get()->addSpriteFramesWithFile(plist.c_str()); CCSpriteFrameCache::get()->addSpriteFramesWithFile(plist.c_str());
} }
} }
log::popNest();
} }
void Loader::Impl::addProblem(LoadProblem const& problem) { void Loader::Impl::addProblem(LoadProblem const& problem) {
@ -275,14 +267,14 @@ void Loader::Impl::addProblem(LoadProblem const& problem) {
void Loader::Impl::queueMods(std::vector<ModMetadata>& modQueue) { void Loader::Impl::queueMods(std::vector<ModMetadata>& modQueue) {
for (auto const& dir : m_modSearchDirectories) { for (auto const& dir : m_modSearchDirectories) {
log::debug("Searching {}", dir); log::debug("Searching {}", dir);
log::pushNest(); log::NestScope nest;
for (auto const& entry : std::filesystem::directory_iterator(dir)) { for (auto const& entry : std::filesystem::directory_iterator(dir)) {
if (!std::filesystem::is_regular_file(entry) || if (!std::filesystem::is_regular_file(entry) ||
entry.path().extension() != GEODE_MOD_EXTENSION) entry.path().extension() != GEODE_MOD_EXTENSION)
continue; continue;
log::debug("Found {}", entry.path().filename()); log::debug("Found {}", entry.path().filename());
log::pushNest(); log::NestScope nest;
auto res = ModMetadata::createFromGeodeFile(entry.path()); auto res = ModMetadata::createFromGeodeFile(entry.path());
if (!res) { if (!res) {
@ -292,7 +284,6 @@ void Loader::Impl::queueMods(std::vector<ModMetadata>& modQueue) {
res.unwrapErr() res.unwrapErr()
}); });
log::error("Failed to queue: {}", res.unwrapErr()); log::error("Failed to queue: {}", res.unwrapErr());
log::popNest();
continue; continue;
} }
auto modMetadata = res.unwrap(); auto modMetadata = res.unwrap();
@ -310,14 +301,11 @@ void Loader::Impl::queueMods(std::vector<ModMetadata>& modQueue) {
"A mod with the same ID is already present." "A mod with the same ID is already present."
}); });
log::error("Failed to queue: a mod with the same ID is already queued"); log::error("Failed to queue: a mod with the same ID is already queued");
log::popNest();
continue; continue;
} }
modQueue.push_back(modMetadata); modQueue.push_back(modMetadata);
log::popNest();
} }
log::popNest();
} }
} }
@ -335,7 +323,7 @@ void Loader::Impl::populateModList(std::vector<ModMetadata>& modQueue) {
for (auto const& metadata : modQueue) { for (auto const& metadata : modQueue) {
log::debug("{} {}", metadata.getID(), metadata.getVersion()); log::debug("{} {}", metadata.getID(), metadata.getVersion());
log::pushNest(); log::NestScope nest;
auto mod = new Mod(metadata); auto mod = new Mod(metadata);
@ -347,20 +335,17 @@ void Loader::Impl::populateModList(std::vector<ModMetadata>& modQueue) {
res.unwrapErr() res.unwrapErr()
}); });
log::error("Failed to set up: {}", res.unwrapErr()); log::error("Failed to set up: {}", res.unwrapErr());
log::popNest();
continue; continue;
} }
m_mods.insert({metadata.getID(), mod}); m_mods.insert({metadata.getID(), mod});
log::popNest();
} }
} }
void Loader::Impl::buildModGraph() { void Loader::Impl::buildModGraph() {
for (auto const& [id, mod] : m_mods) { for (auto const& [id, mod] : m_mods) {
log::debug("{}", mod->getID()); log::debug("{}", mod->getID());
log::pushNest(); log::NestScope nest;
for (auto& dependency : mod->m_impl->m_metadata.m_impl->m_dependencies) { for (auto& dependency : mod->m_impl->m_metadata.m_impl->m_dependencies) {
log::debug("{}", dependency.id); log::debug("{}", dependency.id);
if (!m_mods.contains(dependency.id)) { if (!m_mods.contains(dependency.id)) {
@ -387,7 +372,6 @@ void Loader::Impl::buildModGraph() {
incompatibility.mod = incompatibility.mod =
m_mods.contains(incompatibility.id) ? m_mods[incompatibility.id] : nullptr; m_mods.contains(incompatibility.id) ? m_mods[incompatibility.id] : nullptr;
} }
log::popNest();
} }
} }
@ -404,7 +388,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
res.unwrapErr() res.unwrapErr()
}); });
log::error("{}", res.unwrapErr()); log::error("{}", res.unwrapErr());
log::popNest();
return; return;
} }
@ -418,7 +401,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
geodeVerRes.unwrapErr() geodeVerRes.unwrapErr()
}); });
log::error("{}", geodeVerRes.unwrapErr()); log::error("{}", geodeVerRes.unwrapErr());
log::popNest();
return; return;
} }
@ -431,12 +413,10 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
return; return;
} }
log::debug("{} {}", node->getID(), node->getVersion()); log::NestScope nest;
log::pushNest();
if (node->isEnabled()) { if (node->isEnabled()) {
log::warn("Mod {} already loaded, this should never happen", node->getID()); log::warn("Mod {} already loaded, this should never happen", node->getID());
log::popNest();
return; return;
} }
@ -447,6 +427,7 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
auto unzipFunction = [this, node]() { auto unzipFunction = [this, node]() {
log::debug("Unzip"); log::debug("Unzip");
log::NestScope nest;
auto res = node->m_impl->unzipGeodeFile(node->getMetadata()); auto res = node->m_impl->unzipGeodeFile(node->getMetadata());
return res; return res;
}; };
@ -454,6 +435,7 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
auto loadFunction = [this, node, early]() { auto loadFunction = [this, node, early]() {
if (node->shouldLoad()) { if (node->shouldLoad()) {
log::debug("Load"); log::debug("Load");
log::NestScope nest;
auto res = node->m_impl->loadBinary(); auto res = node->m_impl->loadBinary();
if (!res) { if (!res) {
this->addProblem({ this->addProblem({
@ -479,7 +461,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
}); });
log::error("{}", reason.value()); log::error("{}", reason.value());
m_refreshingModCount -= 1; m_refreshingModCount -= 1;
log::popNest();
return; return;
} }
} }
@ -494,7 +475,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
}); });
log::error("Failed to unzip: {}", res.unwrapErr()); log::error("Failed to unzip: {}", res.unwrapErr());
m_refreshingModCount -= 1; m_refreshingModCount -= 1;
log::popNest();
return; return;
} }
loadFunction(); loadFunction();
@ -524,7 +504,6 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
}); });
}).detach(); }).detach();
} }
log::popNest();
} }
void Loader::Impl::findProblems() { void Loader::Impl::findProblems() {
@ -538,7 +517,7 @@ void Loader::Impl::findProblems() {
continue; continue;
} }
log::debug("{}", id); log::debug("{}", id);
log::pushNest(); log::NestScope nest;
for (auto const& dep : mod->getMetadata().getDependencies()) { for (auto const& dep : mod->getMetadata().getDependencies()) {
if (dep.mod && dep.mod->isEnabled() && dep.version.compare(dep.mod->getVersion())) if (dep.mod && dep.mod->isEnabled() && dep.version.compare(dep.mod->getVersion()))
@ -665,18 +644,15 @@ void Loader::Impl::findProblems() {
}); });
log::error("{} failed to load for an unknown reason", id); log::error("{} failed to load for an unknown reason", id);
} }
log::popNest();
} }
} }
void Loader::Impl::refreshModGraph() { void Loader::Impl::refreshModGraph() {
log::info("Refreshing mod graph"); log::info("Refreshing mod graph");
log::pushNest(); log::NestScope nest;
if (m_isSetup) { if (m_isSetup) {
log::error("Cannot refresh mod graph after startup"); log::error("Cannot refresh mod graph after startup");
log::popNest();
return; return;
} }
@ -686,48 +662,51 @@ void Loader::Impl::refreshModGraph() {
m_loadingState = LoadingState::Queue; m_loadingState = LoadingState::Queue;
log::debug("Queueing mods"); log::debug("Queueing mods");
log::pushNest();
std::vector<ModMetadata> modQueue; std::vector<ModMetadata> modQueue;
this->queueMods(modQueue); {
log::popNest(); log::NestScope nest;
this->queueMods(modQueue);
}
m_loadingState = LoadingState::List; m_loadingState = LoadingState::List;
log::debug("Populating mod list"); log::debug("Populating mod list");
log::pushNest(); {
this->populateModList(modQueue); log::NestScope nest;
modQueue.clear(); this->populateModList(modQueue);
log::popNest(); modQueue.clear();
}
m_loadingState = LoadingState::Graph; m_loadingState = LoadingState::Graph;
log::debug("Building mod graph"); log::debug("Building mod graph");
log::pushNest(); {
this->buildModGraph(); log::NestScope nest;
log::popNest(); this->buildModGraph();
}
log::debug("Ordering mod stack"); log::debug("Ordering mod stack");
log::pushNest(); {
this->orderModStack(); log::NestScope nest;
log::popNest(); this->orderModStack();
}
m_loadingState = LoadingState::EarlyMods; m_loadingState = LoadingState::EarlyMods;
log::debug("Loading early mods"); log::debug("Loading early mods");
log::pushNest(); {
while (!m_modsToLoad.empty() && m_modsToLoad.front()->needsEarlyLoad()) { log::NestScope nest;
auto mod = m_modsToLoad.front(); while (!m_modsToLoad.empty() && m_modsToLoad.front()->needsEarlyLoad()) {
m_modsToLoad.pop_front(); auto mod = m_modsToLoad.front();
this->loadModGraph(mod, true); m_modsToLoad.pop_front();
this->loadModGraph(mod, true);
}
} }
log::popNest();
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count(); auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
log::info("Took {}s. Continuing next frame...", static_cast<float>(time) / 1000.f); log::info("Took {}s. Continuing next frame...", static_cast<float>(time) / 1000.f);
log::popNest();
m_loadingState = LoadingState::Mods; m_loadingState = LoadingState::Mods;
queueInMainThread([&]() { queueInMainThread([this]() {
this->continueRefreshModGraph(); this->continueRefreshModGraph();
}); });
} }
@ -781,7 +760,7 @@ void Loader::Impl::orderModStack() {
void Loader::Impl::continueRefreshModGraph() { void Loader::Impl::continueRefreshModGraph() {
if (m_refreshingModCount != 0) { if (m_refreshingModCount != 0) {
queueInMainThread([&]() { queueInMainThread([this]() {
this->continueRefreshModGraph(); this->continueRefreshModGraph();
}); });
return; return;
@ -794,28 +773,27 @@ void Loader::Impl::continueRefreshModGraph() {
} }
log::info("Continuing mod graph refresh..."); log::info("Continuing mod graph refresh...");
log::pushNest(); log::NestScope nest;
m_timerBegin = std::chrono::high_resolution_clock::now(); m_timerBegin = std::chrono::high_resolution_clock::now();
switch (m_loadingState) { switch (m_loadingState) {
case LoadingState::Mods: case LoadingState::Mods:
if (!m_modsToLoad.empty()) { if (!m_modsToLoad.empty()) {
log::debug("Loading mods");
log::pushNest();
auto mod = m_modsToLoad.front(); auto mod = m_modsToLoad.front();
m_modsToLoad.pop_front(); m_modsToLoad.pop_front();
log::debug("Loading mod {} {}", mod->getID(), mod->getVersion());
this->loadModGraph(mod, false); this->loadModGraph(mod, false);
log::popNest();
break; break;
} }
m_loadingState = LoadingState::Problems; m_loadingState = LoadingState::Problems;
[[fallthrough]]; [[fallthrough]];
case LoadingState::Problems: case LoadingState::Problems:
log::debug("Finding problems"); log::debug("Finding problems");
log::pushNest(); {
this->findProblems(); log::NestScope nest;
log::popNest(); this->findProblems();
}
m_loadingState = LoadingState::Done; m_loadingState = LoadingState::Done;
{ {
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
@ -831,12 +809,10 @@ void Loader::Impl::continueRefreshModGraph() {
} }
if (m_loadingState != LoadingState::Done) { if (m_loadingState != LoadingState::Done) {
queueInMainThread([&]() { queueInMainThread([this]() {
this->continueRefreshModGraph(); this->continueRefreshModGraph();
}); });
} }
log::popNest();
} }
std::vector<LoadProblem> Loader::Impl::getProblems() const { std::vector<LoadProblem> Loader::Impl::getProblems() const {

View file

@ -160,6 +160,38 @@ struct MyMenuLayer : Modify<MyMenuLayer, MenuLayer> {
} }
}; };
struct AfterMenuLayer : Modify<AfterMenuLayer, MenuLayer> {
static void onModify(auto& self) {
if (self.setHookPriorityAfterPost("MenuLayer::init", "geode.test")) {
log::debug("priority set after test");
}
}
bool init() {
if (!MenuLayer::init()) return false;
log::debug("should run third!");
return true;
}
};
struct BeforeMenuLayer : Modify<BeforeMenuLayer, MenuLayer> {
static void onModify(auto& self) {
if (self.setHookPriorityBeforePost("MenuLayer::init", "geode.test")) {
log::debug("priority set before test");
}
}
bool init() {
if (!MenuLayer::init()) return false;
log::debug("should run first!");
return true;
}
};
$on_mod(Loaded) { $on_mod(Loaded) {
// Mod::get()->addCustomSetting<MySettingValue>("overcast-skies", DEFAULT_ICON); // Mod::get()->addCustomSetting<MySettingValue>("overcast-skies", DEFAULT_ICON);

View file

@ -39,23 +39,26 @@ struct $modify(MenuLayer) {
// Launch arguments // Launch arguments
log::info("Testing launch args..."); log::info("Testing launch args...");
log::pushNest(); log::NestScope nest;
log::info("For global context:"); log::info("For global context:");
log::pushNest(); {
for (const auto& arg : Loader::get()->getLaunchArgumentNames()) { log::NestScope nest;
log::info("{}", arg); for (const auto& arg : Loader::get()->getLaunchArgumentNames()) {
log::info("{}", arg);
}
} }
log::popNest();
log::info("For this mod:"); log::info("For this mod:");
log::pushNest(); {
for (const auto& arg : Mod::get()->getLaunchArgumentNames()) { log::NestScope nest;
log::info("{}", arg); for (const auto& arg : Mod::get()->getLaunchArgumentNames()) {
log::info("{}", arg);
}
} }
log::popNest();
log::info("Mod has launch arg 'mod-arg': {}", Mod::get()->hasLaunchArgument("mod-arg")); log::info("Mod has launch arg 'mod-arg': {}", Mod::get()->hasLaunchArgument("mod-arg"));
log::info("Loader flag 'bool-arg': {}", Loader::get()->getLaunchFlag("bool-arg")); log::info("Loader flag 'bool-arg': {}", Loader::get()->getLaunchFlag("bool-arg"));
log::info("Loader int 'int-arg': {}", Loader::get()->parseLaunchArgument<int>("int-arg").unwrapOr(0)); log::info("Loader int 'int-arg': {}", Loader::get()->parseLaunchArgument<int>("int-arg").unwrapOr(0));
log::popNest();
log::debug("should run second!");
return true; return true;
} }