Otclient  14/8/2020
modulemanager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "modulemanager.h"
24 #include "resourcemanager.h"
25 
26 #include <framework/otml/otml.h>
28 
30 
32 {
33  m_modules.clear();
34  m_autoLoadModules.clear();
35 }
36 
38 {
39  // remove modules that are not loaded
40  m_autoLoadModules.clear();
41 
42  auto moduleDirs = g_resources.listDirectoryFiles("/");
43  for(const std::string& moduleDir : moduleDirs) {
44  auto moduleFiles = g_resources.listDirectoryFiles("/" + moduleDir);
45  for(const std::string& moduleFile : moduleFiles) {
46  if(g_resources.isFileType(moduleFile, "otmod")) {
47  ModulePtr module = discoverModule("/" + moduleDir + "/" + moduleFile);
48  if(module && module->isAutoLoad())
49  m_autoLoadModules.insert(std::make_pair(module->getAutoLoadPriority(), module));
50  }
51  }
52  }
53 }
54 
55 void ModuleManager::autoLoadModules(int maxPriority)
56 {
57  for(auto& pair : m_autoLoadModules) {
58  int priority = pair.first;
59  if(priority > maxPriority)
60  break;
61  ModulePtr module = pair.second;
62  module->load();
63  }
64 }
65 
66 ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
67 {
68  ModulePtr module;
69  try {
70  OTMLDocumentPtr doc = OTMLDocument::parse(moduleFile);
71  OTMLNodePtr moduleNode = doc->at("Module");
72 
73  std::string name = moduleNode->valueAt("name");
74 
75  bool push = false;
76  module = getModule(name);
77  if(!module) {
78  module = ModulePtr(new Module(name));
79  push = true;
80  }
81  module->discover(moduleNode);
82 
83  // not loaded modules are always in back
84  if(push)
85  m_modules.push_back(module);
86  } catch(stdext::exception& e) {
87  g_logger.error(stdext::format("Unable to discover module from file '%s': %s", moduleFile, e.what()));
88  }
89  return module;
90 }
91 
92 void ModuleManager::ensureModuleLoaded(const std::string& moduleName)
93 {
94  ModulePtr module = g_modules.getModule(moduleName);
95  if(!module || !module->load())
96  g_logger.fatal(stdext::format("Unable to load '%s' module", moduleName));
97 }
98 
100 {
101  auto modulesBackup = m_modules;
102  for(const ModulePtr& module : modulesBackup)
103  module->unload();
104 }
105 
107 {
108  std::deque<ModulePtr> toLoadList;
109 
110  // unload in the reverse direction, try to unload upto 10 times (because of dependencies)
111  for(int i=0;i<10;++i) {
112  auto modulesBackup = m_modules;
113  for(const ModulePtr& module : modulesBackup) {
114  if(module->isLoaded() && module->canUnload()) {
115  module->unload();
116  toLoadList.push_front(module);
117  }
118  }
119  }
120 
121  for(const ModulePtr& module : toLoadList)
122  module->load();
123 }
124 
125 ModulePtr ModuleManager::getModule(const std::string& moduleName)
126 {
127  for(const ModulePtr& module : m_modules)
128  if(module->getName() == moduleName)
129  return module;
130  return nullptr;
131 }
132 
134 {
135  auto it = std::find(m_modules.begin(), m_modules.end(), module);
136  if(it != m_modules.end())
137  m_modules.erase(it);
138  if(module->isLoaded())
139  m_modules.push_front(module);
140  else
141  m_modules.push_back(module);
142 }
ResourceManager::isFileType
bool isFileType(const std::string &filename, const std::string &type)
Definition: resourcemanager.cpp:359
ResourceManager::listDirectoryFiles
std::list< std::string > listDirectoryFiles(const std::string &directoryPath="")
Definition: resourcemanager.cpp:268
otml.h
ModuleManager::getModule
ModulePtr getModule(const std::string &moduleName)
Definition: modulemanager.cpp:125
OTMLDocument::parse
static OTMLDocumentPtr parse(const std::string &fileName)
Parse OTML from a file.
Definition: otmldocument.cpp:36
resourcemanager.h
Logger::error
void error(const std::string &what)
Definition: logger.h:54
ModuleManager::reloadModules
void reloadModules()
Definition: modulemanager.cpp:106
ModuleManager::clear
void clear()
Definition: modulemanager.cpp:31
stdext::format
std::string format()
Definition: format.h:82
Logger::fatal
void fatal(const std::string &what)
Definition: logger.h:55
g_resources
ResourceManager g_resources
Definition: resourcemanager.cpp:32
ModuleManager
Definition: modulemanager.h:29
ModuleManager::unloadModules
void unloadModules()
Definition: modulemanager.cpp:99
OTMLNode::valueAt
T valueAt(const std::string &childTag)
Definition: otmlnode.h:130
ModuleManager::Module
friend class Module
Definition: modulemanager.h:47
g_logger
Logger g_logger
Definition: logger.cpp:35
ModuleManager::updateModuleLoadOrder
void updateModuleLoadOrder(ModulePtr module)
Definition: modulemanager.cpp:133
ModuleManager::autoLoadModules
void autoLoadModules(int maxPriority)
Definition: modulemanager.cpp:55
ModuleManager::discoverModule
ModulePtr discoverModule(const std::string &moduleFile)
Definition: modulemanager.cpp:66
ModuleManager::discoverModules
void discoverModules()
Definition: modulemanager.cpp:37
stdext::exception::what
virtual const char * what() const
Definition: exception.h:37
stdext::shared_object_ptr
Definition: shared_object.h:39
modulemanager.h
ModuleManager::ensureModuleLoaded
void ensureModuleLoaded(const std::string &moduleName)
Definition: modulemanager.cpp:92
ModulePtr
stdext::shared_object_ptr< Module > ModulePtr
Definition: declarations.h:37
g_modules
ModuleManager g_modules
Definition: modulemanager.cpp:29
OTMLNode::at
OTMLNodePtr at(const std::string &childTag)
Definition: otmlnode.cpp:70
application.h
stdext::exception
Definition: exception.h:31