Panda3D
|
00001 // Filename: bamReader.h 00002 // Created by: jason (12Jun00) 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 __BAM_READER_ 00016 #define __BAM_READER_ 00017 00018 #include "pandabase.h" 00019 #include "pnotify.h" 00020 00021 #include "typedWritable.h" 00022 #include "typedWritableReferenceCount.h" 00023 #include "pointerTo.h" 00024 #include "datagramGenerator.h" 00025 #include "datagramIterator.h" 00026 #include "bamReaderParam.h" 00027 #include "bamEnums.h" 00028 #include "loaderOptions.h" 00029 #include "factory.h" 00030 #include "vector_int.h" 00031 #include "pset.h" 00032 #include "pmap.h" 00033 #include "dcast.h" 00034 #include "pipelineCyclerBase.h" 00035 #include "referenceCount.h" 00036 00037 #include <algorithm> 00038 00039 00040 // A handy macro for reading PointerToArrays. 00041 #define READ_PTA(Manager, source, Read_func, array) \ 00042 { \ 00043 void *t; \ 00044 if ((t = Manager->get_pta(source)) == (void*)NULL) \ 00045 { \ 00046 array = Read_func(Manager, source); \ 00047 Manager->register_pta(array.get_void_ptr()); \ 00048 } \ 00049 else \ 00050 { \ 00051 array.set_void_ptr(t); \ 00052 } \ 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Class : BamReaderAuxData 00057 // Description : Stores auxiliary data that may be piggybacked on the 00058 // BamReader during each object's read pass. To use 00059 // this, subclass BamReaderAuxData and add whatever 00060 // additional data you require. 00061 //////////////////////////////////////////////////////////////////// 00062 class EXPCL_PANDA_PGRAPH BamReaderAuxData : public TypedReferenceCount { 00063 public: 00064 INLINE BamReaderAuxData(); 00065 00066 public: 00067 virtual TypeHandle get_type() const { 00068 return get_class_type(); 00069 } 00070 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00071 static TypeHandle get_class_type() { 00072 return _type_handle; 00073 } 00074 00075 public: 00076 static void init_type() { 00077 TypedReferenceCount::init_type(); 00078 register_type(_type_handle, "BamReaderAuxData", 00079 TypedReferenceCount::get_class_type()); 00080 } 00081 00082 private: 00083 static TypeHandle _type_handle; 00084 }; 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Class : BamReader 00088 // Description : This is the fundamental interface for extracting 00089 // binary objects from a Bam file, as generated by a 00090 // BamWriter. 00091 // 00092 // A Bam file can be thought of as a linear collection 00093 // of objects. Each object is an instance of a class 00094 // that inherits, directly or indirectly, from 00095 // TypedWritable. The objects may include pointers to 00096 // other objects within the Bam file; the BamReader 00097 // automatically manages these (with help from code 00098 // within each class) and restores the pointers 00099 // correctly. 00100 // 00101 // This is the abstract interface and does not 00102 // specifically deal with disk files, but rather with a 00103 // DatagramGenerator of some kind, which is simply a 00104 // linear source of Datagrams. It is probably from a 00105 // disk file, but it might conceivably be streamed 00106 // directly from a network or some such nonsense. 00107 // 00108 // Bam files are most often used to store scene graphs 00109 // or subgraphs, and by convention they are given 00110 // filenames ending in the extension ".bam" when they 00111 // are used for this purpose. However, a Bam file may 00112 // store any arbitrary list of TypedWritable objects; 00113 // in this more general usage, they are given filenames 00114 // ending in ".boo" to differentiate them from the more 00115 // common scene graph files. 00116 // 00117 // See also BamFile, which defines a higher-level 00118 // interface to read and write Bam files on disk. 00119 //////////////////////////////////////////////////////////////////// 00120 class EXPCL_PANDA_PUTIL BamReader : public BamEnums { 00121 public: 00122 typedef Factory<TypedWritable> WritableFactory; 00123 static BamReader *const Null; 00124 static WritableFactory *const NullFactory; 00125 00126 PUBLISHED: 00127 // The primary interface for a caller. 00128 BamReader(DatagramGenerator *source = NULL, const Filename &name = ""); 00129 ~BamReader(); 00130 00131 void set_source(DatagramGenerator *source); 00132 00133 bool init(); 00134 00135 class AuxData; 00136 void set_aux_data(TypedWritable *obj, const string &name, AuxData *data); 00137 AuxData *get_aux_data(TypedWritable *obj, const string &name) const; 00138 00139 INLINE const Filename &get_filename() const; 00140 00141 INLINE const LoaderOptions &get_loader_options() const; 00142 INLINE void set_loader_options(const LoaderOptions &options); 00143 00144 TypedWritable *read_object(); 00145 bool read_object(TypedWritable *&ptr, ReferenceCount *&ref_ptr); 00146 00147 INLINE bool is_eof() const; 00148 bool resolve(); 00149 00150 bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer); 00151 00152 INLINE int get_file_major_ver() const; 00153 INLINE int get_file_minor_ver() const; 00154 INLINE BamEndian get_file_endian() const; 00155 00156 INLINE int get_current_major_ver() const; 00157 INLINE int get_current_minor_ver() const; 00158 00159 public: 00160 // Functions to support classes that read themselves from the Bam. 00161 00162 void read_pointer(DatagramIterator &scan); 00163 void read_pointers(DatagramIterator &scan, int count); 00164 void skip_pointer(DatagramIterator &scan); 00165 00166 void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler); 00167 void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler, 00168 void *extra_data); 00169 00170 void set_int_tag(const string &tag, int value); 00171 int get_int_tag(const string &tag) const; 00172 00173 void set_aux_tag(const string &tag, BamReaderAuxData *value); 00174 BamReaderAuxData *get_aux_tag(const string &tag) const; 00175 00176 void register_finalize(TypedWritable *whom); 00177 00178 typedef TypedWritable *(*ChangeThisFunc)(TypedWritable *object, BamReader *manager); 00179 typedef PT(TypedWritableReferenceCount) (*ChangeThisRefFunc)(TypedWritableReferenceCount *object, BamReader *manager); 00180 void register_change_this(ChangeThisFunc func, TypedWritable *whom); 00181 void register_change_this(ChangeThisRefFunc func, TypedWritableReferenceCount *whom); 00182 00183 void finalize_now(TypedWritable *whom); 00184 00185 void *get_pta(DatagramIterator &scan); 00186 void register_pta(void *ptr); 00187 00188 TypeHandle read_handle(DatagramIterator &scan); 00189 00190 INLINE VirtualFile *get_file(); 00191 INLINE streampos get_file_pos(); 00192 00193 public: 00194 INLINE static WritableFactory *get_factory(); 00195 private: 00196 INLINE static void create_factory(); 00197 00198 private: 00199 class PointerReference; 00200 00201 void free_object_ids(DatagramIterator &scan); 00202 int read_object_id(DatagramIterator &scan); 00203 int read_pta_id(DatagramIterator &scan); 00204 int p_read_object(); 00205 bool resolve_object_pointers(TypedWritable *object, PointerReference &pref); 00206 bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids, 00207 bool require_fully_complete); 00208 void finalize(); 00209 00210 INLINE bool get_datagram(Datagram &datagram); 00211 00212 public: 00213 // Inherit from this class to piggyback additional temporary data on 00214 // the bamReader (via set_aux_data() and get_aux_data()) for any 00215 // particular objects during the bam reading process. 00216 class AuxData : public ReferenceCount { 00217 public: 00218 INLINE AuxData(); 00219 virtual ~AuxData(); 00220 }; 00221 00222 private: 00223 static WritableFactory *_factory; 00224 00225 DatagramGenerator *_source; 00226 bool _needs_init; 00227 00228 bool _long_object_id; 00229 bool _long_pta_id; 00230 00231 // This maps the type index numbers encountered within the Bam file 00232 // to actual TypeHandles. 00233 typedef phash_map<int, TypeHandle, int_hash> IndexMap; 00234 IndexMap _index_map; 00235 00236 // This is the filename of the BAM, or empty string if not in a file. 00237 Filename _filename; 00238 00239 LoaderOptions _loader_options; 00240 00241 // This maps the object ID numbers encountered within the Bam file 00242 // to the actual pointers of the corresponding generated objects. 00243 class CreatedObj { 00244 public: 00245 INLINE CreatedObj(); 00246 INLINE ~CreatedObj(); 00247 INLINE void set_ptr(TypedWritable *ptr, ReferenceCount *ref_ptr); 00248 00249 public: 00250 bool _created; 00251 TypedWritable *_ptr; 00252 ReferenceCount *_ref_ptr; 00253 ChangeThisFunc _change_this; 00254 ChangeThisRefFunc _change_this_ref; 00255 }; 00256 typedef phash_map<int, CreatedObj, int_hash> CreatedObjs; 00257 CreatedObjs _created_objs; 00258 // This is the iterator into the above map for the object we are 00259 // currently reading in p_read_object(). It is carefully maintained 00260 // during recursion. We need this so we can associate 00261 // read_pointer() calls with the proper objects. 00262 CreatedObjs::iterator _now_creating; 00263 // This is the pointer to the current PipelineCycler we are reading, 00264 // if we are within a read_cdata() call. 00265 PipelineCyclerBase *_reading_cycler; 00266 00267 // This is the reverse lookup into the above map. 00268 typedef phash_map<const TypedWritable *, vector_int, pointer_hash> CreatedObjsByPointer; 00269 CreatedObjsByPointer _created_objs_by_pointer; 00270 00271 // This records all the objects that still need their pointers 00272 // completed, along with the object ID's of the pointers they need, 00273 // in the order in which read_pointer() was called, so that we may 00274 // call the appropriate complete_pointers() later. 00275 typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers; 00276 typedef pmap<string, int> IntTags; 00277 typedef pmap<string, PT(BamReaderAuxData) > AuxTags; 00278 class PointerReference { 00279 public: 00280 vector_int _objects; 00281 CyclerPointers _cycler_pointers; 00282 IntTags _int_tags; 00283 AuxTags _aux_tags; 00284 }; 00285 typedef phash_map<int, PointerReference, int_hash> ObjectPointers; 00286 ObjectPointers _object_pointers; 00287 00288 // This is the number of extra objects that must still be read (and 00289 // saved in the _created_objs map) before returning from 00290 // read_object(). It is only used when read bam versions prior to 00291 // 6.20. 00292 int _num_extra_objects; 00293 00294 // The current nesting level. We are not done reading an object 00295 // until we return to our starting nesting level. It is only used 00296 // when reading bam versions of 6.20 or higher. 00297 int _nesting_level; 00298 00299 // This is the set of all objects that registered themselves for 00300 // finalization. 00301 typedef phash_set<TypedWritable *, pointer_hash> Finalize; 00302 Finalize _finalize_list; 00303 00304 // These are used by get_pta() and register_pta() to unify multiple 00305 // references to the same PointerToArray. 00306 typedef phash_map<int, void *, int_hash> PTAMap; 00307 PTAMap _pta_map; 00308 int _pta_id; 00309 00310 // This is used internally to record all of the new types created 00311 // on-the-fly to satisfy bam requirements. We keep track of this 00312 // just so we can suppress warning messages from attempts to create 00313 // objects of these types. 00314 typedef phash_set<TypeHandle> NewTypes; 00315 static NewTypes _new_types; 00316 00317 // This is used in support of set_aux_data() and get_aux_data(). 00318 typedef pmap<string, PT(AuxData)> AuxDataNames; 00319 typedef phash_map<TypedWritable *, AuxDataNames, pointer_hash> AuxDataTable; 00320 AuxDataTable _aux_data; 00321 00322 int _file_major, _file_minor; 00323 BamEndian _file_endian; 00324 static const int _cur_major; 00325 static const int _cur_minor; 00326 }; 00327 00328 typedef BamReader::WritableFactory WritableFactory; 00329 00330 // Useful function for taking apart the Factory Params in the static 00331 // functions that need to be defined in each writable class that will 00332 // be generated by a factory. Sets the DatagramIterator and the 00333 // BamReader pointers. 00334 INLINE void 00335 parse_params(const FactoryParams ¶ms, 00336 DatagramIterator &scan, BamReader *&manager); 00337 00338 #include "bamReader.I" 00339 00340 #endif