1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
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 // PlugInManager.cpp: implementation of the CPlugInManager class.
23 //
24 //////////////////////////////////////////////////////////////////////
25 
26 #include "pluginmanager.h"
27 
28 #include "modulesystem.h"
29 #include "qerplugin.h"
30 #include "iplugin.h"
31 
32 #include "math/vector.h"
33 #include "string/string.h"
34 
35 #include "error.h"
36 #include "select.h"
37 #include "plugin.h"
38 
39 #include "modulesystem.h"
40 
41 #include <list>
42 
43 /* plugin manager --------------------------------------- */
44 class CPluginSlot : public IPlugIn
45 {
46 CopiedString m_menu_name;
47 const _QERPluginTable *mpTable;
48 std::list<CopiedString> m_CommandStrings;
49 std::list<CopiedString> m_CommandTitleStrings;
50 std::list<std::size_t> m_CommandIDs;
51 
52 public:
53 /*!
54    build directly from a SYN_PROVIDE interface
55  */
56 CPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table );
57 /*!
58    dispatching a command by name to the plugin
59  */
60 void Dispatch( const char *p );
61 
62 // IPlugIn ------------------------------------------------------------
63 const char* getMenuName();
64 std::size_t getCommandCount();
65 const char* getCommand( std::size_t n );
66 const char* getCommandTitle( std::size_t n );
67 void addMenuID( std::size_t n );
68 bool ownsCommandID( std::size_t n );
69 
70 };
71 
CPluginSlot(GtkWidget * main_window,const char * name,const _QERPluginTable & table)72 CPluginSlot::CPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table ){
73 	mpTable = &table;
74 	m_menu_name = name;
75 
76 	const char* commands = mpTable->m_pfnQERPlug_GetCommandList();
77 	const char* titles = mpTable->m_pfnQERPlug_GetCommandTitleList();
78 
79 	StringTokeniser commandTokeniser( commands, ",;" );
80 	StringTokeniser titleTokeniser( titles, ",;" );
81 
82 	const char* cmdToken = commandTokeniser.getToken();
83 	const char *titleToken = titleTokeniser.getToken();
84 	while ( !string_empty( cmdToken ) )
85 	{
86 		if ( string_empty( titleToken ) ) {
87 			m_CommandStrings.push_back( cmdToken );
88 			m_CommandTitleStrings.push_back( cmdToken );
89 			cmdToken = commandTokeniser.getToken();
90 			titleToken = "";
91 		}
92 		else
93 		{
94 			m_CommandStrings.push_back( cmdToken );
95 			m_CommandTitleStrings.push_back( titleToken );
96 			cmdToken = commandTokeniser.getToken();
97 			titleToken = titleTokeniser.getToken();
98 		}
99 	}
100 	mpTable->m_pfnQERPlug_Init( 0, (void*)main_window );
101 }
102 
getMenuName()103 const char* CPluginSlot::getMenuName(){
104 	return m_menu_name.c_str();
105 }
106 
getCommandCount()107 std::size_t CPluginSlot::getCommandCount(){
108 	return m_CommandStrings.size();
109 }
110 
getCommand(std::size_t n)111 const char* CPluginSlot::getCommand( std::size_t n ){
112 	std::list<CopiedString>::iterator i = m_CommandStrings.begin();
113 	while ( n-- != 0 )
114 		++i;
115 	return ( *i ).c_str();
116 }
117 
getCommandTitle(std::size_t n)118 const char* CPluginSlot::getCommandTitle( std::size_t n ){
119 	std::list<CopiedString>::iterator i = m_CommandTitleStrings.begin();
120 	while ( n-- != 0 )
121 		++i;
122 	return ( *i ).c_str();
123 }
124 
addMenuID(std::size_t n)125 void CPluginSlot::addMenuID( std::size_t n ){
126 	m_CommandIDs.push_back( n );
127 }
128 
ownsCommandID(std::size_t n)129 bool CPluginSlot::ownsCommandID( std::size_t n ){
130 	for ( std::list<std::size_t>::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i )
131 	{
132 		if ( *i == n ) {
133 			return true;
134 		}
135 	}
136 	return false;
137 }
138 
Dispatch(const char * p)139 void CPluginSlot::Dispatch( const char *p ){
140 	Vector3 vMin, vMax;
141 	Select_GetBounds( vMin, vMax );
142 	mpTable->m_pfnQERPlug_Dispatch( p, reinterpret_cast<float*>( &vMin ), reinterpret_cast<float*>( &vMax ), true ); //QE_SingleBrush(true));
143 }
144 
145 
146 class CPluginSlots
147 {
148 std::list<CPluginSlot *> mSlots;
149 public:
150 virtual ~CPluginSlots();
151 
AddPluginSlot(GtkWidget * main_window,const char * name,const _QERPluginTable & table)152 void AddPluginSlot( GtkWidget* main_window, const char* name, const _QERPluginTable& table ){
153 	mSlots.push_back( new CPluginSlot( main_window, name, table ) );
154 }
155 
156 void PopulateMenu( PluginsVisitor& menu );
157 bool Dispatch( std::size_t n, const char* p );
158 };
159 
~CPluginSlots()160 CPluginSlots::~CPluginSlots(){
161 	std::list<CPluginSlot *>::iterator iSlot;
162 	for ( iSlot = mSlots.begin(); iSlot != mSlots.end(); ++iSlot )
163 	{
164 		delete *iSlot;
165 		*iSlot = 0;
166 	}
167 }
168 
PopulateMenu(PluginsVisitor & menu)169 void CPluginSlots::PopulateMenu( PluginsVisitor& menu ){
170 	std::list<CPluginSlot *>::iterator iPlug;
171 	for ( iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug )
172 	{
173 		menu.visit( *( *iPlug ) );
174 	}
175 }
176 
Dispatch(std::size_t n,const char * p)177 bool CPluginSlots::Dispatch( std::size_t n, const char* p ){
178 	std::list<CPluginSlot *>::iterator iPlug;
179 	for ( iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug )
180 	{
181 		CPluginSlot *pPlug = *iPlug;
182 		if ( pPlug->ownsCommandID( n ) ) {
183 			pPlug->Dispatch( p );
184 			return true;
185 		}
186 	}
187 	return false;
188 }
189 
190 CPluginSlots g_plugin_slots;
191 
192 
FillPluginSlots(CPluginSlots & slots,GtkWidget * main_window)193 void FillPluginSlots( CPluginSlots& slots, GtkWidget* main_window ){
194 	class AddPluginVisitor : public PluginModules::Visitor
195 	{
196 	CPluginSlots& m_slots;
197 	GtkWidget* m_main_window;
198 public:
199 	AddPluginVisitor( CPluginSlots& slots, GtkWidget* main_window )
200 		: m_slots( slots ), m_main_window( main_window ){
201 	}
202 	void visit( const char* name, const _QERPluginTable& table ) const {
203 		m_slots.AddPluginSlot( m_main_window, name, table );
204 	}
205 	} visitor( slots, main_window );
206 
207 	Radiant_getPluginModules().foreachModule( visitor );
208 }
209 
210 
211 #include "pluginmanager.h"
212 
213 CPlugInManager g_PlugInMgr;
214 
GetPlugInMgr()215 CPlugInManager& GetPlugInMgr(){
216 	return g_PlugInMgr;
217 }
218 
Dispatch(std::size_t n,const char * p)219 void CPlugInManager::Dispatch( std::size_t n, const char * p ){
220 	g_plugin_slots.Dispatch( n, p );
221 }
222 
Init(GtkWidget * main_window)223 void CPlugInManager::Init( GtkWidget* main_window ){
224 	FillPluginSlots( g_plugin_slots, main_window );
225 }
226 
constructMenu(PluginsVisitor & menu)227 void CPlugInManager::constructMenu( PluginsVisitor& menu ){
228 	g_plugin_slots.PopulateMenu( menu );
229 }
230 
Shutdown()231 void CPlugInManager::Shutdown(){
232 }
233