a lot of changes in modules

This commit is contained in:
Eduardo Bart
2012-02-06 17:19:47 -02:00
parent add8505a5b
commit 88301c329a
50 changed files with 488 additions and 322 deletions

View File

@@ -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;
}

View File

@@ -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>();
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
};