34 bool operator < (
const ObsoleteName &other)
const {
35 if (_before_major != other._before_major) {
36 return _before_major < other._before_major;
38 return _before_minor < other._before_minor;
53 _next_boc = BOC_adjunct;
59 _long_object_id =
false;
67 <<
"bam-version configuration variable requires two arguments.\n";
69 _file_major = bam_version[0];
70 _file_minor = bam_version[1];
72 if (_file_major < _bam_major_ver || _file_minor < 21) {
74 <<
"bam-version is set to " << bam_version <<
", but this version of " 75 "Panda3D cannot produce .bam files older than 6.21. Set " 76 "bam-version to 6 21 in Config.prc to suppress this error, or " 77 "leave it blank to write version " << _bam_major_ver <<
"." 78 << _bam_minor_ver <<
" files.\n";
83 }
else if (_file_major > _bam_major_ver || _file_minor > _bam_minor_ver) {
85 <<
"bam-version is set to " << bam_version <<
", but this version of " 86 "Panda3D cannot produce .bam files newer than " << _bam_major_ver
87 <<
"." << _bam_minor_ver <<
". Set bam-version to a supported " 88 "version or leave it blank to write version " << _bam_major_ver
89 <<
"." << _bam_minor_ver <<
" files.\n";
91 _file_major = _bam_major_ver;
92 _file_minor = _bam_minor_ver;
93 bam_version.
set_word(0, _bam_major_ver);
94 bam_version.
set_word(1, _bam_minor_ver);
97 _file_major = _bam_major_ver;
98 _file_minor = _bam_minor_ver;
100 _file_endian = bam_endian;
101 _file_stdfloat_double = bam_stdfloat_double;
102 _file_texture_mode = bam_texture_mode;
112 StateMap::iterator si;
113 for (si = _state_map.begin(); si != _state_map.end(); ++si) {
115 object->remove_bam_writer(
this);
117 if ((*si).second._refcount !=
nullptr) {
129 if (_target !=
nullptr) {
134 if (_needs_init && _target !=
nullptr) {
148 nassertr(_target !=
nullptr,
false);
149 nassertr(_needs_init,
false);
155 _long_object_id =
false;
157 _long_pta_id =
false;
159 nassertr_always(_file_major == _bam_major_ver,
false);
160 nassertr_always(_file_minor <= _bam_minor_ver && _file_minor >= 21,
false);
162 _file_endian = bam_endian;
163 _file_texture_mode = bam_texture_mode;
172 if (_file_major >= 6 || _file_minor >= 27) {
173 header.
add_bool(_file_stdfloat_double);
175 _file_stdfloat_double =
false;
178 if (!_target->put_datagram(header)) {
180 <<
"Unable to write Bam header.\n";
205 nassertr(_target !=
nullptr,
false);
212 if (!_freed_object_ids.empty()) {
216 FreedObjectIds::iterator fi;
217 for (fi = _freed_object_ids.begin(); fi != _freed_object_ids.end(); ++fi) {
218 write_object_id(dg, (*fi));
220 _freed_object_ids.clear();
222 if (!_target->put_datagram(dg)) {
224 <<
"Unable to write data to output.\n";
229 nassertr(_object_queue.empty(),
false);
230 _next_boc = BOC_push;
232 int object_id = enqueue_object(
object);
233 nassertr(object_id != 0,
false);
234 if (!flush_queue()) {
239 if (_next_boc != BOC_push) {
242 if (!_target->put_datagram(dg)) {
244 <<
"Unable to write data to output.\n";
259 StateMap::const_iterator si = _state_map.find(
object);
260 return (si != _state_map.end());
268 nassertv(_target !=
nullptr);
280 StateMap::iterator si = _state_map.find(
object);
281 if (si == _state_map.end()) {
283 enqueue_object(
object);
285 }
else if ((*si).second._written_seq.is_initial()) {
287 enqueue_object(
object);
289 }
else if ((*si).second._written_seq == _writing_seq) {
295 enqueue_object(
object);
299 (*si).second._written_seq = _writing_seq;
320 if (
object ==
nullptr) {
321 write_object_id(packet, 0);
324 StateMap::iterator si = _state_map.find(
object);
325 if (si == _state_map.end()) {
328 int object_id = enqueue_object(
object);
329 write_object_id(packet, object_id);
334 int object_id = (*si).second._object_id;
335 bool already_written = !(*si).second._written_seq.is_initial();
336 if ((*si).second._written_seq != _writing_seq &&
340 already_written =
false;
343 write_object_id(packet, object_id);
345 if (!already_written) {
347 enqueue_object(
object);
368 if (!_target->put_datagram(dg)) {
370 <<
"Unable to write data to output.\n";
378 <<
"Unable to write file data to output.\n";
399 if (!_target->put_datagram(dg)) {
401 <<
"Unable to write data to output.\n";
409 <<
"Unable to write file data to output.\n";
426 const CycleData *cdata = cycler.
read(Thread::get_current_thread());
438 const CycleData *cdata = cycler.
read(Thread::get_current_thread());
458 if (ptr ==
nullptr) {
461 write_pta_id(packet, 0);
474 PTAMap::iterator pi = _pta_map.find(ptr);
475 if (pi == _pta_map.end()) {
477 int pta_id = _next_pta_id;
480 bool inserted = _pta_map.insert(PTAMap::value_type(ptr, pta_id)).second;
481 nassertr(inserted,
false);
483 write_pta_id(packet, pta_id);
491 int pta_id = (*pi).second;
492 write_pta_id(packet, pta_id);
516 nassertv(index <= 0xffff);
521 bool inserted = _types_written.insert(index).second;
527 if (_file_major == _bam_major_ver && _file_minor == _bam_minor_ver) {
538 nassertv(num_parent_classes <= 255);
540 for (
int i = 0; i < num_parent_classes; i++) {
552 int index = obsolete_type_names.find(type);
556 for (
const ObsoleteName &name : obsolete_type_names.get_data((
size_t)index)) {
557 if (major < name._before_major ||
558 (major == name._before_major && minor < name._before_minor)) {
575 int before_major,
int before_minor) {
580 ObsoleteName obsolete_name;
581 obsolete_name._name = std::move(name);
582 obsolete_name._before_major = before_major;
583 obsolete_name._before_minor = before_minor;
584 obsolete_type_names[type].insert(std::move(obsolete_name));
595 StateMap::iterator si = _state_map.find(
object);
596 if (si != _state_map.end()) {
599 nassertv(!(*si).second._written_seq.is_initial());
602 nassertv((*si).second._refcount ==
nullptr);
604 int object_id = (*si).second._object_id;
605 _freed_object_ids.push_back(object_id);
607 _state_map.erase(si);
615 write_object_id(
Datagram &dg,
int object_id) {
616 if (_long_object_id) {
623 if (object_id == 0xffff) {
624 _long_object_id =
true;
633 write_pta_id(
Datagram &dg,
int pta_id) {
641 if (pta_id == 0xffff) {
657 nassertr(
object != TypedWritable::Null, 0);
663 if (!object->
is_of_type(TypedWritable::get_class_type())) {
665 <<
"Type " <<
object->get_type()
666 <<
" does not indicate inheritance from TypedWritable.\n" 667 <<
"(this is almost certainly an oversight in " <<
object->get_type()
668 <<
"::init_type().)\n";
676 StateMap::iterator si = _state_map.find(
object);
677 if (si == _state_map.end()) {
679 object_id = _next_object_id;
681 StateMap::iterator si;
684 _state_map.insert(StateMap::value_type(
object, StoreState(_next_object_id)));
685 nassertr(inserted,
false);
689 (const_cast<TypedWritable*>(
object))->add_bam_writer(
this);
697 (*si).second._refcount = rc;
702 object_id = (*si).second._object_id;
705 _object_queue.push_back(
object);
717 nassertr(_target !=
nullptr,
false);
719 while (!_object_queue.empty()) {
721 _object_queue.pop_front();
724 StateMap::iterator si = _state_map.find(
object);
725 nassertr(si != _state_map.end(),
false);
727 if ((*si).second._written_seq == _writing_seq) {
732 int object_id = (*si).second._object_id;
733 bool already_written = !(*si).second._written_seq.is_initial();
737 already_written =
false;
743 _next_boc = BOC_adjunct;
745 if (!already_written) {
753 nassertr(type != TypeHandle::none(),
false);
759 if (registered_type == TypeHandle::none()) {
762 <<
"Objects of type " << type <<
" cannot be read; bam file is invalid.\n";
763 }
else if (registered_type != type) {
765 <<
"Writing " << registered_type <<
" instead of " << type <<
"\n";
766 type = registered_type;
768 }
else if (util_cat.is_debug()) {
770 <<
"Writing " << type <<
" object id " << object_id
775 write_object_id(dg, object_id);
785 (*si).second._written_seq = _writing_seq;
786 (*si).second._modified =
object->get_bam_modified();
793 (*si).second._refcount =
nullptr;
804 write_object_id(dg, object_id);
811 if (!_target->put_datagram(dg)) {
813 <<
"Unable to write data to output.\n";
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_word(size_t n, int value)
Reassigns the variable's nth value.
bool has_object(const TypedWritable *obj) const
Returns true if the object has previously been written (or at least requested to be written) to the b...
UpdateSeq get_bam_modified() const
Returns the current bam_modified counter.
void set_string_value(const std::string &value)
Changes the value assigned to this variable.
A single page of data maintained by a PipelineCycler.
std::string get_name(TypeHandle type, TypedObject *object) const
Returns the name of the indicated type.
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 record_alternate_name(TypeHandle type, const std::string &name)
Indicates an alternate name for the same type.
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the trivial, non-threaded implementation of PipelineCyclerBase.
This template class implements an unordered map of keys to data, implemented as a hashtable.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_name
Returns the name of the type.
void add_uint32(uint32_t value)
Adds an unsigned 32-bit integer to the datagram.
void set_stdfloat_double(bool stdfloat_double)
Changes the stdfloat_double flag, which defines the operation performed by add_stdfloat() and Datagra...
void write_handle(Datagram &packet, TypeHandle type)
Writes a TypeHandle to the file in such a way that the BamReader can read the same TypeHandle later v...
size_t get_num_words() const
Returns the number of words in the variable's value.
virtual void write_datagram(BamWriter *, Datagram &) const
Writes the contents of this object to the datagram for shipping out to a Bam file.
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
void add_bool(bool value)
Adds a boolean value to the datagram.
This class defines the abstract interface to sending datagrams to any target, whether it be into a fi...
The name of a file, such as a texture file or an Egg file.
static std::string get_obsolete_type_name(TypeHandle type, int major, int minor)
Returns the name that the given type had in an older .bam version.
get_index
Returns the integer index associated with this TypeHandle.
virtual bool copy_datagram(SubfileInfo &result, const Filename &filename)
Copies the file data from the entire indicated file (via the vfs) as the next datagram.
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
bool write_object(const TypedWritable *obj)
Writes a single object to the Bam file, so that the BamReader::read_object() can later correctly rest...
static void record_obsolete_type_name(TypeHandle type, std::string name, int before_major, int before_minor)
Registers the given type as having an older name in .bam files *before* the indicated version.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool register_pta(Datagram &packet, const void *ptr)
Prepares to write a PointerToArray to the Bam file, unifying references to the same pointer across th...
get_parent_class
Returns the nth parent class of this type.
void ref() const
Explicitly increments the reference count.
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
A base class for all things that want to be reference-counted.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
The TypeRegistry class maintains all the assigned TypeHandles in a given system.
const CycleData * read(Thread *current_thread) const
Returns a const CycleData pointer, filled with the data for the current stage of the pipeline as seen...
This class records a particular byte sub-range within an existing file on disk.
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void flush()
Ensures that all data written thus far is manifested on the output stream.
void write_file_data(SubfileInfo &result, const Filename &filename)
Writes a block of auxiliary file data from the indicated file (within the vfs).
get_num_parent_classes
Returns the number of parent classes that this type is known to have.
set_target
Changes the destination of future datagrams written by the BamWriter.
void consider_update(const TypedWritable *obj)
Should be called from TypedWritable::update_bam_nested() to recursively check the entire hiererachy o...
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
bool init()
Initializes the BamWriter prior to writing any objects to its output stream.
void release_read(const CycleData *pointer) const
Releases a pointer previously obtained via a call to read().
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle find_registered_type(TypeHandle handle)
Returns the TypeHandle given, if it is a registered type, or if it is not registered,...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.