00001
00002
00014 #ifndef _Factory_H_
00015 #define _Factory_H_
00016
00017 #include "FactoryException.h"
00018
00019 #ifdef _MSC_VER
00020 #include "msdevstudio/MSconfig.h"
00021 #endif
00022
00023 #include <map>
00024 #include <vector>
00025
00026 namespace hippodraw {
00027
00043 template < class Type > class Factory
00044 {
00045 private:
00046
00048 Factory ( const Factory< Type > & );
00049
00050 protected:
00051
00053 std::map < std::string, Type * > m_types;
00054
00058 mutable std::vector< std::string > m_names;
00059
00062 Factory ( );
00063
00066 virtual ~Factory();
00067
00068 public:
00069
00071 void add ( Type * );
00072
00075 void remove ( const std::string & name );
00076
00080 bool exists ( const std::string & name ) const;
00081
00085 Type * prototype ( const std::string & name ) const;
00086
00091 Type * create ( const std::string & name );
00092
00094 const std::vector< std::string > & names () const;
00095
00096 };
00097
00098 template < class Type >
00099 Factory < Type >::Factory ( )
00100 {
00101 }
00102
00103 template< class Type >
00104 Factory<Type>::~Factory ()
00105 {
00106 typename std::map < std::string, Type * > ::iterator first
00107 = m_types.begin();
00108 for ( ; first != m_types.end(); ++first ) {
00109 delete first->second;
00110 }
00111
00112 m_types.clear ();
00113 }
00114
00115 template< class Type >
00116 void Factory<Type>::add ( Type * obj )
00117 {
00118 const std::string & name = obj->name ();
00119 m_types[name] = obj;
00120 }
00121
00122 template < class Type >
00123 void
00124 Factory < Type >::
00125 remove ( const std::string & name )
00126 {
00127 typename std::map < std::string, Type * > ::iterator it
00128 = m_types.find ( name );
00129 if ( it != m_types.end () ) {
00130 m_types.erase ( it );
00131 }
00132 }
00133
00134 template < class Type >
00135 bool Factory < Type>::
00136 exists ( const std::string & name ) const
00137 {
00138
00139
00140 typename std::map< std::string, Type * >::const_iterator it
00141 = m_types.find ( name );
00142
00143 return it != m_types.end ();
00144 }
00145
00146
00147 template< class Type >
00148 Type * Factory<Type>::prototype ( const std::string & name ) const
00149 {
00150
00151
00152 typename std::map< std::string, Type * >::const_iterator it
00153 = m_types.find ( name );
00154 if ( it == m_types.end () ) throw FactoryException ( name );
00155
00156 return it->second;
00157 }
00158
00159 template< class Type >
00160 Type * Factory<Type>::create ( const std::string & name )
00161 {
00162 Type * obj = prototype ( name );
00163 if ( obj == 0 ) {
00164 return 0;
00165 }
00166 return obj->clone ();
00167 }
00168
00169 template< class Type >
00170 const std::vector< std::string > & Factory<Type>::names () const
00171 {
00172 m_names.clear ();
00173 typename std::map <std::string, Type *>::const_iterator it
00174 = m_types.begin ();
00175 for ( ; it != m_types.end (); ++it ) {
00176 m_names.push_back ( it->first );
00177 }
00178
00179 return m_names;
00180 }
00181
00182 }
00183
00184 #endif // _Factory_H_