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