MyGUI  3.4.0
MyGUI_PluginManager.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_PluginManager.h"
9 #include "MyGUI_DynLibManager.h"
10 #include "MyGUI_ResourceManager.h"
11 
12 namespace MyGUI
13 {
14 
15  using DLL_START_PLUGIN = void (*)();
16  using DLL_STOP_PLUGIN = void (*)();
17 
19  template <> const char* Singleton<PluginManager>::mClassTypeName = "PluginManager";
20 
22  mIsInitialise(false),
23  mXmlPluginTagName("Plugin")
24  {
25  }
26 
28  {
29  MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
30  MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
31 
32  ResourceManager::getInstance().registerLoadXmlDelegate(mXmlPluginTagName) = newDelegate(this, &PluginManager::_load);
33 
34  MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
35  mIsInitialise = true;
36  }
37 
39  {
40  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
41  MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
42 
45 
46  MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
47  mIsInitialise = false;
48  }
49 
50  bool PluginManager::loadPlugin(const std::string& _file)
51  {
52 #ifdef EMSCRIPTEN
53  return false;
54 #endif
55  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
56 
57  // Load plugin library
58  DynLib* lib = DynLibManager::getInstance().load(_file);
59  if (!lib)
60  {
61  MYGUI_LOG(Error, "Plugin '" << _file << "' not found");
62  return false;
63  }
64 
65  // Call startup function
66  DLL_START_PLUGIN pFunc = reinterpret_cast<DLL_START_PLUGIN>(lib->getSymbol("dllStartPlugin"));
67  if (!pFunc)
68  {
69  MYGUI_LOG(Error, "Cannot find symbol 'dllStartPlugin' in library " << _file);
70  return false;
71  }
72 
73  // Store for later unload
74  mLibs[_file] = lib;
75 
76  // This must call installPlugin
77  pFunc();
78 
79  return true;
80  }
81 
82  void PluginManager::unloadPlugin(const std::string& _file)
83  {
84  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
85 
86  DynLibList::iterator it = mLibs.find(_file);
87  if (it != mLibs.end())
88  {
89  // Call plugin shutdown
90  DLL_STOP_PLUGIN pFunc = reinterpret_cast<DLL_STOP_PLUGIN>((*it).second->getSymbol("dllStopPlugin"));
91 
92  MYGUI_ASSERT(nullptr != pFunc, getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file);
93 
94  // this must call uninstallPlugin
95  pFunc();
96  // Unload library (destroyed by DynLibManager)
97  DynLibManager::getInstance().unload((*it).second);
98  mLibs.erase(it);
99  }
100  }
101 
102  void PluginManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
103  {
105  while (node.next())
106  {
107  if (node->getName() == "path")
108  {
109  std::string source;
110  if (node->findAttribute("source", source))
111  loadPlugin(source);
112  }
113  else if (node->getName() == "Plugin")
114  {
115  std::string source;
116 
117  xml::ElementEnumerator source_node = node->getElementEnumerator();
118  while (source_node.next("Source"))
119  {
120  std::string build = source_node->findAttribute("build");
121 #if MYGUI_DEBUG_MODE == 1
122  if (build == "Debug")
123  source = source_node->getContent();
124 #else
125  if (build != "Debug")
126  source = source_node->getContent();
127 #endif
128  }
129  if (!source.empty())
130  loadPlugin(source);
131  }
132  }
133  }
134 
136  {
137  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
138 
139  MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName());
140 
141  mPlugins.insert(_plugin);
142  _plugin->install();
143 
144  _plugin->initialize();
145 
146  MYGUI_LOG(Info, "Plugin successfully installed");
147  }
148 
150  {
151  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
152 
153  MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName());
154  PluginList::iterator it = mPlugins.find(_plugin);
155  if (it != mPlugins.end())
156  {
157  _plugin->shutdown();
158  _plugin->uninstall();
159  mPlugins.erase(it);
160  }
161  MYGUI_LOG(Info, "Plugin successfully uninstalled");
162  }
163 
165  {
166  while (!mLibs.empty())
167  unloadPlugin((*mLibs.begin()).first);
168  }
169 
170 } // namespace MyGUI
MyGUI::Singleton< ResourceManager >::getInstance
static ResourceManager & getInstance()
Definition: MyGUI_Singleton.h:44
MyGUI::PluginManager::PluginManager
PluginManager()
Definition: MyGUI_PluginManager.cpp:21
MyGUI::PluginManager::unloadPlugin
void unloadPlugin(const std::string &_file)
Unload plugin.
Definition: MyGUI_PluginManager.cpp:82
MyGUI::PluginManager::unloadAllPlugins
void unloadAllPlugins()
Unload all plugins.
Definition: MyGUI_PluginManager.cpp:164
MyGUI::PluginManager::initialise
void initialise()
Definition: MyGUI_PluginManager.cpp:27
MyGUI_DynLibManager.h
MyGUI::IPlugin::initialize
virtual void initialize()=0
MyGUI::ResourceManager::registerLoadXmlDelegate
LoadXmlDelegate & registerLoadXmlDelegate(const std::string &_key)
Definition: MyGUI_ResourceManager.cpp:119
MyGUI_ResourceManager.h
MyGUI::DynLibManager::unload
void unload(DynLib *library)
Unload library.
Definition: MyGUI_DynLibManager.cpp:68
MyGUI::ResourceManager::unregisterLoadXmlDelegate
void unregisterLoadXmlDelegate(const std::string &_key)
Definition: MyGUI_ResourceManager.cpp:126
MyGUI::xml::Element::getName
const std::string & getName() const
Definition: MyGUI_XmlDocument.cpp:332
MyGUI::Singleton< PluginManager >::getClassTypeName
static const char * getClassTypeName()
Definition: MyGUI_Singleton.h:55
MyGUI::PluginManager
Plugin manager. Load/unload and register plugins.
Definition: MyGUI_PluginManager.h:27
MyGUI::DynLib
Resource holding data about a dynamic library.
Definition: MyGUI_DynLib.h:35
MyGUI::PluginManager::loadPlugin
bool loadPlugin(const std::string &_file)
Load plugin.
Definition: MyGUI_PluginManager.cpp:50
MyGUI::IPlugin::install
virtual void install()=0
MyGUI::xml::Element
Definition: MyGUI_XmlDocument.h:159
MyGUI::xml::Element::findAttribute
bool findAttribute(const std::string &_name, std::string &_value)
Definition: MyGUI_XmlDocument.cpp:246
MyGUI::PluginManager::installPlugin
void installPlugin(IPlugin *_plugin)
Definition: MyGUI_PluginManager.cpp:135
MyGUI::newDelegate
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
Definition: MyGUI_Delegate.h:99
MyGUI_Precompiled.h
MyGUI::IPlugin::uninstall
virtual void uninstall()=0
MyGUI::DLL_STOP_PLUGIN
void(*)() DLL_STOP_PLUGIN
Definition: MyGUI_PluginManager.cpp:16
MyGUI::Version
Definition: MyGUI_Version.h:18
MyGUI::IPlugin
Base plugin class.
Definition: MyGUI_Plugin.h:19
MyGUI_PluginManager.h
MyGUI::IPlugin::shutdown
virtual void shutdown()=0
MyGUI::xml::ElementEnumerator
Definition: MyGUI_XmlDocument.h:115
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition: MyGUI_Diagnostic.h:34
MyGUI::DynLib::getSymbol
void * getSymbol(const std::string &strName) const noexcept
Definition: MyGUI_DynLib.cpp:85
MyGUI::DLL_START_PLUGIN
void(*)() DLL_START_PLUGIN
Definition: MyGUI_PluginManager.cpp:15
MyGUI::DynLibManager::load
DynLib * load(const std::string &fileName)
Load library.
Definition: MyGUI_DynLibManager.cpp:48
MYGUI_LOG
#define MYGUI_LOG(level, text)
Definition: MyGUI_Diagnostic.h:22
MyGUI::PluginManager::uninstallPlugin
void uninstallPlugin(IPlugin *_plugin)
Definition: MyGUI_PluginManager.cpp:149
MyGUI::IPlugin::getName
virtual const std::string & getName() const =0
MyGUI::PluginManager::shutdown
void shutdown()
Definition: MyGUI_PluginManager.cpp:38
MyGUI::Singleton
Definition: MyGUI_Singleton.h:22
MyGUI::xml::Element::getElementEnumerator
ElementEnumerator getElementEnumerator()
Definition: MyGUI_XmlDocument.cpp:352
MyGUI
Definition: MyGUI_ActionController.h:15
MyGUI::xml::ElementEnumerator::next
bool next()
Definition: MyGUI_XmlDocument.cpp:100