mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
remove schedules, also make Mod::get() lazy
This commit is contained in:
parent
87b8138433
commit
5e1d1eccdb
22 changed files with 124 additions and 129 deletions
|
@ -3,7 +3,6 @@
|
|||
#include <Geode/loader/Mod.hpp>
|
||||
|
||||
GEODE_API void GEODE_CALL geode_implicit_load(geode::Mod* m) {
|
||||
geode::Mod::setSharedMod(m);
|
||||
geode::log::Logger::runScheduled(m);
|
||||
geode::Loader::get()->dispatchScheduledFunctions(m);
|
||||
// geode::Mod::setSharedMod(m);
|
||||
// geode::Loader::get()->dispatchScheduledFunctions(m);
|
||||
}
|
||||
|
|
|
@ -175,10 +175,7 @@ namespace cocos2d::extension {}
|
|||
struct GEODE_CONCAT(ExecFuncUnique, __LINE__) {}; \
|
||||
} \
|
||||
static inline auto GEODE_CONCAT(Exec, __LINE__) = \
|
||||
(Loader::get()->scheduleOnModLoad( \
|
||||
getMod(), \
|
||||
&GEODE_CONCAT(geodeExecFunction, __LINE__) < GEODE_CONCAT(ExecFuncUnique, __LINE__) > \
|
||||
), \
|
||||
(GEODE_CONCAT(geodeExecFunction, __LINE__) < GEODE_CONCAT(ExecFuncUnique, __LINE__) > (), \
|
||||
0); \
|
||||
template <class> \
|
||||
void GEODE_CONCAT(geodeExecFunction, __LINE__)()
|
||||
|
|
|
@ -113,7 +113,7 @@ namespace geode {
|
|||
|
||||
class GEODE_DLL [[nodiscard]] Event {
|
||||
private:
|
||||
static std::unordered_set<EventListenerProtocol*> s_listeners;
|
||||
static std::unordered_set<EventListenerProtocol*>& listeners();
|
||||
friend EventListenerProtocol;
|
||||
|
||||
public:
|
||||
|
|
|
@ -64,11 +64,9 @@ namespace geode {
|
|||
|
||||
template<class = void>
|
||||
std::monostate listenForIPC(std::string const& messageID, nlohmann::json(*callback)(IPCEvent*)) {
|
||||
Loader::get()->scheduleOnModLoad(getMod(), [=]() {
|
||||
new EventListener(
|
||||
(void) new EventListener(
|
||||
callback, IPCFilter(getMod()->getID(), messageID)
|
||||
);
|
||||
});
|
||||
return std::monostate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace geode {
|
|||
|
||||
Result<Mod*> loadModFromInfo(ModInfo const& info);
|
||||
|
||||
Mod* takeNextMod();
|
||||
|
||||
public:
|
||||
// TODO: do we want to expose all of these functions?
|
||||
static Loader* get();
|
||||
|
@ -64,7 +66,6 @@ namespace geode {
|
|||
void updateResources();
|
||||
|
||||
void queueInGDThread(ScheduledFunction func);
|
||||
void scheduleOnModLoad(Mod* mod, ScheduledFunction func);
|
||||
void waitForModsToBeLoaded();
|
||||
|
||||
/**
|
||||
|
@ -79,5 +80,16 @@ namespace geode {
|
|||
bool didLastLaunchCrash() const;
|
||||
|
||||
friend class LoaderImpl;
|
||||
|
||||
friend Mod* takeNextLoaderMod();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Take the next mod to load
|
||||
*
|
||||
* @return Mod* The next mod to load
|
||||
*/
|
||||
inline GEODE_HIDDEN Mod* takeNextLoaderMod() {
|
||||
return Loader::get()->takeNextMod();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,40 +114,22 @@ namespace geode {
|
|||
Logger() = delete;
|
||||
~Logger() = delete;
|
||||
|
||||
// Unscheduled logs
|
||||
// logs
|
||||
static void _push(Log&& log);
|
||||
|
||||
// Scheduled functions
|
||||
template <class = void>
|
||||
static inline std::vector<Log>& scheduled() {
|
||||
static std::vector<Log> scheduledLogs;
|
||||
return scheduledLogs;
|
||||
}
|
||||
static void run(Mod* m, std::vector<Log>& scheduled);
|
||||
|
||||
public:
|
||||
static void setup();
|
||||
|
||||
static inline void push(Log&& log) {
|
||||
if (log.m_sender == nullptr)
|
||||
Logger::scheduled().push_back(std::move(log));
|
||||
else
|
||||
Logger::_push(std::move(log));
|
||||
}
|
||||
|
||||
static inline void pop(Log* log) {
|
||||
if (log->m_sender == nullptr)
|
||||
geode::utils::ranges::remove(Logger::scheduled(), *log);
|
||||
else
|
||||
geode::utils::ranges::remove(Logger::s_logs, *log);
|
||||
}
|
||||
|
||||
static std::vector<Log*> list();
|
||||
static void clear();
|
||||
|
||||
static inline void runScheduled(Mod* m) {
|
||||
Logger::run(m, Logger::scheduled());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace geode {
|
|||
~HandleToSaved();
|
||||
};
|
||||
|
||||
inline GEODE_HIDDEN Mod* takeNextLoaderMod();
|
||||
|
||||
/**
|
||||
* @class Mod
|
||||
* Represents a Mod ingame.
|
||||
|
@ -225,6 +227,9 @@ namespace geode {
|
|||
*/
|
||||
template <class = void>
|
||||
static inline GEODE_HIDDEN Mod* get() {
|
||||
if (!sharedMod<>) {
|
||||
sharedMod<> = takeNextLoaderMod();
|
||||
}
|
||||
return sharedMod<>;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,13 +47,9 @@ void GEODE_CONCAT(geodeExecFunction, __LINE__)(ModStateEvent*); \
|
|||
namespace { \
|
||||
struct GEODE_CONCAT(ExecFuncUnique, __LINE__) {}; \
|
||||
} \
|
||||
static inline auto GEODE_CONCAT(Exec, __LINE__) = (geode::Loader::get()->scheduleOnModLoad(\
|
||||
geode::Mod::get(), []() { \
|
||||
new geode::EventListener( \
|
||||
static inline auto GEODE_CONCAT(Exec, __LINE__) = (new geode::EventListener( \
|
||||
&GEODE_CONCAT(geodeExecFunction, __LINE__)<GEODE_CONCAT(ExecFuncUnique, __LINE__)>,\
|
||||
geode::ModStateFilter(geode::Mod::get(), geode::ModEventType::type)\
|
||||
); \
|
||||
} \
|
||||
), 0); \
|
||||
template<class> \
|
||||
void GEODE_CONCAT(geodeExecFunction, __LINE__)(ModStateEvent*)
|
||||
|
|
|
@ -56,20 +56,16 @@ namespace geode {
|
|||
std::monostate listenForSettingChanges(
|
||||
std::string const& settingID, void (*callback)(T*)
|
||||
) {
|
||||
Loader::get()->scheduleOnModLoad(getMod(), [=]() {
|
||||
new EventListener(
|
||||
(void)new EventListener(
|
||||
callback, SettingChangedFilter<T>(getMod()->getID(), settingID)
|
||||
);
|
||||
});
|
||||
return std::monostate();
|
||||
}
|
||||
|
||||
static std::monostate listenForAllSettingChanges(void (*callback)(Setting*)) {
|
||||
Loader::get()->scheduleOnModLoad(getMod(), [=]() {
|
||||
new EventListener(
|
||||
(void)new EventListener(
|
||||
callback, SettingChangedFilter(getMod()->getID())
|
||||
);
|
||||
});
|
||||
return std::monostate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,7 @@ namespace geode::modifier {
|
|||
public:
|
||||
// unordered_map<handles> idea
|
||||
ModifyBase() {
|
||||
Loader::get()->scheduleOnModLoad(getMod(), []() {
|
||||
Derived::apply();
|
||||
});
|
||||
}
|
||||
template <class, class>
|
||||
friend class ModifyDerive;
|
||||
|
|
|
@ -26,7 +26,7 @@ if (GEODE_TARGET_PLATFORM STREQUAL "iOS")
|
|||
target_link_libraries(lilac_hook "-F ${CMAKE_CURRENT_SOURCE_DIR}/../ios -framework CydiaSubstrate")
|
||||
endif()
|
||||
|
||||
target_compile_features(lilac_hook PUBLIC cxx_std_17)
|
||||
target_compile_features(lilac_hook PUBLIC cxx_std_20)
|
||||
target_include_directories(lilac_hook
|
||||
PRIVATE
|
||||
${lilac_SOURCE_DIR}/include/geode/core/hook
|
||||
|
|
|
@ -42,15 +42,12 @@ static ModInfo getInternalModInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
InternalMod::InternalMod() : Mod(getInternalModInfo()) {
|
||||
InternalMod::InternalMod() : Mod(ModInfo()) {}
|
||||
|
||||
void InternalMod::setModInfo() {
|
||||
m_info = getInternalModInfo();
|
||||
m_saveDirPath = dirs::getModsSaveDir() / m_info.id;
|
||||
|
||||
ghc::filesystem::create_directories(m_saveDirPath);
|
||||
|
||||
auto sett = this->loadData();
|
||||
if (!sett) {
|
||||
log::internalLog(Severity::Error, this, "{}", sett.unwrapErr());
|
||||
}
|
||||
}
|
||||
|
||||
InternalMod::~InternalMod() {}
|
||||
|
|
|
@ -13,4 +13,6 @@ protected:
|
|||
|
||||
public:
|
||||
static InternalMod* get();
|
||||
|
||||
void setModInfo();
|
||||
};
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
std::unordered_set<EventListenerProtocol*> Event::s_listeners = {};
|
||||
|
||||
void EventListenerProtocol::enable() {
|
||||
Event::s_listeners.insert(this);
|
||||
Event::listeners().insert(this);
|
||||
}
|
||||
|
||||
void EventListenerProtocol::disable() {
|
||||
Event::s_listeners.erase(this);
|
||||
Event::listeners().erase(this);
|
||||
}
|
||||
|
||||
EventListenerProtocol::~EventListenerProtocol() {
|
||||
|
@ -21,9 +19,14 @@ Event::~Event() {}
|
|||
void Event::postFrom(Mod* m) {
|
||||
if (m) this->sender = m;
|
||||
|
||||
for (auto h : Event::s_listeners) {
|
||||
for (auto h : Event::listeners()) {
|
||||
if (h->passThrough(this) == ListenerResult::Stop) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<EventListenerProtocol*>& Event::listeners() {
|
||||
static std::unordered_set<EventListenerProtocol*> listeners;
|
||||
return listeners;
|
||||
}
|
|
@ -21,10 +21,6 @@ void Loader::addSearchPaths() {
|
|||
return m_impl->addSearchPaths();
|
||||
}
|
||||
|
||||
void Loader::dispatchScheduledFunctions(Mod* mod) {
|
||||
return m_impl->dispatchScheduledFunctions(mod);
|
||||
}
|
||||
|
||||
Result<Mod*> Loader::loadModFromInfo(ModInfo const& info) {
|
||||
return m_impl->loadModFromInfo(info);
|
||||
}
|
||||
|
@ -105,10 +101,6 @@ void Loader::queueInGDThread(ScheduledFunction func) {
|
|||
return m_impl->queueInGDThread(func);
|
||||
}
|
||||
|
||||
void Loader::scheduleOnModLoad(Mod* mod, ScheduledFunction func) {
|
||||
return m_impl->scheduleOnModLoad(mod, func);
|
||||
}
|
||||
|
||||
void Loader::waitForModsToBeLoaded() {
|
||||
return m_impl->waitForModsToBeLoaded();
|
||||
}
|
||||
|
@ -124,3 +116,7 @@ void Loader::closePlatformConsole() {
|
|||
bool Loader::didLastLaunchCrash() const {
|
||||
return m_impl->didLastLaunchCrash();
|
||||
}
|
||||
|
||||
Mod* Loader::takeNextMod() {
|
||||
return m_impl->takeNextMod();
|
||||
}
|
|
@ -245,22 +245,6 @@ Mod* Loader::Impl::getLoadedMod(std::string const& id) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void Loader::Impl::dispatchScheduledFunctions(Mod* mod) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
for (auto& func : m_scheduledFunctions) {
|
||||
func();
|
||||
}
|
||||
m_scheduledFunctions.clear();
|
||||
}
|
||||
|
||||
void Loader::Impl::scheduleOnModLoad(Mod* mod, ScheduledFunction func) {
|
||||
std::lock_guard _(m_scheduledFunctionsMutex);
|
||||
if (mod) {
|
||||
return func();
|
||||
}
|
||||
m_scheduledFunctions.push_back(func);
|
||||
}
|
||||
|
||||
void Loader::Impl::updateModResources(Mod* mod) {
|
||||
if (!mod->m_info.spritesheets.size()) {
|
||||
return;
|
||||
|
@ -594,3 +578,44 @@ ListenerResult ResourceDownloadFilter::handle(
|
|||
}
|
||||
|
||||
ResourceDownloadFilter::ResourceDownloadFilter() {}
|
||||
|
||||
void Loader::Impl::provideNextMod(Mod* mod) {
|
||||
m_nextModLock.lock();
|
||||
m_nextMod = mod;
|
||||
}
|
||||
Mod* Loader::Impl::takeNextMod() {
|
||||
if (!m_nextMod) {
|
||||
// this means we're hopefully loading the internal mod
|
||||
// TODO: make this less hacky
|
||||
auto res = this->setupInternalMod();
|
||||
if (!res) {
|
||||
log::error("{}", res.unwrapErr());
|
||||
return nullptr;
|
||||
}
|
||||
return m_nextMod;
|
||||
}
|
||||
auto ret = m_nextMod;
|
||||
m_nextModCV.notify_all();
|
||||
return ret;
|
||||
}
|
||||
void Loader::Impl::releaseNextMod() {
|
||||
auto lock = std::unique_lock<std::mutex>(m_nextModAccessMutex);
|
||||
m_nextModCV.wait(lock);
|
||||
|
||||
m_nextModLock.unlock();
|
||||
}
|
||||
|
||||
Result<> Loader::Impl::setupInternalMod() {
|
||||
this->provideNextMod(InternalMod::get());
|
||||
(void)Mod::get();
|
||||
m_nextModLock.unlock();
|
||||
|
||||
InternalMod::get()->setModInfo();
|
||||
|
||||
auto sett = Mod::get()->loadData();
|
||||
if (!sett) {
|
||||
log::error("{}", sett.unwrapErr());
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
|
@ -46,8 +46,6 @@ public:
|
|||
std::vector<InvalidGeodeFile> m_invalidMods;
|
||||
std::unordered_map<std::string, Mod*> m_mods;
|
||||
std::vector<ghc::filesystem::path> m_texturePaths;
|
||||
std::vector<ScheduledFunction> m_scheduledFunctions;
|
||||
mutable std::mutex m_scheduledFunctionsMutex;
|
||||
bool m_isSetup = false;
|
||||
|
||||
std::condition_variable m_earlyLoadFinishedCV;
|
||||
|
@ -59,6 +57,18 @@ public:
|
|||
std::vector<std::pair<Hook*, Mod*>> m_internalHooks;
|
||||
bool m_readyToHook = false;
|
||||
|
||||
std::mutex m_nextModMutex;
|
||||
std::unique_lock<std::mutex> m_nextModLock = std::unique_lock<std::mutex>(m_nextModMutex, std::defer_lock);
|
||||
std::condition_variable m_nextModCV;
|
||||
std::mutex m_nextModAccessMutex;
|
||||
Mod* m_nextMod = nullptr;
|
||||
|
||||
Result<> setupInternalMod();
|
||||
|
||||
void provideNextMod(Mod* mod);
|
||||
Mod* takeNextMod();
|
||||
void releaseNextMod();
|
||||
|
||||
void downloadLoaderResources();
|
||||
|
||||
bool loadHooks();
|
||||
|
@ -72,7 +82,6 @@ public:
|
|||
void updateModResources(Mod* mod);
|
||||
void addSearchPaths();
|
||||
|
||||
void dispatchScheduledFunctions(Mod* mod);
|
||||
friend void GEODE_CALL ::geode_implicit_load(Mod*);
|
||||
|
||||
Result<Mod*> loadModFromInfo(ModInfo const& info);
|
||||
|
@ -102,7 +111,6 @@ public:
|
|||
|
||||
void updateResources();
|
||||
|
||||
void scheduleOnModLoad(Mod* mod, ScheduledFunction func);
|
||||
void waitForModsToBeLoaded();
|
||||
|
||||
bool didLastLaunchCrash() const;
|
||||
|
|
|
@ -106,7 +106,7 @@ std::string Log::toString(bool logTime) const {
|
|||
res += fmt::format("{:%H:%M:%S}", m_time);
|
||||
}
|
||||
|
||||
res += fmt::format(" [{}]: ", m_sender ? m_sender->getName() : "?");
|
||||
res += fmt::format(" [{}]: ", m_sender ? m_sender->getName() : "Geode?");
|
||||
|
||||
for (auto& i : m_components) {
|
||||
res += i->_toString();
|
||||
|
@ -209,15 +209,6 @@ void Logger::clear() {
|
|||
s_logs.clear();
|
||||
}
|
||||
|
||||
void Logger::run(Mod* m, std::vector<Log>& scheduled) {
|
||||
for (auto&& log : scheduled) {
|
||||
log.m_sender = m;
|
||||
Logger::_push(std::move(log));
|
||||
}
|
||||
|
||||
scheduled.clear();
|
||||
}
|
||||
|
||||
// Misc
|
||||
|
||||
std::string geode::log::generateLogName() {
|
||||
|
|
|
@ -203,6 +203,8 @@ Result<> Mod::loadBinary() {
|
|||
return Err("Mod has unresolved dependencies");
|
||||
}
|
||||
|
||||
LoaderImpl::get()->provideNextMod(this);
|
||||
|
||||
GEODE_UNWRAP(this->loadPlatformBinary());
|
||||
m_binaryLoaded = true;
|
||||
|
||||
|
|
|
@ -147,16 +147,6 @@ static auto $_ = listenForIPC("list-mods", [](IPCEvent* event) -> nlohmann::json
|
|||
int geodeEntry(void* platformData) {
|
||||
// setup internals
|
||||
|
||||
if (!Loader::get()) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Unable to Load Geode!",
|
||||
"There was an unknown fatal error setting up "
|
||||
"internal tools and Geode can not be loaded. "
|
||||
"(Loader::get returned nullptr)"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!geode::core::hook::initialize()) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Unable to load Geode!",
|
||||
|
@ -167,8 +157,6 @@ int geodeEntry(void* platformData) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
geode_implicit_load(InternalMod::get());
|
||||
|
||||
// set up loader, load mods, etc.
|
||||
if (!LoaderImpl::get()->setup()) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"geode": "0.4.1",
|
||||
"geode": "0.6.1",
|
||||
"version": "1.0.0",
|
||||
"id": "geode.testdep",
|
||||
"name": "Geode Test Dependency",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"geode": "0.4.1",
|
||||
"geode": "0.6.1",
|
||||
"version": "1.0.0",
|
||||
"id": "geode.test",
|
||||
"name": "Geode Test",
|
||||
|
|
Loading…
Reference in a new issue