mirror of
https://github.com/edubart/otclient.git
synced 2025-10-19 05:53:26 +02:00
a lot of changes in modules
This commit is contained in:
@@ -33,7 +33,7 @@ public:
|
||||
Event(const SimpleCallback& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
|
||||
|
||||
void execute() {
|
||||
if(!m_canceled && !m_executed) {
|
||||
if(!m_canceled && !m_executed && m_callback) {
|
||||
m_callback();
|
||||
m_executed = true;
|
||||
}
|
||||
|
@@ -52,8 +52,10 @@ bool Module::load()
|
||||
if(m_loadCallback)
|
||||
m_loadCallback();
|
||||
|
||||
logInfo("Loaded module '", m_name, "'");
|
||||
m_loaded = true;
|
||||
logInfo("Loaded module '", m_name, "'");
|
||||
g_modules.updateModuleLoadOrder(asModule());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,9 +65,33 @@ void Module::unload()
|
||||
if(m_unloadCallback)
|
||||
m_unloadCallback();
|
||||
m_loaded = false;
|
||||
logInfo("Unloaded module '", m_name, "'");
|
||||
g_modules.updateModuleLoadOrder(asModule());
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::reload()
|
||||
{
|
||||
unload();
|
||||
return load();
|
||||
}
|
||||
|
||||
bool Module::isDependent()
|
||||
{
|
||||
for(const ModulePtr& module : g_modules.getModules()) {
|
||||
if(module->isLoaded() && module->hasDependency(m_name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Module::hasDependency(const std::string& name)
|
||||
{
|
||||
if(std::find(m_dependencies.begin(), m_dependencies.end(), name) != m_dependencies.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Module::discover(const OTMLNodePtr& moduleNode)
|
||||
{
|
||||
const static std::string none = "none";
|
||||
@@ -73,8 +99,9 @@ void Module::discover(const OTMLNodePtr& moduleNode)
|
||||
m_author = moduleNode->valueAt("author", none);
|
||||
m_website = moduleNode->valueAt("website", none);
|
||||
m_version = moduleNode->valueAt("version", none);
|
||||
m_autoLoad = moduleNode->valueAt<bool>("autoLoad", false);
|
||||
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoLoadAntecedence", 100);
|
||||
m_autoLoad = moduleNode->valueAt<bool>("autoload", false);
|
||||
m_unloadable = moduleNode->valueAt<bool>("unloadable", true);
|
||||
m_autoLoadAntecedence = moduleNode->valueAt<int>("autoload-antecedence", 9999);
|
||||
|
||||
if(OTMLNodePtr node = moduleNode->get("dependencies")) {
|
||||
for(const OTMLNodePtr& tmp : node->children())
|
||||
@@ -95,4 +122,3 @@ void Module::discover(const OTMLNodePtr& moduleNode)
|
||||
m_unloadCallback = g_lua.polymorphicPop<SimpleCallback>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,8 +35,12 @@ public:
|
||||
|
||||
bool load();
|
||||
void unload();
|
||||
bool reload();
|
||||
|
||||
bool canUnload() { return m_loaded && m_unloadable && !isDependent(); }
|
||||
bool isLoaded() { return m_loaded; }
|
||||
bool isDependent();
|
||||
bool hasDependency(const std::string& name);
|
||||
|
||||
std::string getDescription() { return m_description; }
|
||||
std::string getName() { return m_name; }
|
||||
@@ -46,6 +50,8 @@ public:
|
||||
bool isAutoLoad() { return m_autoLoad; }
|
||||
int getAutoLoadAntecedence() { return m_autoLoadAntecedence; }
|
||||
|
||||
ModulePtr asModule() { return std::static_pointer_cast<Module>(shared_from_this()); }
|
||||
|
||||
protected:
|
||||
void discover(const OTMLNodePtr& moduleNode);
|
||||
friend class ModuleManager;
|
||||
@@ -53,6 +59,7 @@ protected:
|
||||
private:
|
||||
Boolean<false> m_loaded;
|
||||
Boolean<false> m_autoLoad;
|
||||
Boolean<true> m_unloadable;
|
||||
int m_autoLoadAntecedence;
|
||||
std::string m_name;
|
||||
std::string m_description;
|
||||
|
@@ -61,13 +61,13 @@ void ModuleManager::autoLoadModules(int maxAntecedence)
|
||||
void ModuleManager::discoverModulesPath()
|
||||
{
|
||||
// search for modules directory
|
||||
std::string possibleDirs[] = { "modules",
|
||||
g_resources.getBaseDir() + "modules",
|
||||
g_resources.getBaseDir() + "../modules",
|
||||
g_resources.getBaseDir() + "../share/" + g_app->getAppName() + "/modules",
|
||||
"" };
|
||||
std::string possibleModulesDirs[] = { "modules",
|
||||
g_resources.getBaseDir() + "modules",
|
||||
g_resources.getBaseDir() + "../modules",
|
||||
g_resources.getBaseDir() + "../share/" + g_app->getAppName() + "/modules",
|
||||
"" };
|
||||
bool found = false;
|
||||
for(const std::string& dir : possibleDirs) {
|
||||
for(const std::string& dir : possibleModulesDirs) {
|
||||
// try to add module directory
|
||||
if(g_resources.addToSearchPath(dir, false)) {
|
||||
logInfo("Using modules directory '", dir.c_str(), "'");
|
||||
@@ -78,6 +78,21 @@ void ModuleManager::discoverModulesPath()
|
||||
|
||||
if(!found)
|
||||
logFatal("Could not find modules directory");
|
||||
|
||||
// search for addons directory
|
||||
std::string possibleAddonsDirs[] = { "addons",
|
||||
g_resources.getBaseDir() + "addons",
|
||||
g_resources.getBaseDir() + "../addons",
|
||||
g_resources.getBaseDir() + "../addons/" + g_app->getAppName() + "/modules",
|
||||
"" };
|
||||
for(const std::string& dir : possibleAddonsDirs) {
|
||||
// try to add module directory
|
||||
if(g_resources.addToSearchPath(dir, false)) {
|
||||
logInfo("Using addons directory '", dir.c_str(), "'");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
|
||||
@@ -99,6 +114,7 @@ ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
|
||||
}
|
||||
module->discover(moduleNode);
|
||||
|
||||
// not loaded modules are always in back
|
||||
if(push)
|
||||
m_modules.push_back(module);
|
||||
} catch(Exception& e) {
|
||||
@@ -116,10 +132,30 @@ void ModuleManager::ensureModuleLoaded(const std::string& moduleName)
|
||||
|
||||
void ModuleManager::unloadModules()
|
||||
{
|
||||
for(const ModulePtr& module : m_modules)
|
||||
auto modulesBackup = m_modules;
|
||||
for(const ModulePtr& module : modulesBackup)
|
||||
module->unload();
|
||||
}
|
||||
|
||||
void ModuleManager::reloadModules()
|
||||
{
|
||||
std::deque<ModulePtr> toLoadList;
|
||||
|
||||
// unload in the reverse direction, try to unload upto 10 times (because of dependencies)
|
||||
for(int i=0;i<10;++i) {
|
||||
auto modulesBackup = m_modules;
|
||||
for(const ModulePtr& module : modulesBackup) {
|
||||
if(module->isLoaded() && module->canUnload()) {
|
||||
module->unload();
|
||||
toLoadList.push_front(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(const ModulePtr& module : toLoadList)
|
||||
module->load();
|
||||
}
|
||||
|
||||
ModulePtr ModuleManager::getModule(const std::string& moduleName)
|
||||
{
|
||||
for(const ModulePtr& module : m_modules)
|
||||
@@ -127,3 +163,14 @@ ModulePtr ModuleManager::getModule(const std::string& moduleName)
|
||||
return module;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ModuleManager::updateModuleLoadOrder(ModulePtr module)
|
||||
{
|
||||
auto it = std::find(m_modules.begin(), m_modules.end(), module);
|
||||
if(it != m_modules.end())
|
||||
m_modules.erase(it);
|
||||
if(module->isLoaded())
|
||||
m_modules.push_front(module);
|
||||
else
|
||||
m_modules.push_back(module);
|
||||
}
|
||||
|
@@ -34,12 +34,18 @@ public:
|
||||
ModulePtr discoverModule(const std::string& moduleFile);
|
||||
void ensureModuleLoaded(const std::string& moduleName);
|
||||
void unloadModules();
|
||||
void reloadModules();
|
||||
|
||||
ModulePtr getModule(const std::string& moduleName);
|
||||
std::vector<ModulePtr> getModules() { return m_modules; }
|
||||
std::deque<ModulePtr> getModules() { return m_modules; }
|
||||
|
||||
protected:
|
||||
void updateModuleLoadOrder(ModulePtr module);
|
||||
|
||||
friend class Module;
|
||||
|
||||
private:
|
||||
std::vector<ModulePtr> m_modules;
|
||||
std::deque<ModulePtr> m_modules;
|
||||
std::multimap<int, ModulePtr> m_autoLoadModules;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user