28 BamReader *
const BamReader::Null =
nullptr;
31 BamReader::NewTypes BamReader::_new_types;
33 const int BamReader::_cur_major = _bam_major_ver;
34 const int BamReader::_cur_minor = _bam_minor_ver;
45 _num_extra_objects = 0;
47 _now_creating = _created_objs.end();
48 _reading_cycler =
nullptr;
50 _long_object_id =
false;
60 nassertv(_num_extra_objects == 0);
61 nassertv(_nesting_level == 0);
71 if (_needs_init && _source !=
nullptr) {
72 bool success =
init();
86 nassertr(_source !=
nullptr,
false);
87 nassertr(_needs_init,
false);
91 if (_source->is_error()) {
95 if (!get_datagram(header)) {
97 <<
"Unable to read Bam header.\n";
108 if (_file_major != _bam_major_ver ||
109 _file_minor < _bam_first_minor_ver ||
110 _file_minor > _bam_minor_ver) {
112 <<
"Bam file is version " << _file_major <<
"." << _file_minor
115 if (_bam_minor_ver == _bam_first_minor_ver) {
117 <<
"This program can only load version " 118 << _bam_major_ver <<
"." << _bam_first_minor_ver <<
" bams.\n";
121 <<
"This program can only load version " 122 << _bam_major_ver <<
"." << _bam_first_minor_ver <<
" through " 123 << _bam_major_ver <<
"." << _bam_minor_ver <<
" bams.\n";
129 _file_endian = (BamEndian)scan.
get_uint8();
131 _file_stdfloat_double =
false;
132 if (_file_minor >= 27) {
133 _file_stdfloat_double = scan.
get_bool();
138 <<
"Bam header is too short.\n";
168 if (data ==
nullptr) {
169 AuxDataTable::iterator ti = _aux_data.find(obj);
170 if (ti != _aux_data.end()) {
179 _aux_data[obj][name] = data;
190 AuxDataTable::const_iterator ti = _aux_data.find(obj);
191 if (ti != _aux_data.end()) {
193 AuxDataNames::const_iterator ni = names.find(name);
194 if (ni != names.end()) {
248 nassertr(_num_extra_objects == 0,
false);
250 int start_level = _nesting_level;
253 int object_id = p_read_object();
261 while (_num_extra_objects > 0) {
263 _num_extra_objects--;
268 while (_nesting_level > start_level) {
274 if (object_id == 0) {
275 if (bam_cat.is_spam()) {
277 <<
"Returning false\n";
282 CreatedObjs::iterator oi = _created_objs.find(object_id);
284 if (oi == _created_objs.end()) {
286 <<
"Undefined object encountered!\n";
290 CreatedObj &created_obj = (*oi).second;
291 ptr = created_obj._ptr;
292 ref_ptr = created_obj._ref_ptr;
294 if (bam_cat.is_spam()) {
295 if (ptr !=
nullptr) {
297 <<
"Returning object of type " << ptr->get_type() <<
"\n";
300 if (created_obj._change_this !=
nullptr ||
301 created_obj._change_this_ref !=
nullptr) {
303 <<
"Returning pointer to " << ptr->get_type()
304 <<
" that might change.\n";
327 bool any_completed_this_pass;
330 if (bam_cat.is_spam()) {
332 <<
"resolve pass begin\n";
334 all_completed =
true;
335 any_completed_this_pass =
false;
337 ObjectPointers::iterator oi;
338 oi = _object_pointers.begin();
339 while (oi != _object_pointers.end()) {
340 int object_id = (*oi).first;
341 PointerReference &pref = (*oi).second;
343 CreatedObjs::iterator ci = _created_objs.find(object_id);
344 nassertr(ci != _created_objs.end(),
false);
346 CreatedObj &created_obj = (*ci).second;
352 CreatedObjs::iterator was_creating = _now_creating;
355 if (resolve_object_pointers(object_ptr, pref)) {
359 ObjectPointers::iterator old = oi;
361 _object_pointers.erase(old);
362 any_completed_this_pass =
true;
365 if (created_obj._change_this_ref !=
nullptr) {
368 nassertr(created_obj._ref_ptr ==
nullptr || created_obj._ref_ptr == object_ref_ptr,
false);
370 if (new_ptr != object_ref_ptr) {
372 vector_int &old_refs = _created_objs_by_pointer[object_ptr];
373 vector_int &new_refs = _created_objs_by_pointer[new_ptr];
374 for (vector_int::const_iterator oi = old_refs.begin();
375 oi != old_refs.end();
377 new_refs.push_back(*oi);
379 _created_objs_by_pointer.erase(object_ptr);
383 _finalize_list.erase(object_ptr);
385 created_obj.set_ptr(new_ptr, new_ptr);
386 created_obj._change_this =
nullptr;
387 created_obj._change_this_ref =
nullptr;
389 }
else if (created_obj._change_this !=
nullptr) {
391 TypedWritable *new_ptr = created_obj._change_this(object_ptr,
this);
392 if (new_ptr != object_ptr) {
394 vector_int &old_refs = _created_objs_by_pointer[object_ptr];
395 vector_int &new_refs = _created_objs_by_pointer[new_ptr];
396 for (vector_int::const_iterator oi = old_refs.begin();
397 oi != old_refs.end();
399 new_refs.push_back(*oi);
401 _created_objs_by_pointer.erase(object_ptr);
405 _finalize_list.erase(object_ptr);
408 created_obj._change_this =
nullptr;
409 created_obj._change_this_ref =
nullptr;
415 all_completed =
false;
418 _now_creating = was_creating;
421 if (bam_cat.is_spam()) {
423 <<
"resolve pass end: all_completed = " << all_completed
424 <<
" any_completed_this_pass = " << any_completed_this_pass
427 }
while (!all_completed && any_completed_this_pass);
436 ObjectPointers::const_iterator oi;
437 for (oi = _object_pointers.begin();
438 oi != _object_pointers.end();
440 int object_id = (*oi).first;
441 CreatedObjs::iterator ci = _created_objs.find(object_id);
442 nassertr(ci != _created_objs.end(),
false);
443 CreatedObj &created_obj = (*ci).second;
447 <<
"Unable to complete " << object_ptr->get_type() <<
"\n";
451 return all_completed;
465 if (orig_pointer == new_pointer) {
468 CreatedObjsByPointer::iterator ci = _created_objs_by_pointer.find(orig_pointer);
469 if (ci == _created_objs_by_pointer.end()) {
474 if (bam_cat.is_spam()) {
476 <<
"change_pointer(" << (
void *)orig_pointer <<
", " 477 << (
void *)new_pointer <<
") (" << new_pointer->get_type() <<
")\n";
480 const vector_int &old_refs = (*ci).second;
481 vector_int &new_refs = _created_objs_by_pointer[new_pointer];
483 for (vector_int::const_iterator oi = old_refs.begin();
484 oi != old_refs.end();
486 int object_id = (*oi);
488 CreatedObjs::iterator ci = _created_objs.find(object_id);
489 nassertr(ci != _created_objs.end(),
false);
490 nassertr((*ci).second._ptr == orig_pointer,
false);
494 new_refs.push_back(object_id);
497 _created_objs_by_pointer.erase(ci);
500 Finalize::iterator fi = _finalize_list.find((
TypedWritable *)orig_pointer);
501 if (fi != _finalize_list.end()) {
503 _finalize_list.erase(fi);
529 return TypeHandle::none();
532 IndexMap::const_iterator mi = _index_map.find(
id);
533 if (mi != _index_map.end()) {
546 bool new_type =
false;
549 if (type == TypeHandle::none()) {
555 <<
"Bam file '" <<
get_filename() <<
"' contains objects of unknown type: " 558 _new_types.insert(type);
562 int num_parent_classes = scan.
get_uint8();
563 for (
int i = 0; i < num_parent_classes; i++) {
569 if (bam_cat.is_debug()) {
571 <<
"Bam file indicates a derivation of " << type
572 <<
" from " << parent_type <<
" which is no longer true.\n";
578 bool inserted = _index_map.insert(IndexMap::value_type(
id, type)).second;
579 nassertr(inserted, type);
581 if (bam_cat.is_spam()) {
583 <<
"Read TypeHandle for " << type <<
".\n";
613 nassertr(_now_creating != _created_objs.end(),
false);
614 int requestor_id = (*_now_creating).first;
617 int object_id = read_object_id(scan);
619 PointerReference &pref = _object_pointers[requestor_id];
620 if (_reading_cycler ==
nullptr) {
622 pref._objects.push_back(object_id);
625 pref._cycler_pointers[_reading_cycler].push_back(object_id);
630 if (object_id != 0) {
639 _num_extra_objects++;
654 for (
int i = 0; i < count; i++) {
666 read_object_id(scan);
683 nassertv(!_file_data_records.empty());
684 info = _file_data_records.front();
685 _file_data_records.pop_front();
697 _reading_cycler = &cycler;
699 cdata->
fillin(scan,
this);
701 _reading_cycler = old_cycler;
712 _reading_cycler = &cycler;
714 cdata->
fillin(scan,
this, extra_data);
716 _reading_cycler = old_cycler;
732 nassertv(_now_creating != _created_objs.end());
733 int requestor_id = (*_now_creating).first;
735 PointerReference &pref = _object_pointers[requestor_id];
736 pref._int_tags[tag] = value;
745 nassertr(_now_creating != _created_objs.end(), 0);
746 int requestor_id = (*_now_creating).first;
748 ObjectPointers::const_iterator opi = _object_pointers.find(requestor_id);
749 nassertr(opi != _object_pointers.end(), 0);
750 const PointerReference &pref = (*opi).second;
752 IntTags::const_iterator iti = pref._int_tags.find(tag);
753 nassertr(iti != pref._int_tags.end(), 0);
754 return (*iti).second;
773 nassertv(_now_creating != _created_objs.end());
774 int requestor_id = (*_now_creating).first;
776 PointerReference &pref = _object_pointers[requestor_id];
777 pref._aux_tags[tag] = value;
786 nassertr(_now_creating != _created_objs.end(),
nullptr);
787 int requestor_id = (*_now_creating).first;
789 ObjectPointers::const_iterator opi = _object_pointers.find(requestor_id);
790 nassertr(opi != _object_pointers.end(),
nullptr);
791 const PointerReference &pref = (*opi).second;
793 AuxTags::const_iterator ati = pref._aux_tags.find(tag);
794 nassertr(ati != pref._aux_tags.end(),
nullptr);
795 return (*ati).second;
809 nassertv(whom !=
nullptr);
811 if (bam_cat.is_spam()) {
813 <<
"register_finalize(" << (
void *)whom <<
") (" << whom->get_type()
817 _finalize_list.insert(whom);
836 nassertv(_now_creating != _created_objs.end());
837 CreatedObj &created_obj = (*_now_creating).second;
842 if (created_obj._ptr ==
nullptr) {
847 nassertv(created_obj._ptr ==
object);
851 created_obj._change_this = func;
852 created_obj._change_this_ref =
nullptr;
871 nassertv(_now_creating != _created_objs.end());
872 CreatedObj &created_obj = (*_now_creating).second;
877 if (created_obj._ptr ==
nullptr) {
878 created_obj.set_ptr(
object,
object);
882 nassertv(created_obj._ptr ==
object);
883 nassertv(created_obj._ref_ptr ==
object);
887 created_obj._change_this =
nullptr;
888 created_obj._change_this_ref = func;
898 if (whom ==
nullptr) {
902 Finalize::iterator fi = _finalize_list.find(whom);
903 if (fi != _finalize_list.end()) {
904 _finalize_list.erase(fi);
905 if (bam_cat.is_spam()) {
907 <<
"finalizing " << (
void *)whom <<
" (" << whom->get_type()
932 nassertr(_pta_id == -1,
nullptr);
933 int id = read_pta_id(scan);
943 PTAMap::iterator pi = _pta_map.find(
id);
944 if (pi == _pta_map.end()) {
966 bool inserted = _pta_map.insert(PTAMap::value_type(_pta_id, ptr)).second;
984 int object_id = read_object_id(scan);
986 CreatedObjs::iterator ci = _created_objs.find(object_id);
987 if (ci == _created_objs.end()) {
989 <<
"Bam file suggests eliminating object_id " << object_id
990 <<
", already gone.\n";
994 ObjectPointers::iterator oi = _object_pointers.find(object_id);
995 if (oi != _object_pointers.end()) {
997 <<
"Unable to resolve object " << object_id
998 <<
" before removing from table.\n";
1001 _created_objs_by_pointer.erase((*ci).second._ptr);
1002 _created_objs.erase(ci);
1015 if (_long_object_id) {
1020 if (object_id == 0xffff) {
1021 _long_object_id =
true;
1040 if (pta_id == 0xffff) {
1041 _long_pta_id =
true;
1057 if (!get_datagram(dg)) {
1059 if (bam_cat.is_debug()) {
1061 <<
"Reached end of bam source.\n";
1071 BamObjectCode boc = BOC_adjunct;
1091 free_object_ids(scan);
1096 return p_read_object();
1106 <<
"Failed to read file data.\n";
1109 _file_data_records.push_back(info);
1112 return p_read_object();
1116 <<
"Encountered invalid BamObjectCode 0x" << std::hex << (int)boc << std::dec <<
".\n";
1126 int object_id = read_object_id(scan);
1130 <<
"Found truncated datagram in bam stream\n";
1148 if (type != TypeHandle::none()) {
1155 CreatedObj new_created_obj;
1156 CreatedObjs::iterator oi =
1157 _created_objs.insert(CreatedObjs::value_type(object_id, new_created_obj)).first;
1158 CreatedObj &created_obj = (*oi).second;
1160 if (created_obj._ptr !=
nullptr) {
1164 if (_object_pointers.find(object_id) != _object_pointers.end()) {
1169 <<
"Found object " << object_id <<
" in bam stream again while " 1170 <<
"trying to resolve its own pointers.\n";
1178 CreatedObjs::iterator was_creating = _now_creating;
1180 created_obj._ptr->fillin(scan,
this);
1181 _now_creating = was_creating;
1186 <<
"in datagram containing type " << type <<
"\n";
1198 CreatedObjs::iterator was_creating = _now_creating;
1202 _now_creating = was_creating;
1205 nassertr(created_obj._ptr ==
object || created_obj._ptr ==
nullptr, object_id);
1206 if (
object ==
nullptr) {
1207 created_obj.set_ptr(
nullptr,
nullptr);
1211 created_obj._created =
true;
1213 if (created_obj._change_this_ref !=
nullptr) {
1218 ObjectPointers::const_iterator ri = _object_pointers.find(object_id);
1219 if (ri == _object_pointers.end()) {
1222 created_obj.set_ptr(object_ref, object_ref);
1223 created_obj._change_this =
nullptr;
1224 created_obj._change_this_ref =
nullptr;
1228 if (new_ptr !=
object) {
1229 _finalize_list.erase(
object);
1234 }
else if (created_obj._change_this !=
nullptr) {
1236 ObjectPointers::const_iterator ri = _object_pointers.find(object_id);
1237 if (ri == _object_pointers.end()) {
1238 TypedWritable *new_ptr = (*created_obj._change_this)(
object,
this);
1240 created_obj._change_this =
nullptr;
1241 created_obj._change_this_ref =
nullptr;
1243 if (new_ptr !=
object) {
1244 _finalize_list.erase(
object);
1250 _created_objs_by_pointer[created_obj._ptr].push_back(object_id);
1253 if (
object ==
nullptr) {
1254 if (bam_cat.is_debug()) {
1256 <<
"Unable to create an object of type " << type << std::endl;
1259 }
else if (object->get_type() != type) {
1260 if (_new_types.find(type) != _new_types.end()) {
1264 if (bam_cat.is_debug()) {
1266 <<
"Attempted to create a " << type.
get_name() \
1267 <<
" but a " <<
object->get_type() \
1268 <<
" was created instead." << std::endl;
1275 <<
"Attempted to create a " << type.
get_name() \
1276 <<
" but a " <<
object->get_type() \
1277 <<
" was created instead." << std::endl;
1281 if (bam_cat.is_spam()) {
1283 <<
"Read a " <<
object->get_type() <<
": " << (
void *)
object 1284 <<
" (id=" << object_id <<
")\n";
1292 <<
"End of datagram reached while reading bam object " 1293 << type <<
": " << (
void *)created_obj._ptr <<
"\n";
1307 BamReader::PointerReference &pref) {
1311 bool require_fully_complete =
object->require_fully_complete();
1314 CyclerPointers::iterator ci;
1315 ci = pref._cycler_pointers.begin();
1316 while (ci != pref._cycler_pointers.end()) {
1318 const vector_int &pointer_ids = (*ci).second;
1320 if (resolve_cycler_pointers(cycler, pointer_ids, require_fully_complete)) {
1324 CyclerPointers::iterator old = ci;
1326 pref._cycler_pointers.erase(old);
1334 if (!pref._cycler_pointers.empty()) {
1336 if (bam_cat.is_spam()) {
1338 <<
"some cyclers pending: complete_pointers for " << (
void *)
object 1339 <<
" (" << object->get_type() <<
")\n";
1348 bool is_complete =
true;
1350 vector_typedWritable references;
1351 references.reserve(pref._objects.size());
1353 vector_int::const_iterator pi;
1354 for (pi = pref._objects.begin();
1355 pi != pref._objects.end() && is_complete;
1357 int child_id = (*pi);
1358 if (child_id == 0) {
1360 references.push_back(
nullptr);
1365 CreatedObjs::const_iterator oi = _created_objs.find(child_id);
1366 if (oi == _created_objs.end()) {
1368 is_complete =
false;
1372 const CreatedObj &child_obj = (*oi).second;
1373 if (!child_obj._created) {
1375 is_complete =
false;
1379 if (child_obj._change_this !=
nullptr || child_obj._change_this_ref !=
nullptr) {
1381 is_complete =
false;
1385 if (require_fully_complete &&
1386 _object_pointers.find(child_id) != _object_pointers.end()) {
1388 is_complete =
false;
1393 references.push_back(child_obj._ptr);
1398 nassertr(references.size() == pref._objects.size(),
false);
1400 if (bam_cat.is_spam()) {
1402 <<
"complete_pointers for " << (
void *)
object 1403 <<
" (" << object->get_type() <<
"), " << references.size()
1406 int num_completed = 0;
1407 if (!references.empty()) {
1408 num_completed =
object->complete_pointers(&references[0],
this);
1410 if (num_completed != (
int)references.size()) {
1412 <<
object->get_type() <<
" completed " << num_completed
1413 <<
" of " << references.size() <<
" pointers.\n";
1414 nassertr(num_completed < (
int)references.size(),
true);
1419 if (bam_cat.is_spam()) {
1421 <<
"not ready: complete_pointers for " << (
void *)
object 1422 <<
" (" << object->get_type() <<
")\n";
1436 const vector_int &pointer_ids,
1437 bool require_fully_complete) {
1443 bool is_complete =
true;
1444 vector_typedWritable references;
1446 vector_int::const_iterator pi;
1447 for (pi = pointer_ids.begin(); pi != pointer_ids.end() && is_complete; ++pi) {
1448 int child_id = (*pi);
1450 if (child_id == 0) {
1452 references.push_back(
nullptr);
1457 CreatedObjs::const_iterator oi = _created_objs.find(child_id);
1458 if (oi == _created_objs.end()) {
1460 is_complete =
false;
1464 const CreatedObj &child_obj = (*oi).second;
1465 if (child_obj._change_this !=
nullptr || child_obj._change_this_ref !=
nullptr) {
1467 is_complete =
false;
1471 if (require_fully_complete &&
1472 _object_pointers.find(child_id) != _object_pointers.end()) {
1474 is_complete =
false;
1479 references.push_back(child_obj._ptr);
1485 if (bam_cat.is_spam()) {
1487 <<
"complete_pointers for CycleData object " << (
void *)cdata
1492 if (num_completed != (
int)references.size()) {
1494 <<
"CycleData object completed " << num_completed
1495 <<
" of " << references.size() <<
" pointers.\n";
1496 nassertr(num_completed < (
int)references.size(),
true);
1510 if (bam_cat.is_debug()) {
1512 <<
"Finalizing bam source\n";
1515 Finalize::iterator fi = _finalize_list.begin();
1516 while (fi != _finalize_list.end()) {
1518 nassertv(
object !=
nullptr);
1519 _finalize_list.erase(fi);
1520 if (bam_cat.is_spam()) {
1522 <<
"finalizing " << (
void *)
object <<
" (" << object->get_type()
1525 object->finalize(
this);
1526 _aux_data.erase(
object);
1527 fi = _finalize_list.begin();
1531 if (!_aux_data.empty()) {
1532 AuxDataTable::iterator ti = _aux_data.find(
nullptr);
1534 if (ti != _aux_data.end()) {
1535 if (_aux_data.size() > 1) {
1537 AuxDataTable new_aux_data;
1538 AuxDataTable::iterator nti =
1539 new_aux_data.insert(AuxDataTable::value_type(
nullptr, AuxDataNames())).first;
1540 (*nti).second.swap((*ti).second);
1541 _aux_data.swap(new_aux_data);
This is our own Panda specialization on the default STL map.
void read_file_data(SubfileInfo &info)
Reads a block of auxiliary file data from the Bam file.
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(),...
bool get_bool()
Extracts a boolean value.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
Stores auxiliary data that may be piggybacked on the BamReader during each object's read pass.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
A Factory can be used to create an instance of a particular subclass of some general base class.
virtual ReferenceCount * as_reference_count()
Returns the pointer cast to a ReferenceCount pointer, if it is in fact of that type.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Type * make_instance_more_general(TypeHandle handle, const FactoryParams ¶ms=FactoryParams())
Attempts to create an instance of the type requested, or some base type of the type requested.
TypedWritable * read_object()
Reads a single object from the Bam file.
void * get_pta(DatagramIterator &scan)
This function works in conjection with register_pta(), below, to read a PointerToArray (PTA) from the...
A single page of data maintained by a PipelineCycler.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void skip_pointer(DatagramIterator &scan)
Reads and discards a pointer value from the Bam file.
This is the trivial, non-threaded implementation of PipelineCyclerBase.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle register_dynamic_type(const std::string &name)
Registers a new type on-the-fly, presumably at runtime.
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
TypeHandle find_type(const std::string &name) const
Looks for a previously-registered type of the given name.
int get_int_tag(const std::string &tag) const
Returns the value previously set via set_int_tag().
size_t get_remaining_size() const
Return the bytes left in the datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CycleData * write(Thread *current_thread)
Returns a non-const CycleData pointer, filled with a unique copy of the data for the current stage of...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_string()
Extracts a variable-length string.
get_name
Returns the name of the type.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool init()
Initializes the BamReader prior to reading any objects from its source.
size_t get_current_index() const
Returns the current position within the datagram of the next piece of data to extract.
virtual bool save_datagram(SubfileInfo &info)
Skips over the next datagram without extracting it, but saves the relevant file information in the Su...
set_source
Changes the source of future datagrams for this BamReader.
BamReaderAuxData * get_aux_tag(const std::string &tag) const
Returns the value previously set via set_aux_tag().
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
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.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
void finalize_now(TypedWritable *whom)
Forces the finalization of a particular object.
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.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
A base class for all things that want to be reference-counted.
void release_write(CycleData *pointer)
Releases a pointer previously obtained via a call to write().
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
TypeHandle get_parent_towards(TypeHandle ancestor, TypedObject *object=nullptr) const
Returns the parent class that is in a direct line of inheritance to the indicated ancestor class.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
This class records a particular byte sub-range within an existing file on disk.
A class to retrieve the individual data elements previously stored in a Datagram.
void set_int_tag(const std::string &tag, int value)
Allows the creating object to store a temporary data value on the BamReader.
TypeHandle is the identifier used to differentiate C++ class types.
The parameters that are passed through the Factory to any object constructing itself from a Bam file.
get_filename
If a BAM is a file, then the BamReader should contain the name of the file.
This class defines the abstract interace to any source of datagrams, whether it be from a file or fro...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void record_derivation(TypeHandle child, TypeHandle parent)
Records that the type referenced by child inherits directly from the type referenced by parent.
void set_aux_tag(const std::string &tag, BamReaderAuxData *value)
Allows the creating object to store a temporary data value on the BamReader.
TypeHandle read_handle(DatagramIterator &scan)
Reads a TypeHandle out of the Datagram.
size_t get_length() const
Returns the number of bytes in the datagram.
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...