MyGUI  3.2.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 {
14 
15  typedef void (*DLL_START_PLUGIN)(void);
16  typedef void (*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  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
53 
54  // Load plugin library
55  DynLib* lib = DynLibManager::getInstance().load(_file);
56  if (!lib)
57  {
58  MYGUI_LOG(Error, "Plugin '" << _file << "' not found");
59  return false;
60  }
61 
62  // Call startup function
63  DLL_START_PLUGIN pFunc = reinterpret_cast<DLL_START_PLUGIN>(lib->getSymbol("dllStartPlugin"));
64  if (!pFunc)
65  {
66  MYGUI_LOG(Error, "Cannot find symbol 'dllStartPlugin' in library " << _file);
67  return false;
68  }
69 
70  // Store for later unload
71  mLibs[_file] = lib;
72 
73  // This must call installPlugin
74  pFunc();
75 
76  return true;
77  }
78 
79  void PluginManager::unloadPlugin(const std::string& _file)
80  {
81  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
82 
83  DynLibList::iterator it = mLibs.find(_file);
84  if (it != mLibs.end())
85  {
86  // Call plugin shutdown
87  DLL_STOP_PLUGIN pFunc = reinterpret_cast<DLL_STOP_PLUGIN>((*it).second->getSymbol("dllStopPlugin"));
88 
89  MYGUI_ASSERT(nullptr != pFunc, getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file);
90 
91  // this must call uninstallPlugin
92  pFunc();
93  // Unload library (destroyed by DynLibManager)
94  DynLibManager::getInstance().unload((*it).second);
95  mLibs.erase(it);
96  }
97  }
98 
99  void PluginManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
100  {
102  while (node.next())
103  {
104  if (node->getName() == "path")
105  {
106  std::string source;
107  if (node->findAttribute("source", source))
108  loadPlugin(source);
109  }
110  else if (node->getName() == "Plugin")
111  {
112  std::string source;
113 
114  xml::ElementEnumerator source_node = node->getElementEnumerator();
115  while (source_node.next("Source"))
116  {
117  std::string build = source_node->findAttribute("build");
118 #if MYGUI_DEBUG_MODE == 1
119  if (build == "Debug")
120  source = source_node->getContent();
121 #else
122  if (build != "Debug")
123  source = source_node->getContent();
124 #endif
125  }
126  if (!source.empty())
127  loadPlugin(source);
128  }
129  }
130  }
131 
133  {
134  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
135 
136  MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName());
137 
138  mPlugins.insert(_plugin);
139  _plugin->install();
140 
141  _plugin->initialize();
142 
143  MYGUI_LOG(Info, "Plugin successfully installed");
144  }
145 
147  {
148  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
149 
150  MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName());
151  PluginList::iterator it = mPlugins.find(_plugin);
152  if (it != mPlugins.end())
153  {
154  _plugin->shutdown();
155  _plugin->uninstall();
156  mPlugins.erase(it);
157  }
158  MYGUI_LOG(Info, "Plugin successfully uninstalled");
159  }
160 
162  {
163  while (!mLibs.empty())
164  unloadPlugin((*mLibs.begin()).first);
165  }
166 
167 } // namespace MyGUI