MyGUI
3.2.0
|
00001 00006 /* 00007 This file is part of MyGUI. 00008 00009 MyGUI is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Lesser General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 MyGUI is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 #include "MyGUI_Precompiled.h" 00023 #include "MyGUI_PluginManager.h" 00024 #include "MyGUI_DynLibManager.h" 00025 #include "MyGUI_ResourceManager.h" 00026 00027 namespace MyGUI 00028 { 00029 typedef void (*DLL_START_PLUGIN)(void); 00030 typedef void (*DLL_STOP_PLUGIN)(void); 00031 00032 const std::string XML_TYPE("Plugin"); 00033 00034 template <> PluginManager* Singleton<PluginManager>::msInstance = nullptr; 00035 template <> const char* Singleton<PluginManager>::mClassTypeName("PluginManager"); 00036 00037 PluginManager::PluginManager() : 00038 mIsInitialise(false) 00039 { 00040 } 00041 00042 void PluginManager::initialise() 00043 { 00044 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 00045 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName()); 00046 00047 ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &PluginManager::_load); 00048 00049 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized"); 00050 mIsInitialise = true; 00051 } 00052 00053 void PluginManager::shutdown() 00054 { 00055 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 00056 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName()); 00057 00058 unloadAllPlugins(); 00059 ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE); 00060 00061 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown"); 00062 mIsInitialise = false; 00063 } 00064 00065 bool PluginManager::loadPlugin(const std::string& _file) 00066 { 00067 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00068 00069 // Load plugin library 00070 DynLib* lib = DynLibManager::getInstance().load(_file); 00071 if (!lib) 00072 { 00073 MYGUI_LOG(Error, "Plugin '" << _file << "' not found"); 00074 return false; 00075 } 00076 00077 // Call startup function 00078 DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin"); 00079 if (!pFunc) 00080 { 00081 MYGUI_LOG(Error, "Cannot find symbol 'dllStartPlugin' in library " << _file); 00082 return false; 00083 } 00084 00085 // Store for later unload 00086 mLibs[_file] = lib; 00087 00088 // This must call installPlugin 00089 pFunc(); 00090 00091 return true; 00092 } 00093 00094 void PluginManager::unloadPlugin(const std::string& _file) 00095 { 00096 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00097 00098 DynLibList::iterator it = mLibs.find(_file); 00099 if (it != mLibs.end()) 00100 { 00101 // Call plugin shutdown 00102 DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*it).second->getSymbol("dllStopPlugin"); 00103 00104 MYGUI_ASSERT(nullptr != pFunc, getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file); 00105 00106 // this must call uninstallPlugin 00107 pFunc(); 00108 // Unload library (destroyed by DynLibManager) 00109 DynLibManager::getInstance().unload((*it).second); 00110 mLibs.erase(it); 00111 } 00112 } 00113 00114 void PluginManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version) 00115 { 00116 xml::ElementEnumerator node = _node->getElementEnumerator(); 00117 while (node.next()) 00118 { 00119 if (node->getName() == "path") 00120 { 00121 std::string source; 00122 if (node->findAttribute("source", source)) 00123 loadPlugin(source); 00124 } 00125 else if (node->getName() == "Plugin") 00126 { 00127 std::string source, source_debug; 00128 00129 xml::ElementEnumerator source_node = node->getElementEnumerator(); 00130 while (source_node.next("Source")) 00131 { 00132 std::string build = source_node->findAttribute("build"); 00133 if (build == "Debug") 00134 source_debug = source_node->getContent(); 00135 else 00136 source = source_node->getContent(); 00137 } 00138 #if MYGUI_DEBUG_MODE == 0 00139 if (!source.empty()) 00140 loadPlugin(source); 00141 #else 00142 if (!source_debug.empty()) 00143 loadPlugin(source_debug); 00144 #endif 00145 } 00146 } 00147 } 00148 00149 void PluginManager::installPlugin(IPlugin* _plugin) 00150 { 00151 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00152 00153 MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName()); 00154 00155 mPlugins.insert(_plugin); 00156 _plugin->install(); 00157 00158 _plugin->initialize(); 00159 00160 MYGUI_LOG(Info, "Plugin successfully installed"); 00161 } 00162 00163 void PluginManager::uninstallPlugin(IPlugin* _plugin) 00164 { 00165 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00166 00167 MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName()); 00168 PluginList::iterator it = mPlugins.find(_plugin); 00169 if (it != mPlugins.end()) 00170 { 00171 _plugin->shutdown(); 00172 _plugin->uninstall(); 00173 mPlugins.erase(it); 00174 } 00175 MYGUI_LOG(Info, "Plugin successfully uninstalled"); 00176 } 00177 00178 void PluginManager::unloadAllPlugins() 00179 { 00180 while (!mLibs.empty()) 00181 unloadPlugin((*mLibs.begin()).first); 00182 } 00183 00184 } // namespace MyGUI