Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2011, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef TypInfo_INCLUDE_ONCE 00033 #define TypInfo_INCLUDE_ONCE 00034 00035 #include <vlCore/MurmurHash3.hpp> 00036 00037 namespace vl 00038 { 00044 //--------------------------------------------------------------------------------------------------------------------- 00046 struct TypeInfo 00047 { 00049 TypeInfo(const char* name): mName(name) 00050 { 00051 // compute string length 00052 const char* ptr = name; 00053 while( *ptr ) ++ptr; 00054 vl::MurmurHash3_x86_32(name, (int)(ptr - name), 0, &mHash); 00055 // printf("--- --- TypeInfo : %s = %x\n", name, mHash); 00056 } 00057 00059 bool operator==(const TypeInfo& other) const { return mHash == other.mHash; } 00060 00062 bool operator<(const TypeInfo& other) const { return mHash < other.mHash; } 00063 00065 const char* name() const { return mName; } 00066 00068 u32 hash() const { return mHash; } 00069 00070 private: 00071 // we could also use u32 mHash[4] and MurmurHash3_x86_128() for extra safety. 00072 u32 mHash; 00073 const char* mName; 00074 }; 00075 } 00076 //--------------------------------------------------------------------------------------------------------------------- 00077 #define VL_GROUP(...) __VA_ARGS__ 00078 #define VL_TO_STR(...) #__VA_ARGS__ 00079 //--------------------------------------------------------------------------------------------------------------------- 00080 #define VL_INSTRUMENT_BASE_CLASS(ClassName) \ 00081 public: \ 00082 /* static functions */ \ 00083 \ 00084 static const char* Name() { return VL_TO_STR(ClassName); } \ 00085 \ 00086 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00087 \ 00088 /* virtual functions */ \ 00089 \ 00090 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00091 \ 00092 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00093 \ 00094 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00095 { \ 00096 return type == Type(); \ 00097 } \ 00098 /* virtual Object* createThisType() const { return new ClassName; } */ \ 00099 private: 00100 //--------------------------------------------------------------------------------------------------------------------- 00101 #define VL_INSTRUMENT_ABSTRACT_BASE_CLASS(ClassName) \ 00102 public: \ 00103 /* static functions */ \ 00104 \ 00105 static const char* Name() { return VL_TO_STR(ClassName); } \ 00106 \ 00107 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00108 \ 00109 /* virtual functions */ \ 00110 \ 00111 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00112 \ 00113 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00114 \ 00115 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00116 { \ 00117 return type == Type(); \ 00118 } \ 00119 /* virtual Object* createThisType() const = 0; */ \ 00120 private: 00121 //--------------------------------------------------------------------------------------------------------------------- 00122 #define VL_INSTRUMENT_CLASS(ClassName, BaseClass) \ 00123 private: \ 00124 typedef BaseClass super; \ 00125 public: \ 00126 /* static functions */ \ 00127 \ 00128 static const char* Name() { return VL_TO_STR(ClassName); } \ 00129 \ 00130 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00131 \ 00132 /* virtual functions */ \ 00133 \ 00134 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00135 \ 00136 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00137 \ 00138 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00139 { \ 00140 return type == Type() || super::isOfType(type); \ 00141 } \ 00142 /* virtual Object* createThisType() const { return new ClassName; } */ \ 00143 private: 00144 //--------------------------------------------------------------------------------------------------------------------- 00145 #define VL_INSTRUMENT_ABSTRACT_CLASS(ClassName, BaseClass) \ 00146 private: \ 00147 typedef BaseClass super; \ 00148 public: \ 00149 /* static functions */ \ 00150 \ 00151 static const char* Name() { return VL_TO_STR(ClassName); } \ 00152 \ 00153 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00154 \ 00155 /* virtual functions */ \ 00156 \ 00157 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00158 \ 00159 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00160 \ 00161 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00162 { \ 00163 return type == Type() || super::isOfType(type); \ 00164 } \ 00165 /* virtual Object* createThisType() const = 0; */ \ 00166 private: 00167 //--------------------------------------------------------------------------------------------------------------------- 00168 #define VL_INSTRUMENT_CLASS_2(ClassName, BaseClass1, BaseClass2) \ 00169 private: \ 00170 typedef BaseClass1 super1; \ 00171 typedef BaseClass2 super2; \ 00172 public: \ 00173 /* static functions */ \ 00174 \ 00175 static const char* Name() { return VL_TO_STR(ClassName); } \ 00176 \ 00177 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00178 \ 00179 /* virtual functions */ \ 00180 \ 00181 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00182 \ 00183 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00184 \ 00185 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00186 { \ 00187 return type == Type() || super1::isOfType(type) || super2::isOfType(type); \ 00188 } \ 00189 /* virtual Object* createThisType() const { return new ClassName; } */ \ 00190 private: 00191 //--------------------------------------------------------------------------------------------------------------------- 00192 #define VL_INSTRUMENT_ABSTRACT_CLASS_2(ClassName, BaseClass1, BaseClass2) \ 00193 private: \ 00194 typedef BaseClass1 super1; \ 00195 typedef BaseClass2 super2; \ 00196 public: \ 00197 /* static functions */ \ 00198 \ 00199 static const char* Name() { return VL_TO_STR(ClassName); } \ 00200 \ 00201 static const ::vl::TypeInfo& Type() { static const ::vl::TypeInfo class_type(VL_TO_STR(ClassName)); return class_type; } \ 00202 \ 00203 /* virtual functions */ \ 00204 \ 00205 virtual const char* className() const { return VL_TO_STR(ClassName); } \ 00206 \ 00207 virtual const ::vl::TypeInfo& classType() const { return Type(); } \ 00208 \ 00209 virtual bool isOfType(const ::vl::TypeInfo& type) const \ 00210 { \ 00211 return type == Type() || super1::isOfType(type) || super2::isOfType(type); \ 00212 } \ 00213 /* virtual Object* createThisType() const = 0; */ \ 00214 private: 00215 //--------------------------------------------------------------------------------------------------------------------- 00216 namespace vl 00217 { 00218 template<class B, class A> 00219 B* cast(A* obj) 00220 { 00221 if(obj && obj->isOfType(B::Type())) 00222 return static_cast<B*>(obj); 00223 else 00224 return NULL; 00225 } 00226 //--------------------------------------------------------------------------------------------------------------------- 00227 template<class B, class A> 00228 const B* cast_const(const A* obj) // need rename to cast_const for GCC 00229 { 00230 if(obj && obj->isOfType(B::Type())) 00231 return static_cast<const B*>(obj); 00232 else 00233 return NULL; 00234 } 00235 } 00236 //--------------------------------------------------------------------------------------------------------------------- 00237 00238 //--------------------------------------------------------------------------------------------------------------------- 00239 // USAGE EXAMPLES 00240 //--------------------------------------------------------------------------------------------------------------------- 00241 00242 /*** 00243 00244 namespace ns 00245 { 00246 // NO INHERITANCE FROM INSTRUMENTED BASE CLASS 00247 class Base 00248 { 00249 VL_INSTRUMENT_BASE_CLASS(Base) 00250 }; 00251 00252 // SIMPLE INHERITANCE OF INSTRUMENTED CLASS 00253 class ClassA: public virtual Base 00254 { 00255 VL_INSTRUMENT_CLASS(ns::ClassA, Base) 00256 }; 00257 00258 // SIMPLE INHERITANCE OF INSTRUMENTED CLASS 00259 class ClassB: public virtual Base 00260 { 00261 VL_INSTRUMENT_CLASS(ns::ClassB, Base) 00262 }; 00263 00264 // MULTIPLE INHERITANCE 00265 class ClassAB: public ClassA, public ClassB 00266 { 00267 VL_INSTRUMENT_CLASS_2(ns::ClassAB, ClassA, ClassB) 00268 }; 00269 00270 // TEMPLATE CLASSES WITH MORE THAN 1 PARAMS 00271 template<class T1, class T2> 00272 class ClassT: public Base 00273 { 00274 VL_INSTRUMENT_CLASS(VL_GROUP(ns::ClassT<T1, T2>), Base) 00275 }; 00276 00277 // SUBCLASSES OF TEMPLATES WITH MORE THAN 1 PARAMS 00278 class ClassSubT: public ClassT<int, float> 00279 { 00280 VL_INSTRUMENT_CLASS(ns::ClassSubT, VL_GROUP(ClassT<int, float>)) 00281 }; 00282 } 00283 00284 IMPORTANT NOTE: 00285 - The "ClassName" parameter of VL_INSTRUMENT_* should ALWAYS specify the full NAMESPACE. 00286 - The "BaseClass" parameter of VL_INSTRUMENT_* should not specify the namespace unless strictly necessary. 00287 00288 --- dynamic casting example --- 00289 00290 ns::ClassAB AB; 00291 ns::ClassA* pA = &AB; 00292 ns::ClassB* pB = &AB; 00293 assert( vl::cast<ns::ClassAB>(pA) != NULL ) 00294 assert( vl::cast<ns::ClassAB>(pB) != NULL ) 00295 assert( vl::cast<ns::ClassSubT>(pA) == NULL ) 00296 00297 or 00298 00299 assert( pA->as<ns::ClassAB>() != NULL ) 00300 assert( pB->as<ns::ClassAB>() != NULL ) 00301 assert( pA->as<ns::ClassSubT>() == NULL ) 00302 00303 NOTE THAT UNLIKE dynamic_cast<> AND static_cast<> WE USE: 00304 00305 vl::cast<ns::ClassAB>(pB) 00306 00307 INSTEAD OF: 00308 00309 vl::cast<ns::ClassAB*>(pB) 00310 00311 REMARKS: 00312 00313 There is no need to say that, similarly to dynamic_cast<>, one should avoid using VL TypeInfo facilities 00314 inside "fast" loops otherwise they won't be that "fast" anymore! 00315 00316 ***/ 00317 00318 #endif