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