Ticket #32: DynamicFactory.h

File DynamicFactory.h, 4.1 KB (added by Nick Draper, 13 years ago)

DynamicFactory header

Line 
1#ifndef DYNAMICFACTORY_H_
2#define DYNAMICFACTORY_H_
3
4//----------------------------------------------------------------------
5// Includes
6//----------------------------------------------------------------------
7#include "Instantiator.h"
8#include <map>
9
10namespace Mantid
11{
12/** @class DynamicFactory DynamicFactory.h Kernel/DynamicFactory.h
13
14    The dynmic factory is a base dynamic factory for serving up objects in response to requests from other classes.
15   
16    @author Nick Draper, Tessella Support Services plc
17    @date 10/10/2007
18   
19    Copyright © 2007 ???RAL???
20
21    This file is part of Mantid.
22
23    Mantid is free software; you can redistribute it and/or modify
24    it under the terms of the GNU General Public License as published by
25    the Free Software Foundation; either version 3 of the License, or
26    (at your option) any later version.
27
28    Mantid is distributed in the hope that it will be useful,
29    but WITHOUT ANY WARRANTY; without even the implied warranty of
30    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31    GNU General Public License for more details.
32
33    You should have received a copy of the GNU General Public License
34    along with this program.  If not, see <http://www.gnu.org/licenses/>.
35
36    File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>   
37*/
38template <class Base>
39class DynamicFactory
40        /// A factory that creates objects by class name.
41{
42public:
43        typedef AbstractInstantiator<Base> AbstractFactory;
44       
45        DynamicFactory()
46                /// Creates the DynamicFactory.
47        {
48        }
49
50        ~DynamicFactory()
51                /// Destroys the DynamicFactory and deletes the instantiators for
52                /// all registered classes.
53        {
54                for (typename FactoryMap::iterator it = _map.begin(); it != _map.end(); ++it)
55                {
56                        delete it->second;
57                }
58        }
59       
60        Base* create(const std::string& className) const
61                /// Creates a new instance of the class with the given name.
62                /// The class must have been registered with registerClass.
63                /// If the class name is unknown, a NotFoundException is thrown.
64        {
65               
66                typename FactoryMap::const_iterator it = _map.find(className);
67                if (it != _map.end())
68                        return it->second->createInstance();
69                else
70                        throw NotFoundException(className);
71        }
72       
73        template <class C> 
74        void subscribe(const std::string& className)
75                /// Registers the instantiator for the given class with the DynamicFactory.
76                /// The DynamicFactory takes ownership of the instantiator and deletes
77                /// it when it's no longer used.
78                /// If the class has already been registered, an ExistsException is thrown
79                /// and the instantiator is deleted.
80        {
81                registerClass(className, new Instantiator<C, Base>);
82        }
83       
84        void subscribe(const std::string& className, AbstractFactory* pAbstractFactory)
85                /// Registers the instantiator for the given class with the DynamicFactory.
86                /// The DynamicFactory takes ownership of the instantiator and deletes
87                /// it when it's no longer used.
88                /// If the class has already been registered, an ExistsException is thrown
89                /// and the instantiator is deleted.
90        {
91                std::auto_ptr<AbstractFactory> ptr(pAbstractFactory);
92                typename FactoryMap::iterator it = _map.find(className);
93                if (it == _map.end())
94                        _map[className] = ptr.release();
95                else
96                        throw ExistsException(className);
97        }
98       
99        void unsubscribe(const std::string& className)
100                /// Unregisters the given class and deletes the instantiator
101                /// for the class.
102                /// Throws a NotFoundException if the class has not been registered.
103        {
104                typename FactoryMap::iterator it = _map.find(className);
105                if (it != _map.end())
106                {
107                        delete it->second;
108                        _map.erase(it);
109                }
110                else throw NotFoundException(className);
111        }
112       
113        bool exists(const std::string& className) const
114                /// Returns true if the given class is currently registered.
115        {
116                return _map.find(className) != _map.end();
117        }
118       
119
120private:
121        DynamicFactory(const DynamicFactory&);
122        DynamicFactory& operator = (const DynamicFactory&);
123
124        typedef std::map<std::string, AbstractFactory*> FactoryMap;
125       
126        FactoryMap _map;
127};
128
129}
130
131#endif /*DYNAMICFACTORY_H_*/
132
133