MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_PluginManager.h" 00009 #include "MyGUI_DynLibManager.h" 00010 #include "MyGUI_ResourceManager.h" 00011 00012 namespace MyGUI 00013 { 00014 00015 typedef void (*DLL_START_PLUGIN)(void); 00016 typedef void (*DLL_STOP_PLUGIN)(void); 00017 00018 template <> PluginManager* Singleton<PluginManager>::msInstance = nullptr; 00019 template <> const char* Singleton<PluginManager>::mClassTypeName = "PluginManager"; 00020 00021 PluginManager::PluginManager() : 00022 mIsInitialise(false), 00023 mXmlPluginTagName("Plugin") 00024 { 00025 } 00026 00027 void PluginManager::initialise() 00028 { 00029 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 00030 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName()); 00031 00032 ResourceManager::getInstance().registerLoadXmlDelegate(mXmlPluginTagName) = newDelegate(this, &PluginManager::_load); 00033 00034 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized"); 00035 mIsInitialise = true; 00036 } 00037 00038 void PluginManager::shutdown() 00039 { 00040 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 00041 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName()); 00042 00043 unloadAllPlugins(); 00044 ResourceManager::getInstance().unregisterLoadXmlDelegate(mXmlPluginTagName); 00045 00046 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown"); 00047 mIsInitialise = false; 00048 } 00049 00050 bool PluginManager::loadPlugin(const std::string& _file) 00051 { 00052 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00053 00054 // Load plugin library 00055 DynLib* lib = DynLibManager::getInstance().load(_file); 00056 if (!lib) 00057 { 00058 MYGUI_LOG(Error, "Plugin '" << _file << "' not found"); 00059 return false; 00060 } 00061 00062 // Call startup function 00063 DLL_START_PLUGIN pFunc = reinterpret_cast<DLL_START_PLUGIN>(lib->getSymbol("dllStartPlugin")); 00064 if (!pFunc) 00065 { 00066 MYGUI_LOG(Error, "Cannot find symbol 'dllStartPlugin' in library " << _file); 00067 return false; 00068 } 00069 00070 // Store for later unload 00071 mLibs[_file] = lib; 00072 00073 // This must call installPlugin 00074 pFunc(); 00075 00076 return true; 00077 } 00078 00079 void PluginManager::unloadPlugin(const std::string& _file) 00080 { 00081 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00082 00083 DynLibList::iterator it = mLibs.find(_file); 00084 if (it != mLibs.end()) 00085 { 00086 // Call plugin shutdown 00087 DLL_STOP_PLUGIN pFunc = reinterpret_cast<DLL_STOP_PLUGIN>((*it).second->getSymbol("dllStopPlugin")); 00088 00089 MYGUI_ASSERT(nullptr != pFunc, getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file); 00090 00091 // this must call uninstallPlugin 00092 pFunc(); 00093 // Unload library (destroyed by DynLibManager) 00094 DynLibManager::getInstance().unload((*it).second); 00095 mLibs.erase(it); 00096 } 00097 } 00098 00099 void PluginManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version) 00100 { 00101 xml::ElementEnumerator node = _node->getElementEnumerator(); 00102 while (node.next()) 00103 { 00104 if (node->getName() == "path") 00105 { 00106 std::string source; 00107 if (node->findAttribute("source", source)) 00108 loadPlugin(source); 00109 } 00110 else if (node->getName() == "Plugin") 00111 { 00112 std::string source; 00113 00114 xml::ElementEnumerator source_node = node->getElementEnumerator(); 00115 while (source_node.next("Source")) 00116 { 00117 std::string build = source_node->findAttribute("build"); 00118 #if MYGUI_DEBUG_MODE == 1 00119 if (build == "Debug") 00120 source = source_node->getContent(); 00121 #else 00122 if (build != "Debug") 00123 source = source_node->getContent(); 00124 #endif 00125 } 00126 if (!source.empty()) 00127 loadPlugin(source); 00128 } 00129 } 00130 } 00131 00132 void PluginManager::installPlugin(IPlugin* _plugin) 00133 { 00134 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00135 00136 MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName()); 00137 00138 mPlugins.insert(_plugin); 00139 _plugin->install(); 00140 00141 _plugin->initialize(); 00142 00143 MYGUI_LOG(Info, "Plugin successfully installed"); 00144 } 00145 00146 void PluginManager::uninstallPlugin(IPlugin* _plugin) 00147 { 00148 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised"); 00149 00150 MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName()); 00151 PluginList::iterator it = mPlugins.find(_plugin); 00152 if (it != mPlugins.end()) 00153 { 00154 _plugin->shutdown(); 00155 _plugin->uninstall(); 00156 mPlugins.erase(it); 00157 } 00158 MYGUI_LOG(Info, "Plugin successfully uninstalled"); 00159 } 00160 00161 void PluginManager::unloadAllPlugins() 00162 { 00163 while (!mLibs.empty()) 00164 unloadPlugin((*mLibs.begin()).first); 00165 } 00166 00167 } // namespace MyGUI