plaintext/plugin_impl/interfaces_utils.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef INTERFACE_UTILS_H_
00028 #define INTERFACE_UTILS_H_
00029
00030 #include <typeinfo>
00031 #include <cassert>
00032 #include <string>
00033 #include <vector>
00034 #include <map>
00035 #include <algorithm>
00036
00037 #include "log.h"
00038
00039 namespace utils
00040 {
00041
00042 const unsigned int MAX_OBJECTS = 20;
00043 const unsigned int MAX_INTERFACES = 13;
00044
00045
00046 class InterfaceBase
00047 {
00048 public:
00049 InterfaceBase() {};
00050 virtual ~InterfaceBase(){} ;
00051 virtual bool is_name_equal(const char *name) = 0;
00052 virtual void * get_pointer() = 0;
00053 };
00054
00055
00056
00057
00058
00059 template<typename T>
00060 class InterfaceEntry : public InterfaceBase
00061 {
00062 public:
00063 InterfaceEntry(T *p)
00064 : ptr(p)
00065 {
00066 }
00067
00068 ~InterfaceEntry()
00069 {
00070 }
00071
00072 bool is_name_equal(const char * name)
00073 {
00074 if (name_.size() <= 0)
00075 {
00076 name_ = typeid(T).name();
00077 std::string::size_type start = name_.find("IPlugin");
00078 if (start != std::string::npos)
00079 {
00080 name_ = name_.substr(start);
00081 }
00082 else
00083 {
00084 name_.clear();
00085 }
00086 }
00087 return name_ == name;
00088 }
00089
00090 virtual void * get_pointer()
00091 {
00092 return ptr;
00093 }
00094
00095 private:
00096 std::string name_;
00097 T * ptr;
00098 };
00099
00100
00101
00102 class InterfaceTable
00103 {
00104 public:
00105 InterfaceTable()
00106 {
00107 }
00108
00109 ~InterfaceTable()
00110 {
00111 clear();
00112 }
00113
00114 public:
00115 template <class T>
00116 void add_entry(T * ptr)
00117 {
00118 interfaces.push_back(new InterfaceEntry<T>(ptr));
00119 unsigned int size = interfaces.size();
00120 if (size > MAX_INTERFACES)
00121 {
00122 ERRORPRINTF("Too many interfaces for class %s: interfaces.size [%u] max [%u]",
00123 typeid(T).name(), size, MAX_INTERFACES);
00124 }
00125 }
00126
00127 bool query_interface(const char * name, void **return_ptr)
00128 {
00129 Iter begin = interfaces.begin();
00130 Iter end = interfaces.end();
00131 for(Iter it = begin; it != end; ++it)
00132 {
00133 if ((*it)->is_name_equal(name))
00134 {
00135 *return_ptr = (*it)->get_pointer();
00136 return true;
00137 }
00138 }
00139
00140
00141 return false;
00142 }
00143
00144 template <class T>
00145 bool contain_interface(T *ptr)
00146 {
00147 Iter begin = interfaces.begin();
00148 Iter end = interfaces.end();
00149 for(Iter it = begin; it != end; ++it)
00150 {
00151 if (ptr == (*it)->get_pointer())
00152 {
00153 return true;
00154 }
00155 }
00156 return false;
00157 }
00158
00159 private:
00160 void clear()
00161 {
00162 Iter begin = interfaces.begin();
00163 Iter end = interfaces.end();
00164 for(Iter it = begin; it != end; ++it)
00165 {
00166 delete (*it);
00167 }
00168 interfaces.clear();
00169 }
00170
00171 private:
00172 typedef std::vector<InterfaceBase *> Interfaces;
00173 typedef std::vector<InterfaceBase *>::iterator Iter;
00174 Interfaces interfaces;
00175 };
00176
00177
00178
00179 template <typename T>
00180 class ObjectTable
00181 {
00182 public:
00183 ObjectTable(){}
00184 ~ObjectTable()
00185 {
00186 unsigned int size = table_.size();
00187 if (size != 0)
00188 {
00189 ERRORPRINTF("ObjectTable for class %s not empty: size [%u]",
00190 typeid(T).name(), size);
00191 }
00192 }
00193
00194 public:
00195
00196
00197
00198
00199 template <typename Arg>
00200 bool add_interface(T *object)
00201 {
00202 TableIter iter = table_.find(object);
00203 if (iter != table_.end())
00204 {
00205 iter->second->add_entry(static_cast<Arg *>(object));
00206 }
00207 else
00208 {
00209 InterfaceTablePtr ptr = new InterfaceTable;
00210 ptr->add_entry<Arg>(static_cast<Arg *>(object));
00211 table_[object] = ptr;
00212 unsigned int size = table_.size();
00213 if (size > MAX_OBJECTS)
00214 {
00215 ERRORPRINTF("Too many objects for class %s: ObjectTable.size [%u] max [%u]",
00216 typeid(T).name(), size, MAX_OBJECTS);
00217 }
00218 }
00219 return true;
00220 }
00221
00222 bool query_interface(T * object, const char *name, void **return_ptr)
00223 {
00224 TableIter iter = table_.find(object);
00225 if (iter != table_.end())
00226 {
00227 return iter->second->query_interface(name, return_ptr);
00228 }
00229 return false;
00230 }
00231
00232
00233 bool remove(T * object)
00234 {
00235 TableIter iter = table_.find(object);
00236 if (iter != table_.end())
00237 {
00238 delete iter->second;
00239 table_.erase(iter);
00240 return true;
00241 }
00242 return false;
00243 }
00244
00245
00246 template <typename Arg>
00247 T * get_object(Arg * arg)
00248 {
00249 TableIter begin = table_.begin();
00250 TableIter end = table_.end();
00251 for(TableIter iter = begin; iter != end; ++iter)
00252 {
00253 if (iter->second->contain_interface(arg))
00254 {
00255 return iter->first;
00256 }
00257 }
00258 assert(false);
00259 return 0;
00260 }
00261
00262
00263 private:
00264 typedef InterfaceTable * InterfaceTablePtr;
00265 typedef std::map<T *, InterfaceTablePtr> Table;
00266 typedef typename std::map<T *, InterfaceTablePtr>::iterator TableIter;
00267 Table table_;
00268
00269 };
00270
00271 };
00272
00273
00274 #endif
00275