refactored plugin api; refactored callback library; added signals library
[xonotic/netradiant.git] / radiant / plugin.cpp
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
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.
11
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.
16
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
20 */
21
22 #include "plugin.h"
23
24 #include "debugging/debugging.h"
25
26 #include "qerplugin.h"
27 #include "ifilesystem.h"
28 #include "ishaders.h"
29 #include "ientity.h"
30 #include "ieclass.h"
31 #include "irender.h"
32 #include "iscenegraph.h"
33 #include "iselection.h"
34 #include "ifilter.h"
35 #include "iscriplib.h"
36 #include "igl.h"
37 #include "iundo.h"
38 #include "itextures.h"
39 #include "ireference.h"
40 #include "ifiletypes.h"
41 #include "preferencesystem.h"
42 #include "ibrush.h"
43 #include "ipatch.h"
44 #include "iimage.h"
45 #include "itoolbar.h"
46 #include "iplugin.h"
47 #include "imap.h"
48 #include "namespace.h"
49
50 #include "gtkutil/messagebox.h"
51 #include "gtkutil/filechooser.h"
52 #include "maplib.h"
53
54 #include "error.h"
55 #include "map.h"
56 #include "qe3.h"
57 #include "entityinspector.h"
58 #include "entitylist.h"
59 #include "points.h"
60 #include "gtkmisc.h"
61 #include "texwindow.h"
62 #include "mainframe.h"
63 #include "build.h"
64 #include "mru.h"
65 #include "multimon.h"
66 #include "surfacedialog.h"
67 #include "groupdialog.h"
68 #include "patchdialog.h"
69 #include "camwindow.h"
70 #include "watchbsp.h"
71 #include "xywindow.h"
72 #include "entity.h"
73 #include "select.h"
74 #include "preferences.h"
75 #include "autosave.h"
76 #include "plugintoolbar.h"
77 #include "findtexturedialog.h"
78 #include "nullmodel.h"
79 #include "grid.h"
80
81 #include "modulesystem/modulesmap.h"
82 #include "modulesystem/singletonmodule.h"
83
84 #include "generic/callback.h"
85
86 const char* GameDescription_getKeyValue(const char* key)
87 {
88   return g_pGameDescription->getKeyValue(key);
89 }
90
91 const char* GameDescription_getRequiredKeyValue(const char* key)
92 {
93   return g_pGameDescription->getRequiredKeyValue(key);
94 }
95
96 const char* getMapName()
97 {
98   return Map_Name(g_map);
99 }
100
101 scene::Node& getMapWorldEntity()
102 {
103   return Map_FindOrInsertWorldspawn(g_map);
104 }
105
106 VIEWTYPE XYWindow_getViewType()
107 {
108   return g_pParentWnd->GetXYWnd()->GetViewType();
109 }
110
111 Vector3 XYWindow_windowToWorld(const WindowVector& position)
112 {
113   Vector3 result(0, 0, 0);
114   g_pParentWnd->GetXYWnd()->XY_ToPoint(static_cast<int>(position.x()), static_cast<int>(position.y()), result);
115   return result;
116 }
117
118 const char* TextureBrowser_getSelectedShader()
119 {
120   return TextureBrowser_GetSelectedShader(GlobalTextureBrowser());
121 }
122
123 class RadiantCoreAPI
124 {
125   _QERFuncTable_1 m_radiantcore;
126 public:
127   typedef _QERFuncTable_1 Type;
128   STRING_CONSTANT(Name, "*");
129
130   RadiantCoreAPI()
131   {
132     m_radiantcore.getEnginePath = &EnginePath_get;
133     m_radiantcore.getAppPath = &AppPath_get;
134     m_radiantcore.getGameToolsPath = &GameToolsPath_get;
135     m_radiantcore.getSettingsPath = &SettingsPath_get;
136
137     m_radiantcore.getGameName = &gamename_get;
138     m_radiantcore.getGameMode = &gamemode_get;
139
140     m_radiantcore.getMapName = &getMapName;
141     m_radiantcore.getMapWorldEntity = getMapWorldEntity;
142     m_radiantcore.getGridSize = GetGridSize;
143
144     m_radiantcore.getGameDescriptionKeyValue = &GameDescription_getKeyValue;
145     m_radiantcore.getRequiredGameDescriptionKeyValue = &GameDescription_getRequiredKeyValue;
146
147     m_radiantcore.attachGameToolsPathObserver = Radiant_attachGameToolsPathObserver;
148     m_radiantcore.detachGameToolsPathObserver = Radiant_detachGameToolsPathObserver;
149     m_radiantcore.attachEnginePathObserver = Radiant_attachEnginePathObserver;
150     m_radiantcore.detachEnginePathObserver = Radiant_detachEnginePathObserver;
151     m_radiantcore.attachGameNameObserver = Radiant_attachGameNameObserver;
152     m_radiantcore.detachGameNameObserver = Radiant_detachGameNameObserver;
153     m_radiantcore.attachGameModeObserver = Radiant_attachGameModeObserver;
154     m_radiantcore.detachGameModeObserver = Radiant_detachGameModeObserver;
155
156     m_radiantcore.XYWindowMouseDown_connect = XYWindowMouseDown_connect;
157     m_radiantcore.XYWindowMouseDown_disconnect = XYWindowMouseDown_disconnect;
158     m_radiantcore.XYWindow_getViewType = XYWindow_getViewType;
159     m_radiantcore.XYWindow_windowToWorld = XYWindow_windowToWorld;
160     m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_getSelectedShader;
161
162     m_radiantcore.m_pfnMessageBox = &gtk_MessageBox;
163     m_radiantcore.m_pfnFileDialog = &file_dialog;
164     m_radiantcore.m_pfnColorDialog = &color_dialog;
165     m_radiantcore.m_pfnDirDialog = &dir_dialog;
166     m_radiantcore.m_pfnNewImage = &new_plugin_image;
167   }
168   _QERFuncTable_1* getTable()
169   {
170     return &m_radiantcore;
171   }
172 };
173
174 typedef SingletonModule<RadiantCoreAPI> RadiantCoreModule;
175 typedef Static<RadiantCoreModule> StaticRadiantCoreModule;
176 StaticRegisterModule staticRegisterRadiantCore(StaticRadiantCoreModule::instance());
177
178
179 class RadiantDependencies :
180   public GlobalRadiantModuleRef,
181   public GlobalFileSystemModuleRef,
182   public GlobalEntityModuleRef,
183   public GlobalShadersModuleRef,
184   public GlobalBrushModuleRef,
185   public GlobalSceneGraphModuleRef,
186   public GlobalShaderCacheModuleRef,
187   public GlobalFiletypesModuleRef,
188   public GlobalSelectionModuleRef,
189   public GlobalReferenceModuleRef,
190   public GlobalOpenGLModuleRef,
191   public GlobalEntityClassManagerModuleRef,
192   public GlobalUndoModuleRef,
193   public GlobalScripLibModuleRef,
194   public GlobalNamespaceModuleRef
195 {
196   ImageModulesRef m_image_modules;
197   MapModulesRef m_map_modules;
198   ToolbarModulesRef m_toolbar_modules;
199   PluginModulesRef m_plugin_modules;
200
201 public:
202   RadiantDependencies() :
203     GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities")),
204     GlobalShadersModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("shaders")),
205     GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")),
206     GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")),
207     m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes")),
208     m_map_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("maptypes")),
209     m_toolbar_modules("*"),
210     m_plugin_modules("*")
211   {
212   }
213
214   ImageModules& getImageModules()
215   {
216     return m_image_modules.get();
217   }
218   MapModules& getMapModules()
219   {
220     return m_map_modules.get();
221   }
222   ToolbarModules& getToolbarModules()
223   {
224     return m_toolbar_modules.get();
225   }
226   PluginModules& getPluginModules()
227   {
228     return m_plugin_modules.get();
229   }
230 };
231
232 class Radiant : public TypeSystemRef
233 {
234 public:
235   Radiant()
236   {
237     Preferences_Init();
238
239     GlobalFiletypes().addType("sound", "wav", filetype_t("PCM sound files", "*.wav"));
240
241     Selection_construct();
242     HomePaths_Construct();
243     VFS_Construct();
244     Grid_construct();
245     MultiMon_Construct();
246     MRU_Construct();
247     Pointfile_Construct();
248     GLWindow_Construct();
249     BuildMenu_Construct();
250     Map_Construct();
251     EntityList_Construct();
252     MainFrame_Construct();
253     GroupDialog_Construct();
254     SurfaceInspector_Construct();
255     PatchInspector_Construct();
256     CamWnd_Construct();
257     XYWindow_Construct();
258     BuildMonitor_Construct();
259     TextureBrowser_Construct();
260     Entity_Construct();
261     Autosave_Construct();
262     EntityInspector_construct();
263     FindTextureDialog_Construct();
264     NullModel_construct();
265     MapRoot_construct();
266
267     EnginePath_verify();
268     EnginePath_Realise();
269   }
270   ~Radiant()
271   {
272     EnginePath_Unrealise();
273
274     MapRoot_destroy();
275     NullModel_destroy();
276     FindTextureDialog_Destroy();
277     EntityInspector_destroy();
278     Autosave_Destroy();
279     Entity_Destroy();
280     TextureBrowser_Destroy();
281     BuildMonitor_Destroy();
282     XYWindow_Destroy();
283     CamWnd_Destroy();
284     PatchInspector_Destroy();
285     SurfaceInspector_Destroy();
286     GroupDialog_Destroy();
287     MainFrame_Destroy();
288     EntityList_Destroy();
289     Map_Destroy();
290     BuildMenu_Destroy();
291     GLWindow_Destroy();
292     Pointfile_Destroy();
293     MRU_Destroy();
294     MultiMon_Destroy();
295     Grid_destroy();
296     VFS_Destroy();
297     HomePaths_Destroy();
298     Selection_destroy();
299   }
300 };
301
302 namespace
303 {
304   bool g_RadiantInitialised = false;
305   RadiantDependencies* g_RadiantDependencies;
306   Radiant* g_Radiant;
307 }
308
309
310
311 bool Radiant_Construct(ModuleServer& server)
312 {
313   GlobalModuleServer::instance().set(server);
314   StaticModuleRegistryList().instance().registerModules();
315
316   g_RadiantDependencies = new RadiantDependencies();
317
318   g_RadiantInitialised = !server.getError();
319
320   if(g_RadiantInitialised)
321   {
322     g_Radiant = new Radiant;
323   }
324
325   return g_RadiantInitialised;
326 }
327 void Radiant_Destroy()
328 {
329   if(g_RadiantInitialised)
330   {
331     delete g_Radiant;
332   }
333
334   delete g_RadiantDependencies;
335 }
336
337 ImageModules& Radiant_getImageModules()
338 {
339   return g_RadiantDependencies->getImageModules();
340 }
341 MapModules& Radiant_getMapModules()
342 {
343   return g_RadiantDependencies->getMapModules();
344 }
345 ToolbarModules& Radiant_getToolbarModules()
346 {
347   return g_RadiantDependencies->getToolbarModules();
348 }
349 PluginModules& Radiant_getPluginModules()
350 {
351   return g_RadiantDependencies->getPluginModules();
352 }
353
354