Panda3D

Loading...
Searching...
No Matches
bamReader.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file bamReader.h
10 * @author jason
11 * @date 2000-06-12
12 */
13
14#ifndef __BAM_READER_
15#define __BAM_READER_
16
17#include "pandabase.h"
18#include "pnotify.h"
19
20#include "typedWritable.h"
21#include "typedWritableReferenceCount.h"
22#include "pointerTo.h"
23#include "datagramGenerator.h"
24#include "datagramIterator.h"
25#include "bamReaderParam.h"
26#include "bamEnums.h"
27#include "subfileInfo.h"
28#include "loaderOptions.h"
29#include "factory.h"
30#include "vector_int.h"
31#include "pset.h"
32#include "pmap.h"
33#include "pdeque.h"
34#include "dcast.h"
35#include "pipelineCyclerBase.h"
36#include "referenceCount.h"
37
38#include <algorithm>
39
40
41// A handy macro for reading PointerToArrays.
42#define READ_PTA(Manager, source, Read_func, array) \
43{ \
44 void *t; \
45 if ((t = Manager->get_pta(source)) == nullptr) \
46 { \
47 array = Read_func(Manager, source); \
48 Manager->register_pta(array.get_void_ptr()); \
49 } \
50 else \
51 { \
52 array.set_void_ptr(t); \
53 } \
54}
55
56/**
57 * Stores auxiliary data that may be piggybacked on the BamReader during each
58 * object's read pass. To use this, subclass BamReaderAuxData and add
59 * whatever additional data you require.
60 */
61 class EXPCL_PANDA_PUTIL BamReaderAuxData : public TypedReferenceCount {
62 public:
63 INLINE BamReaderAuxData();
64
65 public:
66 virtual TypeHandle get_type() const {
67 return get_class_type();
68 }
69 virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
70 static TypeHandle get_class_type() {
71 return _type_handle;
72 }
73
74 public:
75 static void init_type() {
76 TypedReferenceCount::init_type();
77 register_type(_type_handle, "BamReaderAuxData",
78 TypedReferenceCount::get_class_type());
79 }
80
81 private:
82 static TypeHandle _type_handle;
83};
84
85/**
86 * This is the fundamental interface for extracting binary objects from a Bam
87 * file, as generated by a BamWriter.
88 *
89 * A Bam file can be thought of as a linear collection of objects. Each
90 * object is an instance of a class that inherits, directly or indirectly,
91 * from TypedWritable. The objects may include pointers to other objects
92 * within the Bam file; the BamReader automatically manages these (with help
93 * from code within each class) and restores the pointers correctly.
94 *
95 * This is the abstract interface and does not specifically deal with disk
96 * files, but rather with a DatagramGenerator of some kind, which is simply a
97 * linear source of Datagrams. It is probably from a disk file, but it might
98 * conceivably be streamed directly from a network or some such nonsense.
99 *
100 * Bam files are most often used to store scene graphs or subgraphs, and by
101 * convention they are given filenames ending in the extension ".bam" when
102 * they are used for this purpose. However, a Bam file may store any
103 * arbitrary list of TypedWritable objects; in this more general usage, they
104 * are given filenames ending in ".boo" to differentiate them from the more
105 * common scene graph files.
106 *
107 * See also BamFile, which defines a higher-level interface to read and write
108 * Bam files on disk.
109 */
110 class EXPCL_PANDA_PUTIL BamReader : public BamEnums {
111 public:
112 typedef Factory<TypedWritable> WritableFactory;
113 static BamReader *const Null;
114 static WritableFactory *const NullFactory;
115
116PUBLISHED:
117 // The primary interface for a caller.
118 explicit BamReader(DatagramGenerator *source = nullptr);
119 ~BamReader();
120
121 void set_source(DatagramGenerator *source);
122 INLINE DatagramGenerator *get_source();
123
124 bool init();
125
126 class AuxData;
127 void set_aux_data(TypedWritable *obj, const std::string &name, AuxData *data);
128 AuxData *get_aux_data(TypedWritable *obj, const std::string &name) const;
129
130 INLINE const Filename &get_filename() const;
131
132 INLINE const LoaderOptions &get_loader_options() const;
133 INLINE void set_loader_options(const LoaderOptions &options);
134
135 BLOCKING TypedWritable *read_object();
136 BLOCKING bool read_object(TypedWritable *&ptr, ReferenceCount *&ref_ptr);
137
138 INLINE bool is_eof() const;
139 bool resolve();
140
141 bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer);
142
143 INLINE int get_file_major_ver() const;
144 INLINE int get_file_minor_ver() const;
145 INLINE BamEndian get_file_endian() const;
146 INLINE bool get_file_stdfloat_double() const;
147
148 INLINE int get_current_major_ver() const;
149 INLINE int get_current_minor_ver() const;
150
151 EXTENSION(PyObject *get_file_version() const);
152
153PUBLISHED:
154 MAKE_PROPERTY(source, get_source, set_source);
155 MAKE_PROPERTY(filename, get_filename);
156 MAKE_PROPERTY(loader_options, get_loader_options, set_loader_options);
157
158 MAKE_PROPERTY(file_version, get_file_version);
159 MAKE_PROPERTY(file_endian, get_file_endian);
160 MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double);
161
162 public:
163 // Functions to support classes that read themselves from the Bam.
164
165 bool read_pointer(DatagramIterator &scan);
166 void read_pointers(DatagramIterator &scan, int count);
167 void skip_pointer(DatagramIterator &scan);
168
169 void read_file_data(SubfileInfo &info);
170
171 void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler);
172 void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler,
173 void *extra_data);
174
175 void set_int_tag(const std::string &tag, int value);
176 int get_int_tag(const std::string &tag) const;
177
178 void set_aux_tag(const std::string &tag, BamReaderAuxData *value);
179 BamReaderAuxData *get_aux_tag(const std::string &tag) const;
180
181 void register_finalize(TypedWritable *whom);
182
183 typedef TypedWritable *(*ChangeThisFunc)(TypedWritable *object, BamReader *manager);
184 typedef PT(TypedWritableReferenceCount) (*ChangeThisRefFunc)(TypedWritableReferenceCount *object, BamReader *manager);
185 void register_change_this(ChangeThisFunc func, TypedWritable *whom);
186 void register_change_this(ChangeThisRefFunc func, TypedWritableReferenceCount *whom);
187
188 void finalize_now(TypedWritable *whom);
189
190 void *get_pta(DatagramIterator &scan);
191 void register_pta(void *ptr);
192
193 TypeHandle read_handle(DatagramIterator &scan);
194
195 INLINE const FileReference *get_file();
196 INLINE VirtualFile *get_vfile();
197 INLINE std::streampos get_file_pos();
198
199 public:
200 INLINE static void register_factory(TypeHandle type, WritableFactory::CreateFunc *func,
201 void *user_data = nullptr);
202 INLINE static WritableFactory *get_factory();
203
204PUBLISHED:
205 EXTENSION(static void register_factory(TypeHandle handle, PyObject *func));
206
207 private:
208 INLINE static void create_factory();
209
210 private:
211 class PointerReference;
212
213 void free_object_ids(DatagramIterator &scan);
214 int read_object_id(DatagramIterator &scan);
215 int read_pta_id(DatagramIterator &scan);
216 int p_read_object();
217 bool resolve_object_pointers(TypedWritable *object, PointerReference &pref);
218 bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids,
219 bool require_fully_complete);
220 void finalize();
221
222 INLINE bool get_datagram(Datagram &datagram);
223
224 public:
225 // Inherit from this class to piggyback additional temporary data on the
226 // bamReader (via set_aux_data() and get_aux_data()) for any particular
227 // objects during the bam reading process.
228 class AuxData : public ReferenceCount {
229 public:
230 INLINE AuxData();
231 virtual ~AuxData() = default;
232 };
233
234 private:
235 static WritableFactory *_factory;
236
237 DatagramGenerator *_source;
238 bool _needs_init;
239
240 bool _long_object_id;
241 bool _long_pta_id;
242
243 // This maps the type index numbers encountered within the Bam file to
244 // actual TypeHandles.
245 typedef phash_map<int, TypeHandle, int_hash> IndexMap;
246 IndexMap _index_map;
247
248 LoaderOptions _loader_options;
249
250 // This maps the object ID numbers encountered within the Bam file to the
251 // actual pointers of the corresponding generated objects.
252 class CreatedObj {
253 public:
254 INLINE CreatedObj();
255 INLINE ~CreatedObj();
256 INLINE void set_ptr(TypedWritable *ptr, ReferenceCount *ref_ptr);
257
258 public:
259 bool _created;
260 TypedWritable *_ptr;
261 ReferenceCount *_ref_ptr;
262 ChangeThisFunc _change_this;
263 ChangeThisRefFunc _change_this_ref;
264 };
265 typedef phash_map<int, CreatedObj, int_hash> CreatedObjs;
266 CreatedObjs _created_objs;
267 // This is the iterator into the above map for the object we are currently
268 // reading in p_read_object(). It is carefully maintained during recursion.
269 // We need this so we can associate read_pointer() calls with the proper
270 // objects.
271 CreatedObjs::iterator _now_creating;
272 // This is the pointer to the current PipelineCycler we are reading, if we
273 // are within a read_cdata() call.
274 PipelineCyclerBase *_reading_cycler;
275
276 // This is the reverse lookup into the above map.
277 typedef phash_map<const TypedWritable *, vector_int, pointer_hash> CreatedObjsByPointer;
278 CreatedObjsByPointer _created_objs_by_pointer;
279
280 // This records all the objects that still need their pointers completed,
281 // along with the object ID's of the pointers they need, in the order in
282 // which read_pointer() was called, so that we may call the appropriate
283 // complete_pointers() later.
284 typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers;
285 typedef pmap<std::string, int> IntTags;
286 typedef pmap<std::string, PT(BamReaderAuxData) > AuxTags;
287 class PointerReference {
288 public:
289 vector_int _objects;
290 CyclerPointers _cycler_pointers;
291 IntTags _int_tags;
292 AuxTags _aux_tags;
293 };
294 typedef phash_map<int, PointerReference, int_hash> ObjectPointers;
295 ObjectPointers _object_pointers;
296
297 // This is the number of extra objects that must still be read (and saved in
298 // the _created_objs map) before returning from read_object(). It is only
299 // used when read bam versions prior to 6.20.
300 int _num_extra_objects;
301
302 // The current nesting level. We are not done reading an object until we
303 // return to our starting nesting level. It is only used when reading bam
304 // versions of 6.20 or higher.
305 int _nesting_level;
306
307 // This is the set of all objects that registered themselves for
308 // finalization.
309 typedef phash_set<TypedWritable *, pointer_hash> Finalize;
310 Finalize _finalize_list;
311
312 // These are used by get_pta() and register_pta() to unify multiple
313 // references to the same PointerToArray.
314 typedef phash_map<int, void *, int_hash> PTAMap;
315 PTAMap _pta_map;
316 int _pta_id;
317
318 // This is a queue of the currently-pending file data blocks that we have
319 // recently encountered in the stream and still expect a subsequent object
320 // to request.
321 typedef pdeque<SubfileInfo> FileDataRecords;
322 FileDataRecords _file_data_records;
323
324 // This is used internally to record all of the new types created on-the-fly
325 // to satisfy bam requirements. We keep track of this just so we can
326 // suppress warning messages from attempts to create objects of these types.
327 typedef phash_set<TypeHandle> NewTypes;
328 static NewTypes _new_types;
329
330 // This is used in support of set_aux_data() and get_aux_data().
331 typedef pmap<std::string, PT(AuxData)> AuxDataNames;
332 typedef phash_map<TypedWritable *, AuxDataNames, pointer_hash> AuxDataTable;
333 AuxDataTable _aux_data;
334
335 int _file_major, _file_minor;
336 BamEndian _file_endian;
337 bool _file_stdfloat_double;
338 static const int _cur_major;
339 static const int _cur_minor;
340};
341
342 typedef BamReader::WritableFactory WritableFactory;
343
344// Useful function for taking apart the Factory Params in the static functions
345// that need to be defined in each writable class that will be generated by a
346// factory. Sets the DatagramIterator and the BamReader pointers.
347INLINE void
348 parse_params(const FactoryParams &params,
349 DatagramIterator &scan, BamReader *&manager);
350
351#include "bamReader.I"
352
353#endif
bamEnums.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bamReaderParam.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bamReader.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
parse_params
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition bamReader.I:275
BamEnums
This class exists just to provide scoping for the enums shared by BamReader and BamWriter.
Definition bamEnums.h:23
BamEnums::BamEndian
BamEndian
This defines an enumerated type used to represent the endianness of certain numeric values stored in ...
Definition bamEnums.h:32
BamReaderAuxData
Stores auxiliary data that may be piggybacked on the BamReader during each object's read pass.
Definition bamReader.h:61
BamReader::AuxData
Definition bamReader.h:228
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
BamReader::register_finalize
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
Definition bamReader.cxx:808
BamReader::read_handle
TypeHandle read_handle(DatagramIterator &scan)
Reads a TypeHandle out of the Datagram.
Definition bamReader.cxx:514
BamReader::change_pointer
bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer)
Indicates that an object recently read from the bam stream should be replaced with a new object.
Definition bamReader.cxx:464
BamReader::read_pointers
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
Definition bamReader.cxx:653
BamReader::is_eof
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
Definition bamReader.I:66
BamReader::read_file_data
void read_file_data(SubfileInfo &info)
Reads a block of auxiliary file data from the Bam file.
Definition bamReader.cxx:677
BamReader::get_current_minor_ver
int get_current_minor_ver() const
Returns the minor version number of Bam files supported by the current code base.
Definition bamReader.I:124
BamReader::get_int_tag
int get_int_tag(const std::string &tag) const
Returns the value previously set via set_int_tag().
Definition bamReader.cxx:744
BamReader::register_pta
void register_pta(void *ptr)
The second part of read_pta(), this should be called with the pointer to the array that was read in a...
Definition bamReader.cxx:964
BamReader::get_file
const FileReference * get_file()
Returns the FileReference that provides the source for these datagrams, if any, or NULL if the datagr...
Definition bamReader.I:133
BamReader::skip_pointer
void skip_pointer(DatagramIterator &scan)
Reads and discards a pointer value from the Bam file.
Definition bamReader.cxx:665
BamReader::get_file_stdfloat_double
get_file_stdfloat_double
Returns true if the file stores all "standard" floats as 64-bit doubles, or false if they are 32-bit ...
Definition bamReader.h:160
BamReader::get_aux_tag
BamReaderAuxData * get_aux_tag(const std::string &tag) const
Returns the value previously set via set_aux_tag().
Definition bamReader.cxx:785
BamReader::get_source
get_source
Returns the current source of the BamReader as set by set_source() or the constructor.
Definition bamReader.h:154
BamReader::finalize_now
void finalize_now(TypedWritable *whom)
Forces the finalization of a particular object.
Definition bamReader.cxx:897
BamReader::resolve
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
Definition bamReader.cxx:325
BamReader::get_file_major_ver
int get_file_major_ver() const
Returns the major version number of the Bam file currently being read.
Definition bamReader.I:75
BamReader::set_aux_tag
void set_aux_tag(const std::string &tag, BamReaderAuxData *value)
Allows the creating object to store a temporary data value on the BamReader.
Definition bamReader.cxx:772
BamReader::init
bool init()
Initializes the BamReader prior to reading any objects from its source.
Definition bamReader.cxx:85
BamReader::set_aux_data
void set_aux_data(TypedWritable *obj, const std::string &name, AuxData *data)
Associates an arbitrary block of data with the indicated object (or NULL), and the indicated name.
Definition bamReader.cxx:167
BamReader::get_filename
get_filename
If a BAM is a file, then the BamReader should contain the name of the file.
Definition bamReader.h:155
BamReader::get_pta
void * get_pta(DatagramIterator &scan)
This function works in conjection with register_pta(), below, to read a PointerToArray (PTA) from the...
Definition bamReader.cxx:931
BamReader::read_object
TypedWritable * read_object()
Reads a single object from the Bam file.
Definition bamReader.cxx:224
BamReader::register_change_this
void register_change_this(ChangeThisFunc func, TypedWritable *whom)
Called by an object reading itself from the bam file to indicate that the object pointer that will be...
Definition bamReader.cxx:835
BamReader::register_factory
static void register_factory(TypeHandle type, WritableFactory::CreateFunc *func, void *user_data=nullptr)
Registers a factory function that is called when an object of the given type is encountered within th...
Definition bamReader.I:169
BamReader::get_file_pos
std::streampos get_file_pos()
Returns the current file position within the data stream, if any, or 0 if the file position is not me...
Definition bamReader.I:157
BamReader::set_loader_options
set_loader_options
Specifies the LoaderOptions for this BamReader.
Definition bamReader.h:156
BamReader::get_vfile
VirtualFile * get_vfile()
Returns the VirtualFile that provides the source for these datagrams, if any, or NULL if the datagram...
Definition bamReader.I:143
BamReader::set_int_tag
void set_int_tag(const std::string &tag, int value)
Allows the creating object to store a temporary data value on the BamReader.
Definition bamReader.cxx:731
BamReader::read_pointer
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition bamReader.cxx:610
BamReader::get_loader_options
get_loader_options
Returns the LoaderOptions passed to the loader when the model was requested, if any.
Definition bamReader.h:156
BamReader::get_file_minor_ver
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition bamReader.I:83
BamReader::get_aux_data
AuxData * get_aux_data(TypedWritable *obj, const std::string &name) const
Returns the pointer previously associated with the bam reader by a previous call to set_aux_data(),...
Definition bamReader.cxx:189
BamReader::get_file_endian
get_file_endian
Returns the endian preference indicated by the Bam file currently being read.
Definition bamReader.h:159
BamReader::read_cdata
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Definition bamReader.cxx:695
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
BamReader::set_source
set_source
Changes the source of future datagrams for this BamReader.
Definition bamReader.h:154
BamReader::get_current_major_ver
int get_current_major_ver() const
Returns the major version number of Bam files supported by the current code base.
Definition bamReader.I:114
DatagramGenerator
This class defines the abstract interace to any source of datagrams, whether it be from a file or fro...
Definition datagramGenerator.h:30
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition datagramIterator.h:30
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition factoryParams.h:36
FileReference
Keeps a reference-counted pointer to a file on disk.
Definition fileReference.h:26
Filename
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
LoaderOptions
Specifies parameters that may be passed to the loader.
Definition loaderOptions.h:23
ReferenceCount
A base class for all things that want to be reference-counted.
Definition referenceCount.h:38
SubfileInfo
This class records a particular byte sub-range within an existing file on disk.
Definition subfileInfo.h:26
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
TypedWritableReferenceCount
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
Definition typedWritableReferenceCount.h:31
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition typedWritable.h:35
VirtualFile
The abstract base class for a file or directory within the VirtualFileSystem.
Definition virtualFile.h:35
datagramGenerator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagramIterator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
factory.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
loaderOptions.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pandabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pdeque.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pipelineCyclerBase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pmap.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pnotify.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pointerTo.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pset.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
referenceCount.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
register_type
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition register_type.I:22
subfileInfo.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
typedWritableReferenceCount.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
typedWritable.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
vector_int.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.