00001 // Filename: typedObject.h 00002 // Created by: drose (11May01) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef TYPEDOBJECT_H 00016 #define TYPEDOBJECT_H 00017 00018 #include "dtoolbase.h" 00019 00020 #include "typeHandle.h" 00021 #include "register_type.h" 00022 #include "memoryBase.h" 00023 00024 #include <set> 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Class : TypedObject 00028 // Description : This is an abstract class that all classes which 00029 // use TypeHandle, and also provide virtual functions to 00030 // support polymorphism, should inherit from. Each 00031 // derived class should define get_type(), which should 00032 // return the specific type of the derived class. 00033 // Inheriting from this automatically provides support 00034 // for is_of_type() and is_exact_type(). 00035 // 00036 // All classes that inherit directly or indirectly from 00037 // TypedObject should redefine get_type() and 00038 // force_init_type(), as shown below. Some classes that 00039 // do not inherit from TypedObject may still declare 00040 // TypeHandles for themselves by defining methods called 00041 // get_class_type() and init_type(). Classes such as 00042 // these may serve as base classes, but the dynamic type 00043 // identification system will be limited. Classes that 00044 // do not inherit from TypedObject need not define the 00045 // virtual functions get_type() and force_init_type() 00046 // (or any other virtual functions). 00047 // 00048 // There is a specific layout for defining the 00049 // overrides from this class. Keeping the definitions 00050 // formatted just like these examples will allow 00051 // someone in the future to use a sed (or similar) 00052 // script to make global changes, if necessary. Avoid 00053 // rearranging the braces or the order of the functions 00054 // unless you're ready to change them in every file all 00055 // at once. 00056 // 00057 // What follows are some examples that can be used in 00058 // new classes that you create. 00059 // 00060 // @par In the class definition (.h file): 00061 // @code 00062 // public: 00063 // static TypeHandle get_class_type() { 00064 // return _type_handle; 00065 // } 00066 // static void init_type() { 00067 // <<<BaseClassOne>>>::init_type(); 00068 // <<<BaseClassTwo>>>::init_type(); 00069 // <<<BaseClassN>>>::init_type(); 00070 // register_type(_type_handle, "<<<ThisClassStringName>>>", 00071 // <<<BaseClassOne>>>::get_class_type(), 00072 // <<<BaseClassTwo>>>::get_class_type(), 00073 // <<<BaseClassN>>>::get_class_type()); 00074 // } 00075 // virtual TypeHandle get_type() const { 00076 // return get_class_type(); 00077 // } 00078 // virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00079 // 00080 // private: 00081 // static TypeHandle _type_handle; 00082 // @endcode 00083 // 00084 // @par In the class .cxx file: 00085 // @code 00086 // TypeHandle <<<ThisClassStringName>>>::_type_handle; 00087 // @endcode 00088 // 00089 // @par In the class config_<<<PackageName>>>.cxx file: 00090 // @code 00091 // ConfigureFn(config_<<<PackageName>>>) { 00092 // <<<ClassOne>>>::init_type(); 00093 // <<<ClassTwo>>>::init_type(); 00094 // <<<ClassN>>>::init_type(); 00095 // } 00096 // @endcode 00097 //////////////////////////////////////////////////////////////////// 00098 class EXPCL_DTOOL TypedObject : public MemoryBase { 00099 public: 00100 INLINE TypedObject(); 00101 INLINE TypedObject(const TypedObject ©); 00102 INLINE void operator = (const TypedObject ©); 00103 00104 PUBLISHED: 00105 // A virtual destructor is just a good idea. 00106 virtual ~TypedObject(); 00107 00108 // Derived classes should override this function to return 00109 // get_class_type(). 00110 virtual TypeHandle get_type() const=0; 00111 00112 INLINE int get_type_index() const; 00113 INLINE bool is_of_type(TypeHandle handle) const; 00114 INLINE bool is_exact_type(TypeHandle handle) const; 00115 00116 public: 00117 INLINE int get_best_parent_from_Set(const std::set<int> &) const; 00118 00119 // Derived classes should override this function to call 00120 // init_type(). It will only be called in error situations when the 00121 // type was for some reason not properly initialized. 00122 virtual TypeHandle force_init_type()=0; 00123 00124 // This pair of methods exists mainly for the convenience of 00125 // unambiguous upcasting. Interrogate generates code to call this 00126 // method instead of making an explicit cast to (TypedObject *); 00127 // this allows classes who multiply inherit from TypedObejct to 00128 // override these methods and disambiguate the cast. It doesn't 00129 // have to be a virtual method, since this is just a static upcast. 00130 INLINE TypedObject *as_typed_object(); 00131 INLINE const TypedObject *as_typed_object() const; 00132 00133 public: 00134 static TypeHandle get_class_type() { 00135 return _type_handle; 00136 } 00137 static void init_type(); 00138 00139 private: 00140 static TypeHandle _type_handle; 00141 }; 00142 00143 #include "typedObject.I" 00144 00145 #endif