00001
#ifndef REGISTRY_H
00002
#define REGISTRY_H
00003
00004
#include <nmstl_util.h>
00005
#include "Exceptions.h"
00006
00007 BOREALIS_NAMESPACE_BEGIN;
00008
00009
template<
typename BaseClass =
void,
typename Key = string>
class RegistryInfo;
00010
00011
template<
typename Key>
00012 class RegistryInfo<void, Key>
00013 {
00014
protected:
00015 RegistryInfo(string class_name, Key key) :
00016 _class_name(class_name), _key(key.empty() ? class_name : key) {}
00017
00018
public:
00019 virtual ~
RegistryInfo() {}
00020
00021 string getClassName()
const {
return _class_name; }
00022 Key getKey()
const {
return _key; }
00023
00024 virtual string as_string()
const
00025
{
00026
return( _class_name ==
to_string( _key )
00027 ? _class_name
00028 : (
to_string( _key ) +
"->" + _class_name ));
00029 }
00030
00031
private:
00032 string _class_name;
00033 Key _key;
00034 };
00035
00036
00038
template<
typename BaseClass,
typename Key>
00039 class RegistryInfo :
public RegistryInfo<void, Key>
00040 {
00041
protected:
00042 RegistryInfo(string class_name, Key key) :
00043
RegistryInfo<void, Key>(class_name, key)
00044 {}
00045
00046
public:
00047
virtual BaseClass *
instantiate() const = 0;
00048 };
00049
00050
00051
00052 template<typename BaseClass, typename Subclass, typename Key = string>
00053 class
SimpleRegistryInfo : public
RegistryInfo<BaseClass>
00054 {
00055
public:
00056 SimpleRegistryInfo( Key key = Key() ) :
00057
RegistryInfo<BaseClass>(
to_string( typeid( Subclass )), key) {}
00058
00059 virtual BaseClass *
instantiate()
const {
return(
new Subclass ); }
00060 };
00061
00062
00063 #define AURORA_DECLARE_REG_CLASS(BaseClass, Subclass) \
00064
private: \
00065
static const SimpleRegistryInfo<BaseClass, Subclass> _aurora_info; \
00066
static bool _aurora_registered;
00067
00068 #define AURORA_DEFINE_REG_CLASS(BaseClass, Subclass) \
00069
const SimpleRegistryInfo<BaseClass, Subclass> Subclass::_aurora_info; \
00070
bool Subclass::_aurora_registered = \
00071
(Borealis::Registry<BaseClass>::get().add(_aurora_info), true);
00072
00073 #define AURORA_DEFINE_REG_CLASS_WITH_KEY(BaseClass, Subclass, Key) \
00074
const SimpleRegistryInfo<BaseClass, Subclass> Subclass::_aurora_info(Key); \
00075
bool Subclass::_aurora_registered = \
00076
(Borealis::Registry<BaseClass>::get().add(_aurora_info), true);
00077
00078
00079 #define AURORA_DECLARE_REG_CLASS_WITH_INFO(RegistryClass, Subclass) \
00080
private: \
00081
static bool _aurora_registered;
00082
00083 #define AURORA_DEFINE_REG_CLASS_WITH_INFO(RegistryClass, Subclass, info) \
00084
bool Subclass::_aurora_registered = \
00085
(Borealis::RegistryClass::get().add(info), true);
00086
00087
00088
00089
00090
template<
typename BaseClass,
00091
typename _Info =
RegistryInfo<BaseClass>,
00092
typename Key = string
00093 >
00094 class Registry
00095 {
00096
typedef Registry<BaseClass, _Info, Key> Me;
00097
typedef map<Key, const _Info *> InfoMap;
00098
00099
public:
00100 typedef _Info
Info;
00101
00102 static Registry<BaseClass, Info> &get()
00103 {
00104
static Me it;
00105
return it;
00106 }
00107
00108 Registry() : _my_type(
"Registry<" +
to_string( typeid( BaseClass )) +
">" )
00109 {
00110 INFO <<
"Creating " << _my_type;
00111 }
00112
00113 void add(
const Info &info )
00114 {
00115 DEBUG <<
"Adding " << info <<
" to " << _my_type;
00116
00117 _infos[ info.getKey() ] = &info;
00118 }
00119
00120 string as_string()
const
00121
{
00122 string ret;
00123 ret << _my_type <<
"{";
00124
00125
for (
typename InfoMap::const_iterator i = _infos.begin();
00126 i != _infos.end(); ++i )
00127 {
00128
if ( i != _infos.begin() )
00129 { ret <<
",";
00130 }
00131
00132 ret << *(i->second);
00133 }
00134
00135 ret <<
"}";
00136
00137
return( ret );
00138 }
00139
00140 const Info *forKey( Key key )
const
00141
{
00142
return( lookup( _infos, key ));
00143 }
00144
00145
private:
00146 InfoMap _infos;
00147 string _my_type;
00148 };
00149
00150 BOREALIS_NAMESPACE_END;
00151
00152
#endif // REGISTRY_H