1 // GnashFactory.h A generic class template
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef GNASH_FACTORY_H
22 #define GNASH_FACTORY_H
25 # include "gnashconfig.h"
32 #include <boost/type_traits.hpp>
33 #include <boost/utility/enable_if.hpp>
36 #include "GnashAlgorithm.h"
41 /// A generic factory class for registering and retrieving objects by key.
43 /// Note: there is only one GnashFactory for any combination of template
44 /// arguments. It's not advisable to have more than one factory for any
47 /// Note that this relies on static initialization, so do not call get()
48 /// before or after main().
50 /// @tparam T The base type to be produced by the factory
51 /// @tparam Init An object whose constructor ensures that the elements
52 /// are registered. This helps avoid problems with
53 /// unpredictable static initialization.
54 /// @tparam Key The type to be used as a key.
55 template<typename T
, typename Init
= void, typename Key
= std::string
>
56 class DSOEXPORT GnashFactory
63 template<typename Derived
>
64 struct RegisterHandler
66 static T
* createHandler() {
70 RegisterHandler(const Key
& name
) {
71 GnashFactory::instance().registerHandler(name
, createHandler
);
75 typedef T
*(*CreateHandler
)();
76 typedef std::map
<std::string
, CreateHandler
> Handlers
;
78 /// Get the GnashFactory singleton.
79 static GnashFactory
& instance() {
80 static GnashFactory m
;
84 /// Dump the registered keys to the iterator.
86 /// Only usable with output iterators.
87 template<typename Iterator
>
88 void listKeys(Iterator i
, typename
boost::enable_if
<boost::is_same
<
89 typename
std::iterator_traits
<Iterator
>::iterator_category
,
90 std::output_iterator_tag
> >::type
* dummy
= 0) {
92 static_cast<void>(dummy
);
93 std::transform(_handlers
.begin(), _handlers
.end(), i
,
94 FirstElement
<typename
Handlers::value_type
>());
98 /// Return a Handler identified by a name.
100 /// @param name The name of the handler to return. An empty string
101 /// will return the first available handler. If the
102 /// string is not empty and no match is found, a null
103 /// pointer will be returned.
104 T
* get(const Key
& name
) {
107 return _handlers
.empty() ? 0 : _handlers
.begin()->second();
110 typename
Handlers::const_iterator it
= _handlers
.find(name
);
111 if (it
== _handlers
.end()) return 0;
115 /// Register a Handler with a particular name.
117 /// @param name The name to register the Handler under. Duplicated
118 /// names will replace previous handlers!
119 /// @param r A pointer to a function that will return the
120 /// Handler when called.
121 void registerHandler(const Key
& name
, CreateHandler r
) {