ProcessingDataPlugin.hxx
Go to the documentation of this file.00001 #ifndef ProcessingDataPlugin_hxx
00002 #define ProcessingDataPlugin_hxx
00003
00004 #include <string>
00005 #include <cstdlib>
00006 #include <map>
00007 #include <list>
00008 #include <typeinfo>
00009 #include <iostream>
00010
00011 #ifdef __GNUC__
00012 #include <cxxabi.h>
00013 #endif//__GNUC__
00014 namespace CLAM
00015 {
00016
00017 class ProcessingDataPlugin
00018 {
00019 public:
00020 typedef std::string Key;
00021 typedef std::type_info Type;
00022 typedef std::map<Key,ProcessingDataPlugin *> TypeMap;
00023 private:
00024 const Type & _type;
00025 std::string _color;
00026 std::string _displayName;
00027 std::string _name;
00028 static std::string demangle(const std::string & mangledName)
00029 {
00030 std::string result = mangledName;
00031 #ifdef __GNUC__
00032 int demangleError = 0;
00033 char * demangled = abi::__cxa_demangle(mangledName.c_str(),0,0,&demangleError);
00034 if (!demangleError && demangled)
00035 result = demangled;
00036 if (demangled) free(demangled);
00037 #endif//__GNUC__
00038 return result;
00039 }
00040 ProcessingDataPlugin(const std::type_info & type, const std::string & color, const std::string & displayName)
00041 : _type(type)
00042 , _color(color)
00043 {
00044 _name = _displayName = type.name();
00045 _displayName = displayName.empty()?
00046 demangle(_name) : displayName;
00047
00048 getTypeMap().insert(std::make_pair(_name, this));
00049 }
00050 ~ProcessingDataPlugin()
00051 {
00052 if (lookUp(_type)==this) getTypeMap().erase(_type.name());
00053 }
00054 public:
00055 const std::string & color() const { return _color; }
00056 const std::string & name() const { return _name; }
00057 const std::string & displayName() const { return _displayName; }
00058 private:
00059 static TypeMap & getTypeMap();
00060 public:
00061 static std::list<std::string> types()
00062 {
00063 std::list<std::string> result;
00064 for (TypeMap::iterator it=getTypeMap().begin();
00065 it!=getTypeMap().end(); it++)
00066 {
00067 result.push_back(it->first);
00068 }
00069 return result;
00070 }
00071 static ProcessingDataPlugin * lookUp(const Type & type)
00072 {
00073 TypeMap::iterator it = getTypeMap().find(type.name());
00074 if (it==getTypeMap().end()) return 0;
00075 return it->second;
00076 }
00077 static std::string colorFor(const std::type_info & type)
00078 {
00079 CLAM::ProcessingDataPlugin * plugin = lookUp(type);
00080 if (plugin) return plugin->color();
00081 return "";
00082 }
00083 static std::string displayNameFor(const std::type_info & type)
00084 {
00085 CLAM::ProcessingDataPlugin * plugin = lookUp(type);
00086 if (plugin) return plugin->displayName();
00087 return demangle(type.name());
00088 }
00089
00090 public:
00091 template <typename DataType>
00092 class Registrator
00093 {
00094 ProcessingDataPlugin * _plugin;
00095 public:
00096 Registrator(const std::string & color, const std::string & displayName="")
00097 : _plugin( new ProcessingDataPlugin(typeid(DataType), color, displayName))
00098 {
00099 }
00100 ~Registrator() { delete _plugin; }
00101 };
00102 };
00103
00104 }
00105
00106
00107 #endif//ProcessingDataPlugin_hxx
00108