MyGUI  3.2.0
MyGUI_PluginManager.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_PluginManager.h"
24 #include "MyGUI_DynLibManager.h"
25 #include "MyGUI_ResourceManager.h"
26 
27 namespace MyGUI
28 {
29  typedef void (*DLL_START_PLUGIN)(void);
30  typedef void (*DLL_STOP_PLUGIN)(void);
31 
32  const std::string XML_TYPE("Plugin");
33 
35  template <> const char* Singleton<PluginManager>::mClassTypeName("PluginManager");
36 
38  mIsInitialise(false)
39  {
40  }
41 
43  {
44  MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
45  MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
46 
48 
49  MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
50  mIsInitialise = true;
51  }
52 
54  {
55  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
56  MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
57 
60 
61  MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
62  mIsInitialise = false;
63  }
64 
65  bool PluginManager::loadPlugin(const std::string& _file)
66  {
67  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
68 
69  // Load plugin library
70  DynLib* lib = DynLibManager::getInstance().load(_file);
71  if (!lib)
72  {
73  MYGUI_LOG(Error, "Plugin '" << _file << "' not found");
74  return false;
75  }
76 
77  // Call startup function
78  DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin");
79  if (!pFunc)
80  {
81  MYGUI_LOG(Error, "Cannot find symbol 'dllStartPlugin' in library " << _file);
82  return false;
83  }
84 
85  // Store for later unload
86  mLibs[_file] = lib;
87 
88  // This must call installPlugin
89  pFunc();
90 
91  return true;
92  }
93 
94  void PluginManager::unloadPlugin(const std::string& _file)
95  {
96  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
97 
98  DynLibList::iterator it = mLibs.find(_file);
99  if (it != mLibs.end())
100  {
101  // Call plugin shutdown
102  DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*it).second->getSymbol("dllStopPlugin");
103 
104  MYGUI_ASSERT(nullptr != pFunc, getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file);
105 
106  // this must call uninstallPlugin
107  pFunc();
108  // Unload library (destroyed by DynLibManager)
109  DynLibManager::getInstance().unload((*it).second);
110  mLibs.erase(it);
111  }
112  }
113 
114  void PluginManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
115  {
117  while (node.next())
118  {
119  if (node->getName() == "path")
120  {
121  std::string source;
122  if (node->findAttribute("source", source))
123  loadPlugin(source);
124  }
125  else if (node->getName() == "Plugin")
126  {
127  std::string source;
128 
129  xml::ElementEnumerator source_node = node->getElementEnumerator();
130  while (source_node.next("Source"))
131  {
132  std::string build = source_node->findAttribute("build");
133 #if MYGUI_DEBUG_MODE == 1
134  if (build == "Debug")
135  source = source_node->getContent();
136 #else
137  if (build != "Debug")
138  source = source_node->getContent();
139 #endif
140  }
141  if (!source.empty())
142  loadPlugin(source);
143  }
144  }
145  }
146 
148  {
149  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
150 
151  MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName());
152 
153  mPlugins.insert(_plugin);
154  _plugin->install();
155 
156  _plugin->initialize();
157 
158  MYGUI_LOG(Info, "Plugin successfully installed");
159  }
160 
162  {
163  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
164 
165  MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName());
166  PluginList::iterator it = mPlugins.find(_plugin);
167  if (it != mPlugins.end())
168  {
169  _plugin->shutdown();
170  _plugin->uninstall();
171  mPlugins.erase(it);
172  }
173  MYGUI_LOG(Info, "Plugin successfully uninstalled");
174  }
175 
177  {
178  while (!mLibs.empty())
179  unloadPlugin((*mLibs.begin()).first);
180  }
181 
182 } // namespace MyGUI