00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_CLASS_REGISTRY_H
00027 #define NL_CLASS_REGISTRY_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/common.h"
00031 #include <typeinfo>
00032 #include <string>
00033 #include <set>
00034
00035
00036 namespace NLMISC
00037 {
00038
00039
00040
00047 struct ERegistry : public Exception
00048 {
00049 ERegistry() : Exception( "Registry error" ) {};
00050
00051 ERegistry( const std::string& str ) : Exception( str ) {};
00052 };
00053
00054 struct ERegisteredClass : public ERegistry
00055 {
00056 ERegisteredClass() : ERegistry( "Class already registered" ) {};
00057 };
00058
00059 struct EUnregisteredClass : public ERegistry
00060 {
00061 EUnregisteredClass() : ERegistry( "Class not registered" ) {}
00062 EUnregisteredClass(const std::string &className) : ERegistry( std::string("Class not registered : ") + className ) {}
00063 };
00064
00065
00066
00073 class IClassable
00074 {
00075 public:
00076 virtual std::string getClassName() =0;
00077 };
00078
00079
00080
00087 class CClassRegistry
00088 {
00089 public:
00090
00092 static void registerClass(const std::string &className, IClassable* (*creator)(), const std::string &typeidCheck) throw(ERegistry);
00093
00095 static IClassable *create(const std::string &className) throw(ERegistry);
00096
00098 static bool checkObject(IClassable* obj);
00099
00100
00101 private:
00102 struct CClassNode
00103 {
00104 std::string ClassName;
00105 std::string TypeIdCheck;
00106 IClassable* (*Creator)();
00107 bool operator<(const CClassNode &n) const
00108 {
00109 return ClassName<n.ClassName;
00110 }
00111 };
00112 static std::set<CClassNode> *RegistredClasses;
00113
00115 static void init();
00116 };
00117
00118
00120 #define NLMISC_DECLARE_CLASS(_class_) \
00121 virtual std::string getClassName() {return #_class_;} \
00122 static NLMISC::IClassable *creator() {return new _class_;}
00123 #define NLMISC_REGISTER_CLASS(_class_) NLMISC::CClassRegistry::registerClass(#_class_, _class_::creator, typeid(_class_).name());
00124
00125
00126
00127 }
00128
00129
00130 #endif // NL_STREAM_H
00131
00132