2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "debugging/debugging.h"
31 #include "modulesystem.h"
33 class RadiantModuleServer : public ModuleServer
35 typedef std::pair<CopiedString, int> ModuleType;
36 typedef std::pair<ModuleType, CopiedString> ModuleKey;
37 typedef std::map<ModuleKey, Module*> Modules_;
42 RadiantModuleServer() : m_error(false)
46 void setError(bool error)
55 TextOutputStream& getOutputStream()
57 return globalOutputStream();
59 TextOutputStream& getErrorStream()
61 return globalErrorStream();
63 DebugMessageHandler& getDebugMessageHandler()
65 return globalDebugMessageHandler();
68 void registerModule(const char* type, int version, const char* name, Module& module)
70 ASSERT_NOTNULL(&module);
71 if(!m_modules.insert(Modules_::value_type(ModuleKey(ModuleType(type, version), name), &module)).second)
73 globalErrorStream() << "module already registered: type=" << makeQuoted(type) << " name=" << makeQuoted(name) << "\n";
77 globalOutputStream() << "Module Registered: type=" << makeQuoted(type) << " version=" << makeQuoted(version) << " name=" << makeQuoted(name) << "\n";
81 Module* findModule(const char* type, int version, const char* name) const
83 Modules_::const_iterator i = m_modules.find(ModuleKey(ModuleType(type, version), name));
84 if(i != m_modules.end())
91 void foreachModule(const char* type, int version, const Visitor& visitor)
93 for(Modules_::const_iterator i = m_modules.begin(); i != m_modules.end(); ++i)
95 if(string_equal((*i).first.first.first.c_str(), type))
97 visitor.visit((*i).first.second.c_str(), *(*i).second);
108 #define FORMAT_BUFSIZE 2048
109 const char* FormatGetLastError()
111 static char buf[FORMAT_BUFSIZE];
113 FORMAT_MESSAGE_FROM_SYSTEM |
114 FORMAT_MESSAGE_IGNORE_INSERTS,
117 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
129 typedef int (__stdcall* FunctionPointer)();
131 DynamicLibrary(const char* filename)
133 m_library = LoadLibrary(filename);
136 globalErrorStream() << "LoadLibrary failed: '" << filename << "'\n";
137 globalErrorStream() << "GetLastError: " << FormatGetLastError();
144 FreeLibrary(m_library);
149 return m_library == 0;
151 FunctionPointer findSymbol(const char* symbol)
153 FunctionPointer address = GetProcAddress(m_library, symbol);
156 globalErrorStream() << "GetProcAddress failed: '" << symbol << "'\n";
157 globalErrorStream() << "GetLastError: " << FormatGetLastError();
171 typedef int (* FunctionPointer)();
173 DynamicLibrary(const char* filename)
175 m_library = dlopen(filename, RTLD_NOW);
184 return m_library == 0;
186 FunctionPointer findSymbol(const char* symbol)
188 FunctionPointer p = (FunctionPointer)dlsym(m_library, symbol);
191 const char* error = reinterpret_cast<const char*>(dlerror());
194 globalErrorStream() << error;
202 #error "unsupported platform"
205 class DynamicLibraryModule
207 typedef void (RADIANT_DLLIMPORT* RegisterModulesFunc)(ModuleServer& server);
208 DynamicLibrary m_library;
209 RegisterModulesFunc m_registerModule;
211 DynamicLibraryModule(const char* filename)
212 : m_library(filename), m_registerModule(0)
214 if(!m_library.failed())
216 m_registerModule = reinterpret_cast<RegisterModulesFunc>(m_library.findSymbol("Radiant_RegisterModules"));
218 if(!m_registerModule)
219 m_registerModule = reinterpret_cast<RegisterModulesFunc>(m_library.findSymbol("Radiant_RegisterModules@4"));
225 return m_registerModule == 0;
227 void registerModules(ModuleServer& server)
229 m_registerModule(server);
236 typedef std::vector<DynamicLibraryModule*> libraries_t;
237 libraries_t m_libraries;
244 void registerLibrary(const char* filename, ModuleServer& server)
246 DynamicLibraryModule* library = new DynamicLibraryModule(filename);
248 if(library->failed())
254 m_libraries.push_back(library);
255 library->registerModules(server);
260 for(libraries_t::iterator i = m_libraries.begin(); i != m_libraries.end(); ++i)
272 Libraries g_libraries;
273 RadiantModuleServer g_server;
275 ModuleServer& GlobalModuleServer_get()
280 void GlobalModuleServer_loadModule(const char* filename)
282 g_libraries.registerLibrary(filename, g_server);
285 void GlobalModuleServer_Initialise()
289 void GlobalModuleServer_Shutdown()