diff --git a/panda/src/chan/partBundle.cxx b/panda/src/chan/partBundle.cxx index 2e77f8c1af..8c5cb009f6 100644 --- a/panda/src/chan/partBundle.cxx +++ b/panda/src/chan/partBundle.cxx @@ -428,13 +428,13 @@ recompute_net_blend() { //////////////////////////////////////////////////////////////////// // Function: PartBundle::finalize -// Access: Public -// Description: Method to ensure that any necessary clean up tasks -// that have to be performed by this object are performed +// Access: Public, Virtual +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void PartBundle:: -finalize(void) -{ +finalize(BamReader *) { do_update(this, NULL, true, true); } diff --git a/panda/src/chan/partBundle.h b/panda/src/chan/partBundle.h index 01425c8ea1..c128598fb4 100644 --- a/panda/src/chan/partBundle.h +++ b/panda/src/chan/partBundle.h @@ -142,7 +142,7 @@ protected: public: static void register_with_read_factory(void); - virtual void finalize(); + virtual void finalize(BamReader *manager); static TypedWritable *make_PartBundle(const FactoryParams ¶ms); diff --git a/panda/src/char/characterVertexSlider.cxx b/panda/src/char/characterVertexSlider.cxx index e36316dff4..0dcaf78852 100644 --- a/panda/src/char/characterVertexSlider.cxx +++ b/panda/src/char/characterVertexSlider.cxx @@ -93,6 +93,8 @@ register_with_read_factory() { void CharacterVertexSlider:: write_datagram(BamWriter *manager, Datagram &dg) { VertexSlider::write_datagram(manager, dg); + + manager->write_pointer(dg, _char_slider); } //////////////////////////////////////////////////////////////////// @@ -106,6 +108,8 @@ int CharacterVertexSlider:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = VertexSlider::complete_pointers(p_list, manager); + _char_slider = DCAST(CharacterSlider, p_list[pi++]); + return pi; } @@ -139,4 +143,6 @@ make_from_bam(const FactoryParams ¶ms) { void CharacterVertexSlider:: fillin(DatagramIterator &scan, BamReader *manager) { VertexSlider::fillin(scan, manager); + + manager->read_pointer(scan); } diff --git a/panda/src/char/jointVertexTransform.cxx b/panda/src/char/jointVertexTransform.cxx index e1968460db..303a07365f 100644 --- a/panda/src/char/jointVertexTransform.cxx +++ b/panda/src/char/jointVertexTransform.cxx @@ -154,6 +154,8 @@ register_with_read_factory() { void JointVertexTransform:: write_datagram(BamWriter *manager, Datagram &dg) { VertexTransform::write_datagram(manager, dg); + + manager->write_pointer(dg, _joint); } //////////////////////////////////////////////////////////////////// @@ -167,6 +169,8 @@ int JointVertexTransform:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = VertexTransform::complete_pointers(p_list, manager); + _joint = DCAST(CharacterJoint, p_list[pi++]); + return pi; } @@ -200,4 +204,7 @@ make_from_bam(const FactoryParams ¶ms) { void JointVertexTransform:: fillin(DatagramIterator &scan, BamReader *manager) { VertexTransform::fillin(scan, manager); + + manager->read_pointer(scan); + _matrix_stale = true; } diff --git a/panda/src/gobj/internalName.cxx b/panda/src/gobj/internalName.cxx index eada8689a9..520a01289e 100644 --- a/panda/src/gobj/internalName.cxx +++ b/panda/src/gobj/internalName.cxx @@ -78,6 +78,8 @@ InternalName:: //////////////////////////////////////////////////////////////////// PT(InternalName) InternalName:: append(const string &name) { + test_ref_count_integrity(); + if (name.empty()) { return this; } @@ -129,6 +131,8 @@ get_name() const { //////////////////////////////////////////////////////////////////// int InternalName:: find_ancestor(const string &basename) const { + test_ref_count_integrity(); + if (_basename == basename) { return 0; @@ -152,6 +156,8 @@ find_ancestor(const string &basename) const { //////////////////////////////////////////////////////////////////// const InternalName *InternalName:: get_ancestor(int n) const { + test_ref_count_integrity(); + if (n == 0) { return this; @@ -217,11 +223,12 @@ register_with_read_factory() { //////////////////////////////////////////////////////////////////// // Function: InternalName::finalize // Access: Public, Virtual -// Description: Method to ensure that any necessary clean up tasks -// that have to be performed by this object are performed +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void InternalName:: -finalize() { +finalize(BamReader *) { // Unref the pointer that we explicitly reffed in make_from_bam(). unref(); diff --git a/panda/src/gobj/internalName.h b/panda/src/gobj/internalName.h index fe48f446cd..75e058bae2 100644 --- a/panda/src/gobj/internalName.h +++ b/panda/src/gobj/internalName.h @@ -107,7 +107,7 @@ public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &me); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 5e074e4f44..be341bd113 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -784,6 +784,16 @@ make_copy() const { //////////////////////////////////////////////////////////////////// void qpGeom::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { + manager->write_pointer(dg, _data); + + dg.add_uint16(_primitives.size()); + Primitives::const_iterator pi; + for (pi = _primitives.begin(); pi != _primitives.end(); ++pi) { + manager->write_pointer(dg, *pi); + } + + dg.add_uint8(_primitive_type); + dg.add_uint16(_point_rendering); } //////////////////////////////////////////////////////////////////// @@ -797,6 +807,13 @@ int qpGeom::CData:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = CycleData::complete_pointers(p_list, manager); + _data = DCAST(qpGeomVertexData, p_list[pi++]); + + Primitives::iterator pri; + for (pri = _primitives.begin(); pri != _primitives.end(); ++pri) { + (*pri) = DCAST(qpGeomPrimitive, p_list[pi++]); + } + return pi; } @@ -809,4 +826,17 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void qpGeom::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + manager->read_pointer(scan); + + int num_primitives = scan.get_uint16(); + _primitives.reserve(num_primitives); + for (int i = 0; i < num_primitives; ++i) { + manager->read_pointer(scan); + _primitives.push_back(NULL); + } + + _primitive_type = (qpGeomPrimitive::PrimitiveType)scan.get_uint8(); + _point_rendering = scan.get_uint16(); + _got_usage_hint = false; + _modified = qpGeom::get_next_modified(); } diff --git a/panda/src/gobj/qpgeomPrimitive.cxx b/panda/src/gobj/qpgeomPrimitive.cxx index 749f3a4adf..2e70688a1a 100644 --- a/panda/src/gobj/qpgeomPrimitive.cxx +++ b/panda/src/gobj/qpgeomPrimitive.cxx @@ -1004,6 +1004,8 @@ void qpGeomPrimitive:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); + dg.add_uint8(_usage_hint); + manager->write_cdata(dg, _cycler); } @@ -1018,6 +1020,8 @@ void qpGeomPrimitive:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); + _usage_hint = (qpGeomUsageHint::UsageHint)scan.get_uint8(); + manager->read_cdata(scan, _cycler); } @@ -1079,20 +1083,10 @@ make_copy() const { //////////////////////////////////////////////////////////////////// void qpGeomPrimitive::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { -} + dg.add_uint8(_shade_model); -//////////////////////////////////////////////////////////////////// -// Function: qpGeomPrimitive::CData::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int qpGeomPrimitive::CData:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); - - return pi; + WRITE_PTA(manager, dg, IPD_ushort::write_datagram, _vertices); + WRITE_PTA(manager, dg, IPD_int::write_datagram, _ends); } //////////////////////////////////////////////////////////////////// @@ -1104,4 +1098,11 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void qpGeomPrimitive::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + _shade_model = (ShadeModel)scan.get_uint8(); + + READ_PTA(manager, scan, IPD_ushort::read_datagram, _vertices); + READ_PTA(manager, scan, IPD_int::read_datagram, _ends); + + _modified = qpGeom::get_next_modified(); + _got_minmax = false; } diff --git a/panda/src/gobj/qpgeomPrimitive.h b/panda/src/gobj/qpgeomPrimitive.h index 037ae7e23a..bf34ee8e50 100644 --- a/panda/src/gobj/qpgeomPrimitive.h +++ b/panda/src/gobj/qpgeomPrimitive.h @@ -228,7 +228,6 @@ private: INLINE CData(const CData ©); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); virtual void fillin(DatagramIterator &scan, BamReader *manager); ShadeModel _shade_model; diff --git a/panda/src/gobj/qpgeomVertexAnimationSpec.cxx b/panda/src/gobj/qpgeomVertexAnimationSpec.cxx index 13f251a7b3..79b67192c1 100644 --- a/panda/src/gobj/qpgeomVertexAnimationSpec.cxx +++ b/panda/src/gobj/qpgeomVertexAnimationSpec.cxx @@ -17,6 +17,8 @@ //////////////////////////////////////////////////////////////////// #include "qpgeomVertexAnimationSpec.h" +#include "datagram.h" +#include "datagramIterator.h" //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexAnimationSpec::output @@ -40,3 +42,30 @@ output(ostream &out) const { break; } } + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexAnimationSpec::write_datagram +// Access: Public +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexAnimationSpec:: +write_datagram(BamWriter *, Datagram &dg) { + dg.add_uint8(_animation_type); + dg.add_uint16(_num_transforms); + dg.add_bool(_indexed_transforms); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexAnimationSpec::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new qpGeomVertexAnimationSpec. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexAnimationSpec:: +fillin(DatagramIterator &scan, BamReader *) { + _animation_type = (AnimationType)scan.get_uint8(); + _num_transforms = scan.get_uint16(); + _indexed_transforms = scan.get_bool(); +} diff --git a/panda/src/gobj/qpgeomVertexAnimationSpec.h b/panda/src/gobj/qpgeomVertexAnimationSpec.h index f374036e0e..39704e6e6f 100644 --- a/panda/src/gobj/qpgeomVertexAnimationSpec.h +++ b/panda/src/gobj/qpgeomVertexAnimationSpec.h @@ -21,6 +21,11 @@ #include "pandabase.h" +class BamWriter; +class BamReader; +class Datagram; +class DatagramIterator; + //////////////////////////////////////////////////////////////////// // Class : qpGeomVertexAnimationSpec // Description : This object describes how the vertex animation, if @@ -68,6 +73,10 @@ public: INLINE bool operator != (const qpGeomVertexAnimationSpec &other) const; INLINE int compare_to(const qpGeomVertexAnimationSpec &other) const; +public: + void write_datagram(BamWriter *manager, Datagram &dg); + void fillin(DatagramIterator &scan, BamReader *manager); + private: AnimationType _animation_type; diff --git a/panda/src/gobj/qpgeomVertexArrayData.cxx b/panda/src/gobj/qpgeomVertexArrayData.cxx index cfaf029a04..1ca9d499c2 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.cxx +++ b/panda/src/gobj/qpgeomVertexArrayData.cxx @@ -317,11 +317,63 @@ register_with_read_factory() { //////////////////////////////////////////////////////////////////// void qpGeomVertexArrayData:: write_datagram(BamWriter *manager, Datagram &dg) { - TypedWritable::write_datagram(manager, dg); + TypedWritableReferenceCount::write_datagram(manager, dg); + + manager->write_pointer(dg, _array_format); + dg.add_uint8(_usage_hint); manager->write_cdata(dg, _cycler); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::write_raw_data +// Access: Public, Static +// Description: Called by CData::write_datagram to write the raw data +// of the array to the indicated datagram. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexArrayData:: +write_raw_data(Datagram &dg, const PTA_uchar &data) { + // TODO: account for endianness of host. + dg.add_uint32(data.size()); + dg.append_data(data, data.size()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::read_raw_data +// Access: Public, Static +// Description: Called by CData::fillin to read the raw data +// of the array from the indicated datagram. +//////////////////////////////////////////////////////////////////// +PTA_uchar qpGeomVertexArrayData:: +read_raw_data(DatagramIterator &scan) { + // TODO: account for endianness of host. + + size_t size = scan.get_uint32(); + PTA_uchar data = PTA_uchar::empty_array(size); + const unsigned char *source_data = + (const unsigned char *)scan.get_datagram().get_data(); + memcpy(data, source_data + scan.get_current_index(), size); + scan.skip_bytes(size); + + return data; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int qpGeomVertexArrayData:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + + _array_format = DCAST(qpGeomVertexArrayFormat, p_list[pi++]); + + return pi; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayData::make_from_bam // Access: Protected, Static @@ -351,7 +403,10 @@ make_from_bam(const FactoryParams ¶ms) { //////////////////////////////////////////////////////////////////// void qpGeomVertexArrayData:: fillin(DatagramIterator &scan, BamReader *manager) { - TypedWritable::fillin(scan, manager); + TypedWritableReferenceCount::fillin(scan, manager); + + manager->read_pointer(scan); + _usage_hint = (qpGeomUsageHint::UsageHint)scan.get_uint8(); manager->read_cdata(scan, _cycler); } @@ -374,20 +429,7 @@ make_copy() const { //////////////////////////////////////////////////////////////////// void qpGeomVertexArrayData::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { -} - -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexArrayData::CData::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int qpGeomVertexArrayData::CData:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); - - return pi; + WRITE_PTA(manager, dg, write_raw_data, _data); } //////////////////////////////////////////////////////////////////// @@ -399,4 +441,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void qpGeomVertexArrayData::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + READ_PTA(manager, scan, read_raw_data, _data); + + _modified = qpGeom::get_next_modified(); } diff --git a/panda/src/gobj/qpgeomVertexArrayData.h b/panda/src/gobj/qpgeomVertexArrayData.h index a95c0e0e86..9b181dac27 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.h +++ b/panda/src/gobj/qpgeomVertexArrayData.h @@ -115,7 +115,6 @@ private: INLINE CData(const CData ©); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); virtual void fillin(DatagramIterator &scan, BamReader *manager); PTA_uchar _data; @@ -129,6 +128,9 @@ private: public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); + static void write_raw_data(Datagram &dg, const PTA_uchar &data); + static PTA_uchar read_raw_data(DatagramIterator &source); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); @@ -152,6 +154,7 @@ private: static TypeHandle _type_handle; friend class qpGeomCacheManager; + friend class qpGeomVertexData; friend class PreparedGraphicsObjects; }; diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.cxx b/panda/src/gobj/qpgeomVertexArrayFormat.cxx index 3a555b0969..a74050d343 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.cxx +++ b/panda/src/gobj/qpgeomVertexArrayFormat.cxx @@ -151,7 +151,7 @@ qpGeomVertexArrayFormat(const qpGeomVertexArrayFormat ©) : _pad_to(copy._pad_to), _columns_unsorted(copy._columns_unsorted) { - DataTypes::const_iterator dti; + Columns::const_iterator dti; for (dti = copy._columns.begin(); dti != copy._columns.end(); ++dti) { add_column(*(*dti)); } @@ -172,7 +172,7 @@ operator = (const qpGeomVertexArrayFormat ©) { _columns.clear(); _columns_by_name.clear(); _columns_unsorted = false; - DataTypes::const_iterator dti; + Columns::const_iterator dti; for (dti = copy._columns.begin(); dti != copy._columns.end(); ++dti) { add_column(*(*dti)); } @@ -185,9 +185,9 @@ operator = (const qpGeomVertexArrayFormat ©) { //////////////////////////////////////////////////////////////////// qpGeomVertexArrayFormat:: ~qpGeomVertexArrayFormat() { - DataTypes::iterator dti; - for (dti = _columns.begin(); dti != _columns.end(); ++dti) { - delete (*dti); + Columns::iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + delete (*ci); } } @@ -263,7 +263,7 @@ add_column(const qpGeomVertexColumn &column) { int new_index = (int)_columns.size(); _columns.push_back(new_column); - _columns_by_name.insert(DataTypesByName::value_type(new_column->get_name(), new_column)); + _columns_by_name.insert(ColumnsByName::value_type(new_column->get_name(), new_column)); return new_index; } @@ -277,16 +277,16 @@ add_column(const qpGeomVertexColumn &column) { void qpGeomVertexArrayFormat:: remove_column(const InternalName *name) { nassertv(!_is_registered); - DataTypesByName::iterator ni; + ColumnsByName::iterator ni; ni = _columns_by_name.find(name); if (ni != _columns_by_name.end()) { qpGeomVertexColumn *column = (*ni).second; _columns_by_name.erase(ni); - DataTypes::iterator dti; - dti = find(_columns.begin(), _columns.end(), column); - nassertv(dti != _columns.end()); - _columns.erase(dti); + Columns::iterator ci; + ci = find(_columns.begin(), _columns.end(), column); + nassertv(ci != _columns.end()); + _columns.erase(ci); delete column; @@ -326,7 +326,7 @@ clear_columns() { //////////////////////////////////////////////////////////////////// const qpGeomVertexColumn *qpGeomVertexArrayFormat:: get_column(const InternalName *name) const { - DataTypesByName::const_iterator ni; + ColumnsByName::const_iterator ni; ni = _columns_by_name.find(name); if (ni != _columns_by_name.end()) { return (*ni).second; @@ -344,9 +344,9 @@ get_column(const InternalName *name) const { const qpGeomVertexColumn *qpGeomVertexArrayFormat:: get_column(int start_byte, int num_bytes) const { consider_sort_columns(); - DataTypes::const_iterator dti; - for (dti = _columns.begin(); dti != _columns.end(); ++dti) { - const qpGeomVertexColumn *column = (*dti); + Columns::const_iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + const qpGeomVertexColumn *column = (*ci); if (column->overlaps_with(start_byte, num_bytes)) { return column; } @@ -394,10 +394,10 @@ is_data_subset_of(const qpGeomVertexArrayFormat &other) const { //////////////////////////////////////////////////////////////////// void qpGeomVertexArrayFormat:: output(ostream &out) const { - DataTypes::const_iterator dti; + Columns::const_iterator ci; out << "["; - for (dti = _columns.begin(); dti != _columns.end(); ++dti) { - const qpGeomVertexColumn *column = (*dti); + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + const qpGeomVertexColumn *column = (*ci); out << " " << *column; } out << " ]"; @@ -413,9 +413,9 @@ write(ostream &out, int indent_level) const { indent(out, indent_level) << "Array format (stride = " << get_stride() << "):\n"; consider_sort_columns(); - DataTypes::const_iterator dti; - for (dti = _columns.begin(); dti != _columns.end(); ++dti) { - const qpGeomVertexColumn *column = (*dti); + Columns::const_iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + const qpGeomVertexColumn *column = (*ci); indent(out, indent_level + 2) << *column << " " << column->get_numeric_type() @@ -441,9 +441,9 @@ write_with_data(ostream &out, int indent_level, indent(out, indent_level) << "vertex index " << i << ":\n"; reader.set_vertex(i); - DataTypes::const_iterator dti; - for (dti = _columns.begin(); dti != _columns.end(); ++dti) { - const qpGeomVertexColumn *column = (*dti); + Columns::const_iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + const qpGeomVertexColumn *column = (*ci); int num_values = min(column->get_num_values(), 4); reader.set_column(array_index, column); const LVecBase4f &d = reader.get_data4f(); @@ -532,6 +532,19 @@ register_with_read_factory() { void qpGeomVertexArrayFormat:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritableReferenceCount::write_datagram(manager, dg); + + dg.add_uint16(_stride); + dg.add_uint16(_total_bytes); + dg.add_uint8(_pad_to); + + consider_sort_columns(); + + dg.add_uint16(_columns.size()); + Columns::iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + qpGeomVertexColumn *column = (*ci); + column->write_datagram(manager, dg); + } } //////////////////////////////////////////////////////////////////// @@ -545,6 +558,12 @@ int qpGeomVertexArrayFormat:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + Columns::iterator ci; + for (ci = _columns.begin(); ci != _columns.end(); ++ci) { + qpGeomVertexColumn *column = (*ci); + pi += column->complete_pointers(p_list + pi, manager); + } + return pi; } @@ -554,8 +573,8 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { // Description: This function is called by the BamReader's factory // when a new object of type qpGeomVertexArrayFormat is // encountered in the Bam file. It should create the -// qpGeomVertexArrayFormat and extract its information from -// the file. +// qpGeomVertexArrayFormat and extract its information +// from the file. //////////////////////////////////////////////////////////////////// TypedWritable *qpGeomVertexArrayFormat:: make_from_bam(const FactoryParams ¶ms) { @@ -579,4 +598,18 @@ make_from_bam(const FactoryParams ¶ms) { void qpGeomVertexArrayFormat:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritableReferenceCount::fillin(scan, manager); + nassertv(!_is_registered); + + _stride = scan.get_uint16(); + _total_bytes = scan.get_uint16(); + _pad_to = scan.get_uint8(); + + int num_columns = scan.get_uint16(); + _columns.reserve(num_columns); + for (int i = 0; i < num_columns; ++i) { + qpGeomVertexColumn *column = new qpGeomVertexColumn; + column->fillin(scan, manager); + _columns.push_back(column); + } + _columns_unsorted = false; } diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.h b/panda/src/gobj/qpgeomVertexArrayFormat.h index 791c876663..a851bae083 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.h +++ b/panda/src/gobj/qpgeomVertexArrayFormat.h @@ -29,6 +29,8 @@ class qpGeomVertexFormat; class qpGeomVertexData; class InternalName; class FactoryParams; +class BamWriter; +class BamReader; //////////////////////////////////////////////////////////////////// // Class : qpGeomVertexArrayFormat @@ -126,19 +128,16 @@ private: void do_register(); bool _is_registered; - const qpGeomVertexFormat *_root_format; - const qpGeomVertexFormat *_parent_format; - int _stride; int _total_bytes; int _pad_to; - typedef pvector DataTypes; - DataTypes _columns; + typedef pvector Columns; + Columns _columns; bool _columns_unsorted; - typedef pmap DataTypesByName; - DataTypesByName _columns_by_name; + typedef pmap ColumnsByName; + ColumnsByName _columns_by_name; public: static void register_with_read_factory(); diff --git a/panda/src/gobj/qpgeomVertexColumn.I b/panda/src/gobj/qpgeomVertexColumn.I index c39e750c00..30da9148dd 100644 --- a/panda/src/gobj/qpgeomVertexColumn.I +++ b/panda/src/gobj/qpgeomVertexColumn.I @@ -17,6 +17,34 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexColumn::Default Constructor +// Access: Private +// Description: Creates an invalid column. Used on when constructing +// from a bam file. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexColumn:: +qpGeomVertexColumn() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexColumn::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexColumn:: +qpGeomVertexColumn(const InternalName *name, int num_components, + NumericType numeric_type, Contents contents, + int start) : + _name(name), + _num_components(num_components), + _numeric_type(numeric_type), + _contents(contents), + _start(start) +{ + setup(); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexColumn::Copy Constructor // Access: Published diff --git a/panda/src/gobj/qpgeomVertexColumn.cxx b/panda/src/gobj/qpgeomVertexColumn.cxx index 033956618d..b2598d972c 100644 --- a/panda/src/gobj/qpgeomVertexColumn.cxx +++ b/panda/src/gobj/qpgeomVertexColumn.cxx @@ -17,26 +17,32 @@ //////////////////////////////////////////////////////////////////// #include "qpgeomVertexColumn.h" +#include "bamReader.h" +#include "bamWriter.h" //////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexColumn::Constructor +// Function: qpGeomVertexColumn::output // Access: Published // Description: //////////////////////////////////////////////////////////////////// -qpGeomVertexColumn:: -qpGeomVertexColumn(const InternalName *name, int num_components, - NumericType numeric_type, Contents contents, - int start) : - _name(name), - _num_components(num_components), - _num_values(num_components), - _numeric_type(numeric_type), - _contents(contents), - _start(start) -{ - nassertv(num_components > 0 && start >= 0); +void qpGeomVertexColumn:: +output(ostream &out) const { + out << *get_name() << "(" << get_num_components() << ")"; +} - switch (numeric_type) { +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexColumn::setup +// Access: Private +// Description: Called once at construction time (or at bam-reading +// time) to initialize the internal dependent values. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexColumn:: +setup() { + nassertv(_num_components > 0 && _start >= 0); + + _num_values = _num_components; + + switch (_numeric_type) { case NT_uint16: _component_bytes = 2; // sizeof(PN_uint16) break; @@ -60,13 +66,53 @@ qpGeomVertexColumn(const InternalName *name, int num_components, } //////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexColumn::output -// Access: Published -// Description: +// Function: qpGeomVertexColumn::write_datagram +// Access: Public +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. //////////////////////////////////////////////////////////////////// void qpGeomVertexColumn:: -output(ostream &out) const { - out << *get_name() << "(" << get_num_components() << ")"; +write_datagram(BamWriter *manager, Datagram &dg) { + manager->write_pointer(dg, _name); + dg.add_uint8(_num_components); + dg.add_uint8(_numeric_type); + dg.add_uint8(_contents); + dg.add_uint16(_start); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexColumn::complete_pointers +// Access: Public +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int qpGeomVertexColumn:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = 0; + + _name = DCAST(InternalName, p_list[pi++]); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexColumn::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new qpGeomVertexColumn. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexColumn:: +fillin(DatagramIterator &scan, BamReader *manager) { + manager->read_pointer(scan); + + _num_components = scan.get_uint8(); + _numeric_type = (NumericType)scan.get_uint8(); + _contents = (Contents)scan.get_uint8(); + _start = scan.get_uint16(); + + setup(); } ostream & diff --git a/panda/src/gobj/qpgeomVertexColumn.h b/panda/src/gobj/qpgeomVertexColumn.h index 6d14936ad3..d7fb4974bd 100644 --- a/panda/src/gobj/qpgeomVertexColumn.h +++ b/panda/src/gobj/qpgeomVertexColumn.h @@ -23,6 +23,12 @@ #include "internalName.h" #include "pointerTo.h" +class TypedWritable; +class BamWriter; +class BamReader; +class Datagram; +class DatagramIterator; + //////////////////////////////////////////////////////////////////// // Class : qpGeomVertexColumn // Description : This defines how a single column is interleaved @@ -53,9 +59,12 @@ PUBLISHED: C_morph_delta, // A delta from some base value, defining a blend shape }; +private: + INLINE qpGeomVertexColumn(); +PUBLISHED: INLINE qpGeomVertexColumn(const InternalName *name, int num_components, - NumericType numeric_type, Contents contents, - int start); + NumericType numeric_type, Contents contents, + int start); INLINE qpGeomVertexColumn(const qpGeomVertexColumn ©); INLINE void operator = (const qpGeomVertexColumn ©); @@ -83,6 +92,14 @@ public: INLINE bool operator != (const qpGeomVertexColumn &other) const; INLINE bool operator < (const qpGeomVertexColumn &other) const; +private: + void setup(); + +public: + void write_datagram(BamWriter *manager, Datagram &dg); + int complete_pointers(TypedWritable **plist, BamReader *manager); + void fillin(DatagramIterator &scan, BamReader *manager); + private: CPT(InternalName) _name; int _num_components; @@ -92,6 +109,8 @@ private: int _start; int _component_bytes; int _total_bytes; + + friend class qpGeomVertexArrayFormat; }; INLINE ostream &operator << (ostream &out, const qpGeomVertexColumn &obj); diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index ba467657e0..4444ddd39d 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -207,30 +207,6 @@ set_array(int i, const qpGeomVertexArrayData *array) { cdata->_animated_vertices_modified = UpdateSeq(); } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::modify_transform_palette -// Access: Published -// Description: Returns a modifiable pointer to the current -// TransformPalette on this vertex data, if any, or -// NULL if there is not a TransformPalette. See -// get_transform_palette(). -//////////////////////////////////////////////////////////////////// -TransformPalette *qpGeomVertexData:: -modify_transform_palette() { - // Perform copy-on-write: if the reference count on the palette is - // greater than 1, assume some other GeomVertexData has the same - // pointer, so make a copy of it first. - CDWriter cdata(_cycler); - - if (cdata->_transform_palette->get_ref_count() > 1) { - cdata->_transform_palette = new TransformPalette(*cdata->_transform_palette); - } - cdata->_modified = qpGeom::get_next_modified(); - cdata->_animated_vertices_modified = UpdateSeq(); - - return cdata->_transform_palette; -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::set_transform_palette // Access: Published @@ -242,6 +218,8 @@ modify_transform_palette() { //////////////////////////////////////////////////////////////////// void qpGeomVertexData:: set_transform_palette(const TransformPalette *palette) { + nassertv(palette == (TransformPalette *)NULL || palette->is_registered()); + CDWriter cdata(_cycler); cdata->_transform_palette = (TransformPalette *)palette; cdata->_modified = qpGeom::get_next_modified(); @@ -289,30 +267,6 @@ set_transform_blend_palette(const TransformBlendPalette *palette) { cdata->_animated_vertices_modified = UpdateSeq(); } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexData::modify_slider_table -// Access: Published -// Description: Returns a modifiable pointer to the current -// SliderTable on this vertex data, if any, or -// NULL if there is not a SliderTable. See -// get_slider_table(). -//////////////////////////////////////////////////////////////////// -SliderTable *qpGeomVertexData:: -modify_slider_table() { - // Perform copy-on-write: if the reference count on the table is - // greater than 1, assume some other GeomVertexData has the same - // pointer, so make a copy of it first. - CDWriter cdata(_cycler); - - if (cdata->_slider_table->get_ref_count() > 1) { - cdata->_slider_table = new SliderTable(*cdata->_slider_table); - } - cdata->_modified = qpGeom::get_next_modified(); - cdata->_animated_vertices_modified = UpdateSeq(); - - return cdata->_slider_table; -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::set_slider_table // Access: Published @@ -1368,7 +1322,11 @@ register_with_read_factory() { //////////////////////////////////////////////////////////////////// void qpGeomVertexData:: write_datagram(BamWriter *manager, Datagram &dg) { - TypedWritable::write_datagram(manager, dg); + TypedWritableReferenceCount::write_datagram(manager, dg); + + dg.add_string(_name); + manager->write_pointer(dg, _format); + dg.add_uint8(_usage_hint); manager->write_cdata(dg, _cycler); } @@ -1389,10 +1347,78 @@ make_from_bam(const FactoryParams ¶ms) { parse_params(params, scan, manager); object->fillin(scan, manager); + manager->register_finalize(object); return object; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int qpGeomVertexData:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + + _format = DCAST(qpGeomVertexFormat, p_list[pi++]); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::finalize +// Access: Public, Virtual +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. +//////////////////////////////////////////////////////////////////// +void qpGeomVertexData:: +finalize(BamReader *manager) { + // Now we need to register the format that we have read from the bam + // file (since it doesn't come out of the bam file automatically + // registered). This may change the format's pointer, which we + // should then update our own data to reflect. But since this may + // cause the unregistered object to destruct, we have to also tell + // the BamReader to return the new object from now on. + + // This extends to the nested array datas, as well as the transform + // palette and slider tables, as well. + + CDWriter cdata(_cycler); + + CPT(qpGeomVertexFormat) new_format = + qpGeomVertexFormat::register_format(_format); + + for (size_t i = 0; i < cdata->_arrays.size(); ++i) { + CPT(qpGeomVertexArrayFormat) new_array_format = new_format->get_array(i); + CPT(qpGeomVertexArrayFormat) old_array_format = _format->get_array(i); + nassertv(cdata->_arrays[i]->_array_format == old_array_format); + + manager->change_pointer(old_array_format, new_array_format); + cdata->_arrays[i]->_array_format = new_array_format; + } + + manager->change_pointer(_format, new_format); + _format = new_format; + + if (cdata->_transform_palette != (TransformPalette *)NULL) { + CPT(TransformPalette) new_transform_palette = + TransformPalette::register_palette(cdata->_transform_palette); + manager->change_pointer(cdata->_transform_palette, new_transform_palette); + cdata->_transform_palette = new_transform_palette; + } + + if (cdata->_slider_table != (SliderTable *)NULL) { + CPT(SliderTable) new_slider_table = + SliderTable::register_table(cdata->_slider_table); + manager->change_pointer(cdata->_slider_table, new_slider_table); + cdata->_slider_table = new_slider_table; + } +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::fillin // Access: Protected @@ -1402,7 +1428,11 @@ make_from_bam(const FactoryParams ¶ms) { //////////////////////////////////////////////////////////////////// void qpGeomVertexData:: fillin(DatagramIterator &scan, BamReader *manager) { - TypedWritable::fillin(scan, manager); + TypedWritableReferenceCount::fillin(scan, manager); + + _name = scan.get_string(); + manager->read_pointer(scan); + _usage_hint = (qpGeomUsageHint::UsageHint)scan.get_uint8(); manager->read_cdata(scan, _cycler); } @@ -1425,6 +1455,15 @@ make_copy() const { //////////////////////////////////////////////////////////////////// void qpGeomVertexData::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { + dg.add_uint16(_arrays.size()); + Arrays::const_iterator ai; + for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) { + manager->write_pointer(dg, *ai); + } + + manager->write_pointer(dg, _transform_palette); + manager->write_pointer(dg, _transform_blend_palette); + manager->write_pointer(dg, _slider_table); } //////////////////////////////////////////////////////////////////// @@ -1438,6 +1477,17 @@ int qpGeomVertexData::CData:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = CycleData::complete_pointers(p_list, manager); + Arrays::iterator ai; + for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) { + (*ai) = DCAST(qpGeomVertexArrayData, p_list[pi++]); + } + + _transform_palette = DCAST(TransformPalette, p_list[pi++]); + _transform_blend_palette = DCAST(TransformBlendPalette, p_list[pi++]); + _slider_table = DCAST(SliderTable, p_list[pi++]); + + _modified = qpGeom::get_next_modified(); + return pi; } @@ -1450,4 +1500,14 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void qpGeomVertexData::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + size_t num_arrays = scan.get_uint16(); + _arrays.reserve(num_arrays); + for (size_t i = 0; i < num_arrays; ++i) { + manager->read_pointer(scan); + _arrays.push_back(NULL); + } + + manager->read_pointer(scan); + manager->read_pointer(scan); + manager->read_pointer(scan); } diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index df5831a61d..1798477256 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -101,7 +101,6 @@ PUBLISHED: void set_array(int i, const qpGeomVertexArrayData *array); INLINE const TransformPalette *get_transform_palette() const; - TransformPalette *modify_transform_palette(); void set_transform_palette(const TransformPalette *palette); INLINE void clear_transform_palette(); @@ -111,7 +110,6 @@ PUBLISHED: INLINE void clear_transform_blend_palette(); INLINE const SliderTable *get_slider_table() const; - SliderTable *modify_slider_table(); void set_slider_table(const SliderTable *palette); INLINE void clear_slider_table(); @@ -218,9 +216,9 @@ private: virtual void fillin(DatagramIterator &scan, BamReader *manager); Arrays _arrays; - PT(TransformPalette) _transform_palette; + CPT(TransformPalette) _transform_palette; PT(TransformBlendPalette) _transform_blend_palette; - PT(SliderTable) _slider_table; + CPT(SliderTable) _slider_table; PT(qpGeomVertexData) _animated_vertices; UpdateSeq _animated_vertices_modified; UpdateSeq _modified; @@ -247,6 +245,9 @@ private: public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/gobj/qpgeomVertexFormat.I b/panda/src/gobj/qpgeomVertexFormat.I index 49480504fd..d9447bdf64 100644 --- a/panda/src/gobj/qpgeomVertexFormat.I +++ b/panda/src/gobj/qpgeomVertexFormat.I @@ -52,8 +52,8 @@ is_registered() const { // this point on. //////////////////////////////////////////////////////////////////// INLINE CPT(qpGeomVertexFormat) qpGeomVertexFormat:: -register_format(qpGeomVertexFormat *format) { - return get_registry()->register_format(format); +register_format(const qpGeomVertexFormat *format) { + return get_registry()->register_format((qpGeomVertexFormat *)format); } //////////////////////////////////////////////////////////////////// @@ -63,8 +63,8 @@ register_format(qpGeomVertexFormat *format) { // one-array vertex format from the array definition. //////////////////////////////////////////////////////////////////// INLINE CPT(qpGeomVertexFormat) qpGeomVertexFormat:: -register_format(qpGeomVertexArrayFormat *format) { - return get_registry()->register_format(format); +register_format(const qpGeomVertexArrayFormat *format) { + return register_format(new qpGeomVertexFormat(format)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexFormat.cxx b/panda/src/gobj/qpgeomVertexFormat.cxx index 7ff94a7f15..ea0394b846 100644 --- a/panda/src/gobj/qpgeomVertexFormat.cxx +++ b/panda/src/gobj/qpgeomVertexFormat.cxx @@ -44,7 +44,7 @@ qpGeomVertexFormat() : // Description: //////////////////////////////////////////////////////////////////// qpGeomVertexFormat:: -qpGeomVertexFormat(qpGeomVertexArrayFormat *array_format) : +qpGeomVertexFormat(const qpGeomVertexArrayFormat *array_format) : _is_registered(false) { add_array(array_format); @@ -120,10 +120,10 @@ modify_array(int array) { // registered. //////////////////////////////////////////////////////////////////// void qpGeomVertexFormat:: -set_array(int array, qpGeomVertexArrayFormat *format) { +set_array(int array, const qpGeomVertexArrayFormat *format) { nassertv(!_is_registered); nassertv(array >= 0 && array < (int)_arrays.size()); - _arrays[array] = format; + _arrays[array] = (qpGeomVertexArrayFormat *)format; } //////////////////////////////////////////////////////////////////// @@ -154,11 +154,11 @@ remove_array(int array) { // registered. //////////////////////////////////////////////////////////////////// int qpGeomVertexFormat:: -add_array(qpGeomVertexArrayFormat *array_format) { +add_array(const qpGeomVertexArrayFormat *array_format) { nassertr(!_is_registered, -1); int new_array = (int)_arrays.size(); - _arrays.push_back(array_format); + _arrays.push_back((qpGeomVertexArrayFormat *)array_format); return new_array; } @@ -174,11 +174,11 @@ add_array(qpGeomVertexArrayFormat *array_format) { // registered. //////////////////////////////////////////////////////////////////// void qpGeomVertexFormat:: -insert_array(int array, qpGeomVertexArrayFormat *array_format) { +insert_array(int array, const qpGeomVertexArrayFormat *array_format) { nassertv(!_is_registered); nassertv(array >= 0 && array <= (int)_arrays.size()); - _arrays.insert(_arrays.begin() + array, array_format); + _arrays.insert(_arrays.begin() + array, (qpGeomVertexArrayFormat *)array_format); } //////////////////////////////////////////////////////////////////// @@ -516,7 +516,7 @@ do_register() { result = _columns_by_name.insert(DataTypesByName::value_type(column->get_name(), DataTypeRecord())); if (!result.second) { gobj_cat.warning() - << "Column " << column->get_name() << " repeated in format.\n"; + << "Column " << *column->get_name() << " repeated in format.\n"; } else { DataTypeRecord &record = (*result.first).second; record._array_index = array; @@ -627,6 +627,14 @@ register_with_read_factory() { void qpGeomVertexFormat:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritableReferenceCount::write_datagram(manager, dg); + + _animation.write_datagram(manager, dg); + + dg.add_uint16(_arrays.size()); + Arrays::const_iterator ai; + for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) { + manager->write_pointer(dg, *ai); + } } //////////////////////////////////////////////////////////////////// @@ -640,6 +648,11 @@ int qpGeomVertexFormat:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + Arrays::iterator ai; + for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) { + (*ai) = DCAST(qpGeomVertexArrayFormat, p_list[pi++]); + } + return pi; } @@ -649,8 +662,8 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { // Description: This function is called by the BamReader's factory // when a new object of type qpGeomVertexFormat is // encountered in the Bam file. It should create the -// qpGeomVertexFormat and extract its information from -// the file. +// qpGeomVertexFormat and extract its information +// from the file. //////////////////////////////////////////////////////////////////// TypedWritable *qpGeomVertexFormat:: make_from_bam(const FactoryParams ¶ms) { @@ -674,6 +687,15 @@ make_from_bam(const FactoryParams ¶ms) { void qpGeomVertexFormat:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritableReferenceCount::fillin(scan, manager); + + _animation.fillin(scan, manager); + + int num_arrays = scan.get_uint16(); + _arrays.reserve(num_arrays); + for (int i = 0; i < num_arrays; i++) { + manager->read_pointer(scan); + _arrays.push_back(NULL); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexFormat.h b/panda/src/gobj/qpgeomVertexFormat.h index 7a3785bf3d..9c4607100b 100644 --- a/panda/src/gobj/qpgeomVertexFormat.h +++ b/panda/src/gobj/qpgeomVertexFormat.h @@ -67,14 +67,14 @@ class qpGeomMunger; class EXPCL_PANDA qpGeomVertexFormat : public TypedWritableReferenceCount { PUBLISHED: qpGeomVertexFormat(); - qpGeomVertexFormat(qpGeomVertexArrayFormat *array_format); + qpGeomVertexFormat(const qpGeomVertexArrayFormat *array_format); qpGeomVertexFormat(const qpGeomVertexFormat ©); void operator = (const qpGeomVertexFormat ©); virtual ~qpGeomVertexFormat(); INLINE bool is_registered() const; - INLINE static CPT(qpGeomVertexFormat) register_format(qpGeomVertexFormat *format); - INLINE static CPT(qpGeomVertexFormat) register_format(qpGeomVertexArrayFormat *format); + INLINE static CPT(qpGeomVertexFormat) register_format(const qpGeomVertexFormat *format); + INLINE static CPT(qpGeomVertexFormat) register_format(const qpGeomVertexArrayFormat *format); INLINE const qpGeomVertexAnimationSpec &get_animation() const; INLINE void set_animation(const qpGeomVertexAnimationSpec &animation); @@ -82,10 +82,10 @@ PUBLISHED: INLINE int get_num_arrays() const; INLINE const qpGeomVertexArrayFormat *get_array(int array) const; qpGeomVertexArrayFormat *modify_array(int array); - void set_array(int array, qpGeomVertexArrayFormat *format); + void set_array(int array, const qpGeomVertexArrayFormat *format); void remove_array(int array); - int add_array(qpGeomVertexArrayFormat *array_format); - void insert_array(int array, qpGeomVertexArrayFormat *array_format); + int add_array(const qpGeomVertexArrayFormat *array_format); + void insert_array(int array, const qpGeomVertexArrayFormat *array_format); void clear_arrays(); int get_num_columns() const; diff --git a/panda/src/gobj/sliderTable.I b/panda/src/gobj/sliderTable.I index 2e418a9957..6dd152a91c 100644 --- a/panda/src/gobj/sliderTable.I +++ b/panda/src/gobj/sliderTable.I @@ -48,7 +48,7 @@ is_registered() const { // this point on. //////////////////////////////////////////////////////////////////// INLINE CPT(SliderTable) SliderTable:: -register_table(SliderTable *table) { +register_table(const SliderTable *table) { // We don't actually bother adding the table object to a registry. // This means there may be multiple copies of identical registered // SliderTables. Big deal. We can always go back and make a @@ -57,7 +57,7 @@ register_table(SliderTable *table) { return table; } - table->do_register(); + ((SliderTable *)table)->do_register(); return table; } diff --git a/panda/src/gobj/sliderTable.cxx b/panda/src/gobj/sliderTable.cxx index 7b062fa425..3997e475bf 100644 --- a/panda/src/gobj/sliderTable.cxx +++ b/panda/src/gobj/sliderTable.cxx @@ -166,9 +166,38 @@ void SliderTable:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); + dg.add_uint16(_sliders.size()); + Sliders::const_iterator si; + for (si = _sliders.begin(); si != _sliders.end(); ++si) { + manager->write_pointer(dg, (*si).first); + manager->write_pointer(dg, (*si).second); + } + manager->write_cdata(dg, _cycler); } +//////////////////////////////////////////////////////////////////// +// Function: SliderTable::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int SliderTable:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + + for (size_t i = 0; i < _num_sliders; ++i) { + CPT(InternalName) name = DCAST(InternalName, p_list[pi++]); + PT(VertexSlider) slider = DCAST(VertexSlider, p_list[pi++]); + + bool inserted = _sliders.insert(Sliders::value_type(name, slider)).second; + nassertr(inserted, pi); + } + + return pi; +} + //////////////////////////////////////////////////////////////////// // Function: SliderTable::make_from_bam // Access: Protected, Static @@ -200,6 +229,12 @@ void SliderTable:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); + _num_sliders = scan.get_uint16(); + for (size_t i = 0; i < _num_sliders; ++i) { + manager->read_pointer(scan); + manager->read_pointer(scan); + } + manager->read_cdata(scan, _cycler); } @@ -223,20 +258,6 @@ void SliderTable::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { } -//////////////////////////////////////////////////////////////////// -// Function: SliderTable::CData::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int SliderTable::CData:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); - - return pi; -} - //////////////////////////////////////////////////////////////////// // Function: SliderTable::CData::fillin // Access: Public, Virtual @@ -246,4 +267,5 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void SliderTable::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + _modified = VertexTransform::get_next_modified(); } diff --git a/panda/src/gobj/sliderTable.h b/panda/src/gobj/sliderTable.h index 1e81830052..c8f8fcf3ef 100644 --- a/panda/src/gobj/sliderTable.h +++ b/panda/src/gobj/sliderTable.h @@ -53,7 +53,7 @@ PUBLISHED: virtual ~SliderTable(); INLINE bool is_registered() const; - INLINE static CPT(SliderTable) register_table(SliderTable *table); + INLINE static CPT(SliderTable) register_table(const SliderTable *table); INLINE const VertexSlider *get_slider(const InternalName *name) const; INLINE bool has_slider(const InternalName *name) const; @@ -73,9 +73,12 @@ private: private: bool _is_registered; - typedef pmap< const InternalName *, PT(VertexSlider) > Sliders; + typedef pmap< CPT(InternalName), PT(VertexSlider) > Sliders; Sliders _sliders; + // This is only filled in while reading from the bam stream. + size_t _num_sliders; + // This is the data that must be cycled between pipeline stages. class EXPCL_PANDA CData : public CycleData { public: @@ -83,7 +86,6 @@ private: INLINE CData(const CData ©); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); virtual void fillin(DatagramIterator &scan, BamReader *manager); UpdateSeq _modified; @@ -96,6 +98,7 @@ private: public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/gobj/transformBlend.cxx b/panda/src/gobj/transformBlend.cxx index 652062a790..db30ba1d0b 100644 --- a/panda/src/gobj/transformBlend.cxx +++ b/panda/src/gobj/transformBlend.cxx @@ -251,6 +251,13 @@ clear_result() { //////////////////////////////////////////////////////////////////// void TransformBlend:: write_datagram(BamWriter *manager, Datagram &dg) const { + dg.add_uint16(_entries.size()); + + Entries::const_iterator ei; + for (ei = _entries.begin(); ei != _entries.end(); ++ei) { + manager->write_pointer(dg, (*ei)._transform); + dg.add_float32((*ei)._weight); + } } //////////////////////////////////////////////////////////////////// @@ -262,7 +269,18 @@ write_datagram(BamWriter *manager, Datagram &dg) const { //////////////////////////////////////////////////////////////////// int TransformBlend:: complete_pointers(TypedWritable **p_list, BamReader *manager) { - return 0; + int pi = 0; + + Entries::iterator ei; + for (ei = _entries.begin(); ei != _entries.end(); ++ei) { + (*ei)._transform = DCAST(VertexTransform, p_list[pi++]); + } + + // Now that we have actual pointers, we can sort the list of + // entries. + _entries.sort(); + + return pi; } //////////////////////////////////////////////////////////////////// @@ -274,6 +292,14 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void TransformBlend:: fillin(DatagramIterator &scan, BamReader *manager) { + size_t num_entries = scan.get_uint16(); + _entries.reserve(num_entries); + for (size_t i = 0; i < num_entries; ++i) { + TransformEntry entry; + manager->read_pointer(scan); + entry._weight = scan.get_float32(); + _entries.push_back(entry); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/transformBlendPalette.cxx b/panda/src/gobj/transformBlendPalette.cxx index 0bd1b718a0..5b5bad302f 100644 --- a/panda/src/gobj/transformBlendPalette.cxx +++ b/panda/src/gobj/transformBlendPalette.cxx @@ -223,6 +223,12 @@ void TransformBlendPalette:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); + dg.add_uint16(_blends.size()); + Blends::const_iterator bi; + for (bi = _blends.begin(); bi != _blends.end(); ++bi) { + (*bi).write_datagram(manager, dg); + } + manager->write_cdata(dg, _cycler); } @@ -236,6 +242,12 @@ write_datagram(BamWriter *manager, Datagram &dg) { int TransformBlendPalette:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = TypedWritable::complete_pointers(p_list, manager); + + Blends::iterator bi; + for (bi = _blends.begin(); bi != _blends.end(); ++bi) { + pi += (*bi).complete_pointers(p_list + pi, manager); + } + return pi; } @@ -270,6 +282,15 @@ void TransformBlendPalette:: fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); + size_t num_blends = scan.get_uint16(); + _blends.reserve(num_blends); + size_t i; + for (i = 0; i < num_blends; ++i) { + TransformBlend blend; + blend.fillin(scan, manager); + _blends.push_back(blend); + } + manager->read_cdata(scan, _cycler); } @@ -282,3 +303,26 @@ CycleData *TransformBlendPalette::CData:: make_copy() const { return new CData(*this); } + +//////////////////////////////////////////////////////////////////// +// Function: TransformBlendPalette::CData::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void TransformBlendPalette::CData:: +write_datagram(BamWriter *manager, Datagram &dg) const { +} + +//////////////////////////////////////////////////////////////////// +// Function: TransformBlendPalette::CData::fillin +// Access: Public, Virtual +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new TransformBlendPalette. +//////////////////////////////////////////////////////////////////// +void TransformBlendPalette::CData:: +fillin(DatagramIterator &scan, BamReader *manager) { + _modified = VertexTransform::get_next_modified(); + _global_modified = VertexTransform::get_global_modified(); +} diff --git a/panda/src/gobj/transformBlendPalette.h b/panda/src/gobj/transformBlendPalette.h index 4847b829b4..4c9ed5d533 100644 --- a/panda/src/gobj/transformBlendPalette.h +++ b/panda/src/gobj/transformBlendPalette.h @@ -99,6 +99,8 @@ private: INLINE CData(); INLINE CData(const CData ©); virtual CycleData *make_copy() const; + virtual void write_datagram(BamWriter *manager, Datagram &dg) const; + virtual void fillin(DatagramIterator &scan, BamReader *manager); UpdateSeq _modified; UpdateSeq _global_modified; diff --git a/panda/src/gobj/transformPalette.I b/panda/src/gobj/transformPalette.I index a51d0566d1..e871f4adcf 100644 --- a/panda/src/gobj/transformPalette.I +++ b/panda/src/gobj/transformPalette.I @@ -48,7 +48,7 @@ is_registered() const { // this point on. //////////////////////////////////////////////////////////////////// INLINE CPT(TransformPalette) TransformPalette:: -register_palette(TransformPalette *palette) { +register_palette(const TransformPalette *palette) { // We don't actually bother adding the palette object to a registry. // This means there may be multiple copies of identical registered // TransformPalettes. Big deal. We can always go back and make a @@ -57,7 +57,7 @@ register_palette(TransformPalette *palette) { return palette; } - palette->do_register(); + ((TransformPalette *)palette)->do_register(); return palette; } diff --git a/panda/src/gobj/transformPalette.cxx b/panda/src/gobj/transformPalette.cxx index ce79d2ade7..25c34aaac7 100644 --- a/panda/src/gobj/transformPalette.cxx +++ b/panda/src/gobj/transformPalette.cxx @@ -176,11 +176,38 @@ register_with_read_factory() { //////////////////////////////////////////////////////////////////// void TransformPalette:: write_datagram(BamWriter *manager, Datagram &dg) { - TypedWritable::write_datagram(manager, dg); + TypedWritableReferenceCount::write_datagram(manager, dg); + + dg.add_uint16(_transforms.size()); + for (Transforms::const_iterator ti = _transforms.begin(); + ti != _transforms.end(); + ++ti) { + manager->write_pointer(dg, *ti); + } manager->write_cdata(dg, _cycler); } +//////////////////////////////////////////////////////////////////// +// Function: TransformPalette::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int TransformPalette:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager); + + for (Transforms::iterator ti = _transforms.begin(); + ti != _transforms.end(); + ++ti) { + (*ti) = DCAST(VertexTransform, p_list[pi++]); + } + + return pi; +} + //////////////////////////////////////////////////////////////////// // Function: TransformPalette::make_from_bam // Access: Protected, Static @@ -210,7 +237,14 @@ make_from_bam(const FactoryParams ¶ms) { //////////////////////////////////////////////////////////////////// void TransformPalette:: fillin(DatagramIterator &scan, BamReader *manager) { - TypedWritable::fillin(scan, manager); + TypedWritableReferenceCount::fillin(scan, manager); + + size_t num_transforms = scan.get_uint16(); + _transforms.reserve(num_transforms); + for (size_t i = 0; i < num_transforms; ++i) { + manager->read_pointer(scan); + _transforms.push_back(NULL); + } manager->read_cdata(scan, _cycler); } @@ -235,20 +269,6 @@ void TransformPalette::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { } -//////////////////////////////////////////////////////////////////// -// Function: TransformPalette::CData::complete_pointers -// Access: Public, Virtual -// Description: Receives an array of pointers, one for each time -// manager->read_pointer() was called in fillin(). -// Returns the number of pointers processed. -//////////////////////////////////////////////////////////////////// -int TransformPalette::CData:: -complete_pointers(TypedWritable **p_list, BamReader *manager) { - int pi = CycleData::complete_pointers(p_list, manager); - - return pi; -} - //////////////////////////////////////////////////////////////////// // Function: TransformPalette::CData::fillin // Access: Public, Virtual @@ -258,4 +278,5 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void TransformPalette::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + _modified = VertexTransform::get_next_modified(); } diff --git a/panda/src/gobj/transformPalette.h b/panda/src/gobj/transformPalette.h index e88a82f244..b8d6b048f5 100644 --- a/panda/src/gobj/transformPalette.h +++ b/panda/src/gobj/transformPalette.h @@ -52,7 +52,7 @@ PUBLISHED: virtual ~TransformPalette(); INLINE bool is_registered() const; - INLINE static CPT(TransformPalette) register_palette(TransformPalette *palette); + INLINE static CPT(TransformPalette) register_palette(const TransformPalette *palette); INLINE int get_num_transforms() const; INLINE const VertexTransform *get_transform(int n) const; @@ -82,7 +82,6 @@ private: INLINE CData(const CData ©); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; - virtual int complete_pointers(TypedWritable **plist, BamReader *manager); virtual void fillin(DatagramIterator &scan, BamReader *manager); UpdateSeq _modified; @@ -95,6 +94,7 @@ private: public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/gobj/userVertexSlider.cxx b/panda/src/gobj/userVertexSlider.cxx index 4c0c81b1e4..54d959b00f 100644 --- a/panda/src/gobj/userVertexSlider.cxx +++ b/panda/src/gobj/userVertexSlider.cxx @@ -131,6 +131,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { //////////////////////////////////////////////////////////////////// void UserVertexSlider::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { + dg.add_float32(_slider); } //////////////////////////////////////////////////////////////////// @@ -142,4 +143,5 @@ write_datagram(BamWriter *manager, Datagram &dg) const { //////////////////////////////////////////////////////////////////// void UserVertexSlider::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + _slider = scan.get_float32(); } diff --git a/panda/src/gobj/userVertexTransform.cxx b/panda/src/gobj/userVertexTransform.cxx index aea489251b..7c875a9783 100644 --- a/panda/src/gobj/userVertexTransform.cxx +++ b/panda/src/gobj/userVertexTransform.cxx @@ -130,6 +130,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { //////////////////////////////////////////////////////////////////// void UserVertexTransform::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { + _matrix.write_datagram(dg); } //////////////////////////////////////////////////////////////////// @@ -141,4 +142,5 @@ write_datagram(BamWriter *manager, Datagram &dg) const { //////////////////////////////////////////////////////////////////// void UserVertexTransform::CData:: fillin(DatagramIterator &scan, BamReader *manager) { + _matrix.read_datagram(scan); } diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 54774ce12f..ff08b43d56 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -399,12 +399,13 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::finalize // Access: Public, Virtual -// Description: Method to ensure that any necessary clean up tasks -// that have to be performed by this object are performed +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void RenderAttrib:: -finalize() { - // Unref the pointer that we explicitly reffed in make_from_bam(). +finalize(BamReader *) { + // Unref the pointer that we explicitly reffed in change_this(). unref(); // We should never get back to zero after unreffing our own count, diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index 58437bd86d..7a65a99a99 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -112,7 +112,7 @@ private: public: virtual void write_datagram(BamWriter *manager, Datagram &dg); static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *new_from_bam(RenderAttrib *attrib, BamReader *manager); diff --git a/panda/src/pgraph/renderEffect.cxx b/panda/src/pgraph/renderEffect.cxx index 5717b0aa65..5309cc50e1 100644 --- a/panda/src/pgraph/renderEffect.cxx +++ b/panda/src/pgraph/renderEffect.cxx @@ -397,12 +397,13 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { //////////////////////////////////////////////////////////////////// // Function: RenderEffect::finalize // Access: Public, Virtual -// Description: Method to ensure that any necessary clean up tasks -// that have to be performed by this object are performed +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void RenderEffect:: -finalize() { - // Unref the pointer that we explicitly reffed in make_from_bam(). +finalize(BamReader *) { + // Unref the pointer that we explicitly reffed in change_this(). unref(); // We should never get back to zero after unreffing our own count, diff --git a/panda/src/pgraph/renderEffect.h b/panda/src/pgraph/renderEffect.h index ed2b0d189f..9c06a89925 100644 --- a/panda/src/pgraph/renderEffect.h +++ b/panda/src/pgraph/renderEffect.h @@ -104,7 +104,7 @@ private: public: virtual void write_datagram(BamWriter *manager, Datagram &dg); static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *new_from_bam(RenderEffect *effect, BamReader *manager); diff --git a/panda/src/pgraph/renderEffects.cxx b/panda/src/pgraph/renderEffects.cxx index 3a55d1b129..fe7847f68b 100644 --- a/panda/src/pgraph/renderEffects.cxx +++ b/panda/src/pgraph/renderEffects.cxx @@ -735,8 +735,8 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { // have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void RenderEffects:: -finalize() { - // Unref the pointer that we explicitly reffed in make_from_bam(). +finalize(BamReader *) { + // Unref the pointer that we explicitly reffed in change_this(). unref(); // We should never get back to zero after unreffing our own count, diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h index b5fcfa3433..9ba914c222 100644 --- a/panda/src/pgraph/renderEffects.h +++ b/panda/src/pgraph/renderEffects.h @@ -161,7 +161,7 @@ public: virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual int complete_pointers(TypedWritable **plist, BamReader *manager); static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index a97ff423fe..f751322c4e 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1696,8 +1696,8 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { // have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void RenderState:: -finalize() { - // Unref the pointer that we explicitly reffed in make_from_bam(). +finalize(BamReader *) { + // Unref the pointer that we explicitly reffed in change_this(). unref(); // We should never get back to zero after unreffing our own count, diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index db75a54043..08851ace9d 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -267,7 +267,7 @@ public: virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual int complete_pointers(TypedWritable **plist, BamReader *manager); static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index 87012fb592..af5bb7dfca 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -1598,8 +1598,8 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { // have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void TransformState:: -finalize() { - // Unref the pointer that we explicitly reffed in make_from_bam(). +finalize(BamReader *) { + // Unref the pointer that we explicitly reffed in change_this(). unref(); // We should never get back to zero after unreffing our own count, diff --git a/panda/src/pgraph/transformState.h b/panda/src/pgraph/transformState.h index 2c3c432fbf..56ba25ae49 100644 --- a/panda/src/pgraph/transformState.h +++ b/panda/src/pgraph/transformState.h @@ -247,7 +247,7 @@ public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index bcbea131ca..3129919ac8 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -293,7 +293,19 @@ resolve() { // Does the pointer need to change? if (created_obj._change_this != NULL) { - created_obj._ptr = created_obj._change_this(object_ptr, this); + TypedWritable *new_ptr = created_obj._change_this(object_ptr, this); + if (new_ptr != object_ptr) { + // Also update the reverse + vector_int &old_refs = _created_objs_by_pointer[object_ptr]; + vector_int &new_refs = _created_objs_by_pointer[new_ptr]; + for (vector_int::const_iterator oi = old_refs.begin(); + oi != old_refs.end(); + ++oi) { + new_refs.push_back(*oi); + } + _created_objs_by_pointer.erase(object_ptr); + } + created_obj._ptr = new_ptr; created_obj._change_this = NULL; } any_completed_this_pass = true; @@ -356,6 +368,52 @@ resolve() { return all_completed; } +//////////////////////////////////////////////////////////////////// +// Function: BamReader::change_pointer +// Access: Public +// Description: Indicates that an object recently read from the bam +// stream should be replaced with a new object. Any +// future occurrences of the original object in the +// stream will henceforth return the new object instead. +// +// The return value is true if the replacement was +// successfully made, or false if the object was not +// read from the stream (or if change_pointer had +// already been called on it). +//////////////////////////////////////////////////////////////////// +bool BamReader:: +change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer) { + if (orig_pointer == new_pointer) { + return false; + } + CreatedObjsByPointer::iterator ci = _created_objs_by_pointer.find(orig_pointer); + if (ci == _created_objs_by_pointer.end()) { + // No record of this object. + return false; + } + + const vector_int &old_refs = (*ci).second; + vector_int &new_refs = _created_objs_by_pointer[new_pointer]; + + for (vector_int::const_iterator oi = old_refs.begin(); + oi != old_refs.end(); + ++oi) { + int object_id = (*oi); + + CreatedObjs::iterator ci = _created_objs.find(object_id); + nassertr(ci != _created_objs.end(), false); + nassertr((*ci).second._ptr == orig_pointer, false); + + (*ci).second._ptr = (TypedWritable *)new_pointer; + new_refs.push_back(object_id); + } + + _created_objs_by_pointer.erase(ci); + + return true; +} + + //////////////////////////////////////////////////////////////////// // Function: BamReader::read_handle // Access: Public @@ -546,10 +604,9 @@ read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler) { // all the objects and pointers in the Bam file are // completely read. // -// This provides a hook for objects (like Characters) -// that need to do any additional finalization work -// after all of their related pointers are guaranteed to -// be filled in. +// This provides a hook for objects that need to do any +// additional finalization work after all of their +// related pointers are guaranteed to be filled in. //////////////////////////////////////////////////////////////////// void BamReader:: register_finalize(TypedWritable *whom) { @@ -613,7 +670,7 @@ finalize_now(TypedWritable *whom) { Finalize::iterator fi = _finalize_list.find(whom); if (fi != _finalize_list.end()) { _finalize_list.erase(fi); - whom->finalize(); + whom->finalize(this); } } @@ -717,6 +774,7 @@ free_object_ids(DatagramIterator &scan) { << " before removing from table.\n"; } + _created_objs_by_pointer.erase((*ci).second._ptr); _created_objs.erase(ci); } } @@ -875,6 +933,8 @@ p_read_object() { } } + _created_objs_by_pointer[created_obj._ptr].push_back(object_id); + // Just some sanity checks if (object == (TypedWritable *)NULL) { if (bam_cat.is_debug()) { @@ -1059,7 +1119,7 @@ finalize() { TypedWritable *object = (*fi); nassertv(object != (TypedWritable *)NULL); _finalize_list.erase(fi); - object->finalize(); + object->finalize(this); fi = _finalize_list.begin(); } diff --git a/panda/src/putil/bamReader.h b/panda/src/putil/bamReader.h index e9d78d5cf8..1304f4929a 100644 --- a/panda/src/putil/bamReader.h +++ b/panda/src/putil/bamReader.h @@ -105,6 +105,8 @@ public: INLINE bool is_eof() const; bool resolve(); + bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer); + INLINE int get_file_major_ver() const; INLINE int get_file_minor_ver() const; @@ -184,6 +186,10 @@ private: // if we are within a read_cdata() call. PipelineCyclerBase *_reading_cycler; + // This is the reverse lookup into the above map. + typedef phash_map CreatedObjsByPointer; + CreatedObjsByPointer _created_objs_by_pointer; + // This records all the objects that still need their pointers // completed, along with the object ID's of the pointers they need, // in the order in which read_pointer() was called, so that we may diff --git a/panda/src/putil/cycleDataReader.I b/panda/src/putil/cycleDataReader.I index 3cdbc8d76d..4aecc679a6 100644 --- a/panda/src/putil/cycleDataReader.I +++ b/panda/src/putil/cycleDataReader.I @@ -32,6 +32,7 @@ CycleDataReader(const PipelineCycler &cycler) : { _pointer = _cycler->read(); _write_pointer = (CycleDataType *)NULL; + nassertv(_pointer != (const CycleDataType *)NULL); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/putil/cycleDataWriter.I b/panda/src/putil/cycleDataWriter.I index c24aec3b8f..bcd6b5bbb0 100644 --- a/panda/src/putil/cycleDataWriter.I +++ b/panda/src/putil/cycleDataWriter.I @@ -31,6 +31,7 @@ CycleDataWriter(PipelineCycler &cycler) : _cycler(&cycler) { _pointer = _cycler->write(); + nassertv(_pointer != (CycleDataType *)NULL); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/putil/typedWritable.cxx b/panda/src/putil/typedWritable.cxx index 9104738ca6..5f4a427697 100644 --- a/panda/src/putil/typedWritable.cxx +++ b/panda/src/putil/typedWritable.cxx @@ -83,7 +83,7 @@ complete_pointers(TypedWritable **, BamReader *) { // have been read and all pointers have been completed. //////////////////////////////////////////////////////////////////// void TypedWritable:: -finalize() { +finalize(BamReader *) { } diff --git a/panda/src/putil/typedWritable.h b/panda/src/putil/typedWritable.h index 6ba41e0174..8474a2d839 100644 --- a/panda/src/putil/typedWritable.h +++ b/panda/src/putil/typedWritable.h @@ -50,7 +50,7 @@ public: virtual int complete_pointers(TypedWritable **p_list, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: void fillin(DatagramIterator &scan, BamReader *manager); diff --git a/pandatool/src/palettizer/paletteGroup.cxx b/pandatool/src/palettizer/paletteGroup.cxx index 602e60a7eb..6f6659be68 100644 --- a/pandatool/src/palettizer/paletteGroup.cxx +++ b/pandatool/src/palettizer/paletteGroup.cxx @@ -685,7 +685,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { // other pointers being valid. //////////////////////////////////////////////////////////////////// void PaletteGroup:: -finalize() { +finalize(BamReader *) { // Now we can copy the pages into the actual map. pvector::const_iterator pi; for (pi = _load_pages.begin(); pi != _load_pages.end(); ++pi) { diff --git a/pandatool/src/palettizer/paletteGroup.h b/pandatool/src/palettizer/paletteGroup.h index 30ca7262b3..e5e73466c9 100644 --- a/pandatool/src/palettizer/paletteGroup.h +++ b/pandatool/src/palettizer/paletteGroup.h @@ -110,7 +110,7 @@ public: virtual void write_datagram(BamWriter *writer, Datagram &datagram); virtual int complete_pointers(TypedWritable **p_list, BamReader *manager); - virtual void finalize(); + virtual void finalize(BamReader *manager); protected: static TypedWritable *make_PaletteGroup(const FactoryParams ¶ms);