MyGUI 3.4.3
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"
11
12namespace MyGUI
13{
15
16 using DLL_START_PLUGIN = void (*)();
17 using DLL_STOP_PLUGIN = void (*)();
18
20 mXmlPluginTagName("Plugin"),
21 mSingletonHolder(this)
22 {
23 }
24
26 {
27 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
28 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
29
31 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(std::string_view _file)
50 {
51#ifdef EMSCRIPTEN
52 return false;
53#endif
54 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
55
56 // Load plugin library
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[lib->getName()] = lib;
74
75 // This must call installPlugin
76 pFunc();
77
78 return true;
79 }
80
81 void PluginManager::unloadPlugin(std::string_view _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
92 nullptr != pFunc,
93 getClassTypeName() << "Cannot find symbol 'dllStopPlugin' in library " << _file);
94
95 // this must call uninstallPlugin
96 pFunc();
97 // Unload library (destroyed by DynLibManager)
98 DynLibManager::getInstance().unload((*it).second);
99 mLibs.erase(it);
100 }
101 }
102
103 void PluginManager::_load(xml::ElementPtr _node, std::string_view /*_file*/, Version _version)
104 {
106 while (node.next())
107 {
108 if (node->getName() == "path")
109 {
110 std::string source;
111 if (node->findAttribute("source", source))
112 loadPlugin(source);
113 }
114 else if (node->getName() == "Plugin")
115 {
116 std::string_view source;
117
118 xml::ElementEnumerator source_node = node->getElementEnumerator();
119 while (source_node.next("Source"))
120 {
121 std::string_view build = source_node->findAttribute("build");
122#if MYGUI_DEBUG_MODE == 1
123 if (build == "Debug")
124 source = source_node->getContent();
125#else
126 if (build != "Debug")
127 source = source_node->getContent();
128#endif
129 }
130 if (!source.empty())
131 loadPlugin(source);
132 }
133 }
134 }
135
137 {
138 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
139
140 MYGUI_LOG(Info, "Installing plugin: " << _plugin->getName());
141
142 mPlugins.insert(_plugin);
143 _plugin->install();
144
145 _plugin->initialize();
146
147 MYGUI_LOG(Info, "Plugin successfully installed");
148 }
149
151 {
152 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " used but not initialised");
153
154 MYGUI_LOG(Info, "Uninstalling plugin: " << _plugin->getName());
155 PluginList::iterator it = mPlugins.find(_plugin);
156 if (it != mPlugins.end())
157 {
158 _plugin->shutdown();
159 _plugin->uninstall();
160 mPlugins.erase(it);
161 }
162 MYGUI_LOG(Info, "Plugin successfully uninstalled");
163 }
164
166 {
167 while (!mLibs.empty())
168 unloadPlugin((*mLibs.begin()).first);
169 }
170
171} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
#define MYGUI_LOG(level, text)
#define MYGUI_SINGLETON_DEFINITION(ClassName)
Resource holding data about a dynamic library.
void * getSymbol(const char *strName) const noexcept
const std::string & getName() const
Get the name of the library.
void unload(DynLib *library)
Unload library.
DynLib * load(std::string_view fileName)
Load library.
static DynLibManager & getInstance()
Base plugin class.
virtual void install()=0
virtual void initialize()=0
virtual const std::string & getName() const =0
virtual void shutdown()=0
virtual void uninstall()=0
Plugin manager. Load/unload and register plugins.
void installPlugin(IPlugin *_plugin)
void unloadPlugin(std::string_view _file)
Unload plugin.
void uninstallPlugin(IPlugin *_plugin)
void unloadAllPlugins()
Unload all plugins.
bool loadPlugin(std::string_view _file)
Load plugin.
static std::string_view getClassTypeName()
void unregisterLoadXmlDelegate(std::string_view _key)
LoadXmlDelegate & registerLoadXmlDelegate(std::string_view _key)
static ResourceManager & getInstance()
bool findAttribute(std::string_view _name, std::string &_value)
ElementEnumerator getElementEnumerator()
const std::string & getName() const
void(*)() DLL_STOP_PLUGIN
void(*)() DLL_START_PLUGIN
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))