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