1 /***********************************************************************
2 	created:	22/2/2004
3 	author:		Paul D Turner
4 
5 	purpose:	Defines interface for WindowFactoryManager class
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifndef _CEGUIWindowFactoryManager_h_
30 #define _CEGUIWindowFactoryManager_h_
31 
32 #include "CEGUI/Base.h"
33 #include "CEGUI/String.h"
34 #include "CEGUI/Singleton.h"
35 #include "CEGUI/Logger.h"
36 #include "CEGUI/IteratorBase.h"
37 #include "CEGUI/WindowFactory.h"
38 #include "CEGUI/TplWindowFactory.h"
39 #include "CEGUI/Exceptions.h"
40 #include <map>
41 #include <vector>
42 
43 #if defined(_MSC_VER)
44 #	pragma warning(push)
45 #	pragma warning(disable : 4275)
46 #	pragma warning(disable : 4251)
47 #endif
48 
49 
50 // Start of CEGUI namespace section
51 namespace CEGUI
52 {
53 /*!
54 \brief
55 	Class that manages WindowFactory objects
56 
57 \todo
58     I think we could clean up the mapping stuff a bit. Possibly make it more generic now
59     with the window renderers and all.
60 */
61 class CEGUIEXPORT WindowFactoryManager :
62     public Singleton<WindowFactoryManager>,
63     public AllocatedObject<WindowFactoryManager>
64 {
65 public:
66     /*!
67     \brief
68         struct used to hold mapping information required to create a falagard based window.
69     */
70     struct CEGUIEXPORT FalagardWindowMapping
71     {
72         String  d_windowType;
73         String  d_lookName;
74         String  d_baseType;
75         String  d_rendererType;
76         String  d_effectName;
77     };
78 
79     /*!
80     \brief
81         Class used to track active alias targets for Window factory types.
82     */
83 	class CEGUIEXPORT AliasTargetStack
84 	{
85 	public:
86 		/*!
87 		\brief
88 			Constructor for WindowAliasTargetStack objects
89 		*/
AliasTargetStack(void)90 		AliasTargetStack(void) {}
91 
92 
93 		/*!
94 		\brief
95 			Destructor for WindowAliasTargetStack objects
96 		*/
~AliasTargetStack(void)97 		~AliasTargetStack(void) {}
98 
99 
100 		/*!
101 		\brief
102 			Return a String holding the current target type for this stack
103 
104 		\return
105 			reference to a String object holding the currently active target type name for this stack.
106 		*/
107 		const String&	getActiveTarget(void) const;
108 
109 		/*!
110 		\brief
111 			Return the number of stacked target types in the stack
112 
113 		\return
114 			number of target types stacked for this alias.
115 		*/
116 		uint	getStackedTargetCount(void) const;
117 
118 
119 	private:
120 		friend class WindowFactoryManager;
121 
122 		typedef std::vector<String
123             CEGUI_VECTOR_ALLOC(String)> TargetTypeStack; //!< Type used to implement stack of target type names.
124 
125 		TargetTypeStack	d_targetStack; //!< Container holding the target types.
126 	};
127 
128 
129 	/*************************************************************************
130 		Construction and Destruction
131 	*************************************************************************/
132 	/*!
133 	\brief
134 		Constructs a new WindowFactoryManager object.
135 	*/
136 	WindowFactoryManager(void);
137 
138 
139 	/*!
140 	\brief
141 		Destructor for WindowFactoryManager objects
142 	*/
~WindowFactoryManager(void)143 	~WindowFactoryManager(void)
144 	{
145 		Logger::getSingleton().logEvent("CEGUI::WindowFactoryManager singleton destroyed");
146 	}
147 
148 
149 	/*************************************************************************
150 		Public Interface
151 	*************************************************************************/
152 	/*!
153 	\brief
154 		Adds a new WindowFactory to the list of registered factories.
155 
156 	\param factory
157 		Pointer to the WindowFactory to be added to the WindowManager.
158 
159 	\return
160 		Nothing
161 
162 	\exception NullObjectException		\a factory was null.
163 	\exception AlreadyExistsException	\a factory provided a Window type name which is in use by another registered WindowFactory.
164 	*/
165 	void	addFactory(WindowFactory* factory);
166 
167     /*!
168     \brief
169         Creates a WindowFactory of the type \a T and adds it to the system for
170         use.  The created WindowFactory will automatically be deleted when the
171         factory is removed from the system (either directly or at system
172         deletion time).
173 
174     \tparam T
175         Specifies the type of WindowFactory subclass to add a factory for.
176 
177     \return
178         Nothing
179     */
180     template <typename T>
181     static void addFactory();
182 
183     /*!
184     \brief
185         Internally creates a factory suitable for creating Window objects
186         of the given type and adds it to the system.
187 
188     \note
189         The internally created factory is owned and managed by CEGUI,
190         and will be automatically deleted when the window type is removed from
191         the system - either directly by calling
192         WindowFactoryManager::removeFactory or at system shut down.
193 
194     \tparam T
195         Specifies the type of Window to add a factory for.
196     */
197     template <typename T>
198     static void addWindowType();
199 
200 	/*!
201 	\brief
202 		Removes a WindowFactory from the list of registered factories.
203 
204 	\note
205 		The WindowFactory object is not destroyed (since it was created externally), instead it is just removed from the list.
206 
207 	\param name
208 		String which holds the name (technically, Window type name) of the WindowFactory to be removed.  If \a name is not
209 		in the list, no error occurs (nothing happens).
210 
211 	\return
212 		Nothing
213 	*/
214 	void	removeFactory(const String& name);
215 
216 
217 	/*!
218 	\brief
219 		Removes a WindowFactory from the list of registered factories.
220 
221 	\note
222 		The WindowFactory object is not destroyed (since it was created externally), instead it is just removed from the list.
223 
224 	\param factory
225 		Pointer to the factory object to be removed.  If \a factory is null, or if no such WindowFactory is in the list, no
226 		error occurs (nothing happens).
227 
228 	\return
229 		Nothing
230 	*/
231 	void	removeFactory(WindowFactory* factory);
232 
233 
234 	/*!
235 	\brief
236 		Remove all WindowFactory objects from the list.
237 
238 	\return
239 		Nothing
240 	*/
241     void removeAllFactories(void);
242 
243 
244 	/*!
245 	\brief
246 		Return a pointer to the specified WindowFactory object.
247 
248 	\param type
249 		String holding the Window object type to return the WindowFactory for.
250 
251 	\return
252 		Pointer to the WindowFactory object that creates Windows of the type \a type.
253 
254 	\exception UnknownObjectException	No WindowFactory object for Window objects of type \a type was found.
255 	*/
256 	WindowFactory*	getFactory(const String& type) const;
257 
258 
259     /*!
260     \brief
261         Checks the list of registered WindowFactory objects, aliases, and
262         falagard mapped types for one which can create Window objects of the
263         specified type.
264 
265     \param name
266         String containing the Window type name to check for.
267 
268     \return
269         - true if a WindowFactory, alias, or falagard mapping for Window objects
270           of type \a name is registered.
271         - false if the system knows nothing about windows of type \a name.
272     */
273     bool	isFactoryPresent(const String& name) const;
274 
275 
276 	/*!
277 	\brief
278 		Adds an alias for a current window type.
279 
280 		This method allows you to create an alias for a specified window type.  This means that you can then use
281 		either name as the type parameter when creating a window.
282 
283 	\note
284 		You need to be careful using this system.  Creating an alias using a name that already exists will replace the previous
285 		mapping for that alias.  Each alias name maintains a stack, which means that it is possible to remove an alias and have the
286 		previous alias restored.  The windows created via an alias use the real type, so removing an alias after window creation is always
287 		safe (i.e. it is not the same as removing a real factory, which would cause an exception when trying to destroy a window with a missing
288 		factory).
289 
290 	\param aliasName
291 		String object holding the alias name.  That is the name that \a targetType will also be known as from no on.
292 
293 	\param targetType
294 		String object holding the type window type name that is to be aliased.  This type must already exist.
295 
296 	\return
297 		Nothing.
298 
299 	\exception UnknownObjectException	thrown if \a targetType is not known within the system.
300 	*/
301 	void	addWindowTypeAlias(const String& aliasName, const String& targetType);
302 
303 
304 	/*!
305 	\brief
306 		Remove the specified alias mapping.  If the alias mapping does not exist, nothing happens.
307 
308 	\note
309 		You are required to supply both the alias and target names because there may exist more than one entry for a given
310 		alias - therefore you are required to be explicit about which alias is to be removed.
311 
312 	\param aliasName
313 		String object holding the alias name.
314 
315 	\param targetType
316 		String object holding the type window type name that was aliased.
317 
318 	\return
319 		Nothing.
320 	*/
321 	void	removeWindowTypeAlias(const String& aliasName, const String& targetType);
322 
323 	/*!
324 	\brief
325 		Remove all registered window type alias mappings.
326 	*/
327 	void removeAllWindowTypeAliases();
328 
329     /*!
330     \brief
331         Add a mapping for a falagard based window.
332 
333         This function creates maps a target window type and target 'look' name onto a registered window type, thus allowing
334         the ususal window creation interface to be used to create windows that require extra information to full initialise
335         themselves.
336     \note
337         These mappings support 'late binding' to the target window type, as such the type indicated by \a targetType need not
338         exist in the system until attempting to create a Window using the type.
339     \par
340         Also note that creating a mapping for an existing type will replace any previous mapping for that same type.
341 
342     \param newType
343         The type name that will be used to create windows using the target type and look.
344 
345     \param targetType
346         The base window type.
347 
348     \param lookName
349         The name of the 'look' that will be used by windows of this type.
350 
351     \param renderer
352         The type of window renderer to assign for windows of this type.
353 
354     \param effectName
355         The identifier of the RenderEffect to attempt to set up for windows of this type.
356 
357     \return
358         Nothing.
359     */
360     void addFalagardWindowMapping(const String& newType,
361                                   const String& targetType,
362                                   const String& lookName,
363                                   const String& renderer,
364                                   const String& effectName = String(""));
365 
366     /*!
367     \brief
368         Remove the specified falagard type mapping if it exists.
369 
370     \return
371         Nothing.
372     */
373     void removeFalagardWindowMapping(const String& type);
374 
375     /*!
376 	\brief
377 		Remove all registered falagard type mappings
378 	*/
379     void removeAllFalagardWindowMappings();
380 
381     /*!
382     \brief
383         Return whether the given type is a falagard mapped type.
384 
385     \param type
386         Name of a window type.
387 
388     \return
389         - true if the requested type is a Falagard mapped window type.
390         - false if the requested type is a normal WindowFactory (or alias), or if the type does not exist.
391     */
392     bool isFalagardMappedType(const String& type) const;
393 
394     /*!
395     \brief
396         Return the name of the LookN'Feel assigned to the specified window mapping.
397 
398     \param type
399         Name of a window type.  The window type referenced should be a falagard mapped type.
400 
401     \return
402         String object holding the name of the look mapped for the requested type.
403 
404     \exception InvalidRequestException thrown if \a type is not a falagard mapping type (or maybe the type didn't exist).
405     */
406     const String& getMappedLookForType(const String& type) const;
407 
408     /*!
409     \brief
410         Return the name of the WindowRenderer assigned to the specified window mapping.
411 
412     \param type
413         Name of a window type.  The window type referenced should be a falagard mapped type.
414 
415     \return
416         String object holding the name of the window renderer mapped for the requested type.
417 
418     \exception InvalidRequestException thrown if \a type is not a falagard mapping type (or maybe the type didn't exist).
419     */
420     const String& getMappedRendererForType(const String& type) const;
421 
422     /*!
423     \brief
424         Use the alias system, where required, to 'de-reference' the specified
425         type to an actual window type that can be created directly (that being
426         either a concrete window type, or a falagard mapped type).
427 
428     \note
429         Even though implied by the above description, this method does not
430         check that a factory for the final type exists; we simply say that the
431         returned type is not an alias for some other type.
432 
433     \param type
434         String describing the type to be de-referenced.
435 
436     \return
437         String object holding a type for a window that can be created directly;
438         that is, a type that does not describe an alias to some other type.
439     */
440     String getDereferencedAliasType(const String& type) const;
441 
442     /*!
443     \brief
444         Return the FalagardWindowMapping for the specified window mapping \a type.
445 
446     \param type
447         Name of a window type.  The window type referenced should be a falagard mapped type.
448 
449     \return
450         FalagardWindowMapping object describing the falagard mapping.
451 
452     \exception InvalidRequestException thrown if \a type is not a falagard mapping type (or maybe the type didn't exist).
453     */
454     const FalagardWindowMapping& getFalagardMappingForType(const String& type) const;
455 
456 private:
457 	/*************************************************************************
458 		Implementation Data
459 	*************************************************************************/
460 	typedef	std::map<String, WindowFactory*, StringFastLessCompare
461         CEGUI_MAP_ALLOC(String, WindowFactory*)> WindowFactoryRegistry; //!< Type used to implement registry of WindowFactory objects
462 	typedef std::map<String, AliasTargetStack, StringFastLessCompare
463         CEGUI_MAP_ALLOC(String, AliasTargetStack)> TypeAliasRegistry; //!< Type used to implement registry of window type aliases.
464     typedef std::map<String, FalagardWindowMapping, StringFastLessCompare
465         CEGUI_MAP_ALLOC(String, FalagardWindowMapping)> FalagardMapRegistry; //!< Type used to implement registry of falagard window mappings.
466     //! Type used for list of WindowFacory objects that we created ourselves
467     typedef std::vector<WindowFactory*
468         CEGUI_VECTOR_ALLOC(WindowFactory*)> OwnedWindowFactoryList;
469 
470 	WindowFactoryRegistry	d_factoryRegistry;			//!< The container that forms the WindowFactory registry
471 	TypeAliasRegistry		d_aliasRegistry;			//!< The container that forms the window type alias registry.
472     FalagardMapRegistry     d_falagardRegistry;         //!< Container that hold all the falagard window mappings.
473     //! Container that tracks WindowFactory objects we created ourselves.
474     static OwnedWindowFactoryList  d_ownedFactories;
475 
476 public:
477 	/*************************************************************************
478 		Iterator stuff
479 	*************************************************************************/
480 	typedef	ConstMapIterator<WindowFactoryRegistry>	WindowFactoryIterator;
481 	typedef ConstMapIterator<TypeAliasRegistry>		TypeAliasIterator;
482     typedef ConstMapIterator<FalagardMapRegistry>   FalagardMappingIterator;
483 
484 	/*!
485 	\brief
486 		Return a WindowFactoryManager::WindowFactoryIterator object to iterate over the available WindowFactory types.
487 	*/
488 	WindowFactoryIterator	getIterator(void) const;
489 
490 
491 	/*!
492 	\brief
493 		Return a WindowFactoryManager::TypeAliasIterator object to iterate over the defined aliases for window types.
494 	*/
495 	TypeAliasIterator	getAliasIterator(void) const;
496 
497 
498     /*!
499     \brief
500         Return a WindowFactoryManager::FalagardMappingIterator object to iterate over the defined falagard window mappings.
501     */
502     FalagardMappingIterator getFalagardMappingIterator() const;
503 };
504 
505 //----------------------------------------------------------------------------//
506 template <typename T>
addFactory()507 void WindowFactoryManager::addFactory()
508 {
509     // create the factory object
510     WindowFactory* factory = CEGUI_NEW_AO T;
511 
512     // only do the actual add now if our singleton has already been created
513     if (WindowFactoryManager::getSingletonPtr())
514     {
515         Logger::getSingleton().logEvent("Created WindowFactory for '" +
516                                         factory->getTypeName() +
517                                         "' windows.");
518         // add the factory we just created
519         CEGUI_TRY
520         {
521             WindowFactoryManager::getSingleton().addFactory(factory);
522         }
523         CEGUI_CATCH (Exception&)
524         {
525             Logger::getSingleton().logEvent("Deleted WindowFactory for '" +
526                                             factory->getTypeName() +
527                                             "' windows.");
528             // delete the factory object
529             CEGUI_DELETE_AO factory;
530             CEGUI_RETHROW;
531         }
532     }
533 
534     d_ownedFactories.push_back(factory);
535 }
536 
537 //----------------------------------------------------------------------------//
538 template <typename T>
addWindowType()539 void WindowFactoryManager::addWindowType()
540 {
541     WindowFactoryManager::addFactory<TplWindowFactory<T> >();
542 }
543 
544 //----------------------------------------------------------------------------//
545 
546 } // End of  CEGUI namespace section
547 
548 
549 #if defined(_MSC_VER)
550 #	pragma warning(pop)
551 #endif
552 
553 #endif	// end of guard _CEGUIWindowFactoryManager_h_
554