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