Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnFactory.h
1 /*****************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnFactory.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <cassert>
17 #include <map>
18 #include <list>
19 #include <typeinfo>
20 
21 #include "drwnXMLParser.h"
22 #include "drwnInterfaces.h"
23 #include "drwnLogger.h"
24 
25 using namespace std;
26 
27 // drwnFactoryTraits -------------------------------------------------------
30 
31 template <typename T>
33  static void staticRegistration() { /* do nothing */ };
34 };
35 
36 // drwnFactory --------------------------------------------------------------
57 
58 template<typename U>
60 {
61  protected:
62  bool _initialized;
63  typedef U* (*drwnCreatorFcn)(void);
64  map<string, drwnCreatorFcn> _registry;
65 
66  public:
67  ~drwnFactory() { /* do nothing */ }
69  static drwnFactory<U>& get();
70 
72  void registerClass(const char *name, drwnCreatorFcn fcn);
74  void unregisterClass(const char *name);
76  list<string> getRegisteredClasses() const;
77 
79  U *create(const char *name) const;
81  U *createFromXML(drwnXMLNode& xml) const;
83  U *createFromFile(const char *filename) const;
84 
86  void dump() const;
87 
88  protected:
90  drwnFactory() : _initialized(false) { /* do nothing */ }
91 };
92 
93 // drwnFactoryAutoRegister --------------------------------------------------
95 
96 template<typename U, typename T>
98 {
99  public:
100  drwnFactoryAutoRegister(const char *name) {
102  }
103 
104  private:
105  static U *creator() { return new T(); }
106 };
107 
108 #define DRWN_FACTORY_REGISTER(baseName, className) \
109  drwnFactoryAutoRegister<baseName, className> \
110  __ ## baseName ## _ ## className ## _ ## AutoRegister(#className);
111 
112 // drwnFactory implementation ------------------------------------------------
113 
114 template<typename U>
116 {
117  static drwnFactory<U> factory;
118  if (!factory._initialized) {
119  DRWN_LOG_DEBUG("initializing drwnFactory for " << typeid(U).name());
120  factory._initialized = true;
122  }
123  return factory;
124 }
125 
126 template<typename U>
127 void drwnFactory<U>::registerClass(const char *name, drwnCreatorFcn fcn)
128 {
129  DRWN_ASSERT(name != NULL);
130 
131  typename map<string, drwnCreatorFcn>::iterator jt = _registry.find(string(name));
132  if (jt != _registry.end()) {
133  DRWN_LOG_ERROR("class \"" << name << "\" already registered with drwnFactory");
134  jt->second = fcn;
135  } else {
136  DRWN_LOG_DEBUG("registering class \"" << name << "\" with the drwnFactory");
137  _registry.insert(make_pair(string(name), fcn));
138  }
139 }
140 
141 template<typename U>
142 void drwnFactory<U>::unregisterClass(const char *name)
143 {
144  DRWN_ASSERT(name != NULL);
145  DRWN_LOG_DEBUG("unregistering class \"" << name << "\" from drwnFactory");
146  typename map<string, drwnCreatorFcn>::iterator jt = _registry.find(string(name));
147  if (jt == _registry.end()) {
148  DRWN_LOG_ERROR("class \"" << name << "\" does not exist in drwnFactory");
149  return;
150  }
151 
152  _registry.erase(jt);
153 }
154 
155 template<typename U>
157 {
158  list<string> names;
159  for (typename map<string, drwnCreatorFcn>::const_iterator it = _registry.begin();
160  it != _registry.end(); ++it) {
161  names.push_back(it->first);
162  }
163  return names;
164 }
165 
166 template<typename U>
167 U *drwnFactory<U>::create(const char *name) const
168 {
169  DRWN_ASSERT(name != NULL);
170 
171  typename map<string, drwnCreatorFcn>::const_iterator jt = _registry.find(string(name));
172  if (jt == _registry.end()) {
173  DRWN_LOG_ERROR("class \"" << name << "\" does not exist in drwnFactory");
174  return NULL;
175  }
176 
177  return (*jt->second)();
178 }
179 
180 template<typename U>
181 U *drwnFactory<U>::createFromXML(drwnXMLNode& xml) const
182 {
183  // construct node and initialize from XML
184  U *object = create(xml.name());
185  if (object == NULL) {
186  return NULL;
187  }
188 
189  object->load(xml);
190  return object;
191 }
192 
193 template<typename U>
194 U *drwnFactory<U>::createFromFile(const char *filename) const
195 {
196  DRWN_ASSERT(filename != NULL);
197 
198  // parse XML file
199  drwnXMLDoc xml;
200  drwnXMLNode *node = drwnParseXMLFile(xml, filename);
201  DRWN_ASSERT(node != NULL);
202 
203  return createFromXML(*node);
204 }
205 
206 template<typename U>
208 {
209  DRWN_LOG_MESSAGE("drwnFactory has the following registered classes:");
210  for (typename map<string, drwnCreatorFcn>::const_iterator it = _registry.begin();
211  it != _registry.end(); ++it) {
212  DRWN_LOG_MESSAGE(" " << it->first);
213  }
214 }
U * createFromFile(const char *filename) const
create an object from file
Definition: drwnFactory.h:194
Some classes may provide default factory registration (e.g., built-in classes such as drwnClassifier ...
Definition: drwnFactory.h:32
void registerClass(const char *name, drwnCreatorFcn fcn)
register a class and creator function
Definition: drwnFactory.h:127
Templated factory for creating or cloning objects for a particular base class.
Definition: drwnFactory.h:59
drwnFactory()
singleton class so hide constructor
Definition: drwnFactory.h:90
U * createFromXML(drwnXMLNode &xml) const
create an object from an XML node
Definition: drwnFactory.h:181
drwnXMLNode * drwnParseXMLFile(drwnXMLDoc &xml, const char *filename, const char *tag=NULL)
parse an xml file into xml (loads all data into memory) and return a pointer to the first node (with ...
Definition: drwnXMLParser.cpp:22
void unregisterClass(const char *name)
unregister a previously registered class
Definition: drwnFactory.h:142
U * create(const char *name) const
create a default object
Definition: drwnFactory.h:167
Provides XML parsing functionality for serializing and deserializing objects and containers of object...
list< string > getRegisteredClasses() const
get a list of all registered classes
Definition: drwnFactory.h:156
Helper class for registering classes with a drwnFactory.
Definition: drwnFactory.h:97
void dump() const
dump the contents of the registery for debugging
Definition: drwnFactory.h:207
static drwnFactory< U > & get()
get the factory
Definition: drwnFactory.h:115