further fixes to bam loader ordering
This commit is contained in:
parent
59916499a9
commit
0ebafd6c75
|
|
@ -623,7 +623,6 @@ fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
|
|||
} else {
|
||||
// Now, the array data is just stored directly.
|
||||
size_t size = scan.get_uint32();
|
||||
|
||||
_buffer.unclean_realloc(size);
|
||||
|
||||
const unsigned char *source_data =
|
||||
|
|
|
|||
|
|
@ -1536,6 +1536,21 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::require_fully_complete
|
||||
// Access: Public, Virtual
|
||||
// Description: Some objects require all of their nested pointers to
|
||||
// have been completed before the objects themselves can
|
||||
// be completed. If this is the case, override this
|
||||
// method to return true, and be careful with circular
|
||||
// references (which would make the object unreadable
|
||||
// from a bam file).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexData::
|
||||
require_fully_complete() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::finalize
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -1703,7 +1718,8 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
// a SparseArray for each of them that reflects the complete
|
||||
// number of rows in the data.
|
||||
SparseArray all_rows;
|
||||
all_rows.set_range(0, _arrays[0].get_read_pointer()->get_num_rows());
|
||||
CPT(GeomVertexArrayData) adata = _arrays[0].get_read_pointer();
|
||||
all_rows.set_range(0, adata->get_num_rows());
|
||||
|
||||
if (_slider_table != (SliderTable *)NULL) {
|
||||
int num_sliders = _slider_table->get_num_sliders();
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ public:
|
|||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
virtual bool require_fully_complete() const;
|
||||
|
||||
virtual void finalize(BamReader *manager);
|
||||
|
||||
|
|
|
|||
|
|
@ -301,35 +301,11 @@ resolve() {
|
|||
all_completed = true;
|
||||
any_completed_this_pass = false;
|
||||
|
||||
// First do the PipelineCycler objects.
|
||||
CyclerPointers::iterator ci;
|
||||
ci = _cycler_pointers.begin();
|
||||
while (ci != _cycler_pointers.end()) {
|
||||
PipelineCyclerBase *cycler = (*ci).first;
|
||||
const vector_int &pointer_ids = (*ci).second;
|
||||
|
||||
if (resolve_cycler_pointers(cycler, pointer_ids)) {
|
||||
// Now remove this cycler from the list of things that need
|
||||
// completion. We have to be a bit careful when deleting things
|
||||
// from the STL container while we are traversing it.
|
||||
CyclerPointers::iterator old = ci;
|
||||
++ci;
|
||||
_cycler_pointers.erase(old);
|
||||
any_completed_this_pass = true;
|
||||
|
||||
} else {
|
||||
// Couldn't complete this cycler yet; it'll wait for next time.
|
||||
++ci;
|
||||
all_completed = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now do the main objects.
|
||||
ObjectPointers::iterator oi;
|
||||
oi = _object_pointers.begin();
|
||||
while (oi != _object_pointers.end()) {
|
||||
int object_id = (*oi).first;
|
||||
const vector_int &pointer_ids = (*oi).second;
|
||||
PointerReference &pref = (*oi).second;
|
||||
|
||||
CreatedObjs::iterator ci = _created_objs.find(object_id);
|
||||
nassertr(ci != _created_objs.end(), false);
|
||||
|
|
@ -338,7 +314,7 @@ resolve() {
|
|||
|
||||
TypedWritable *object_ptr = created_obj._ptr;
|
||||
|
||||
if (resolve_object_pointers(object_ptr, pointer_ids)) {
|
||||
if (resolve_object_pointers(object_ptr, pref)) {
|
||||
// Now remove this object from the list of things that need
|
||||
// completion. We have to be a bit careful when deleting things
|
||||
// from the STL container while we are traversing it.
|
||||
|
|
@ -574,12 +550,13 @@ read_pointer(DatagramIterator &scan) {
|
|||
// Read the object ID, and associate it with the requesting object.
|
||||
int object_id = read_object_id(scan);
|
||||
|
||||
PointerReference &pref = _object_pointers[requestor_id];
|
||||
if (_reading_cycler == (PipelineCyclerBase *)NULL) {
|
||||
// This is not being read within a read_cdata() call.
|
||||
_object_pointers[requestor_id].push_back(object_id);
|
||||
pref._objects.push_back(object_id);
|
||||
} else {
|
||||
// This *is* being read within a read_cdata() call.
|
||||
_cycler_pointers[_reading_cycler].push_back(object_id);
|
||||
pref._cycler_pointers[_reading_cycler].push_back(object_id);
|
||||
}
|
||||
|
||||
// If the object ID is zero (which indicates a NULL pointer), we
|
||||
|
|
@ -1054,7 +1031,39 @@ p_read_object() {
|
|||
// and returns true; otherwise, returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BamReader::
|
||||
resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
|
||||
resolve_object_pointers(TypedWritable *object,
|
||||
BamReader::PointerReference &pref) {
|
||||
// Some objects further require all of their nested objects to have
|
||||
// been completed (i.e. complete_pointers has been called on each
|
||||
// nested object) before they can themselves be completed.
|
||||
bool require_fully_complete = object->require_fully_complete();
|
||||
|
||||
// First do the PipelineCycler objects.
|
||||
CyclerPointers::iterator ci;
|
||||
ci = pref._cycler_pointers.begin();
|
||||
while (ci != pref._cycler_pointers.end()) {
|
||||
PipelineCyclerBase *cycler = (*ci).first;
|
||||
const vector_int &pointer_ids = (*ci).second;
|
||||
|
||||
if (resolve_cycler_pointers(cycler, pointer_ids, require_fully_complete)) {
|
||||
// Now remove this cycler from the list of things that need
|
||||
// completion. We have to be a bit careful when deleting things
|
||||
// from the STL container while we are traversing it.
|
||||
CyclerPointers::iterator old = ci;
|
||||
++ci;
|
||||
pref._cycler_pointers.erase(old);
|
||||
|
||||
} else {
|
||||
// Couldn't complete this cycler yet; it'll wait for next time.
|
||||
++ci;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pref._cycler_pointers.empty()) {
|
||||
// If we didn't get all the cyclers, we have to wait.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now make sure we have all of the pointers this object is
|
||||
// waiting for. If any of the pointers has not yet been read
|
||||
// in, we can't resolve this object--we can't do anything for a
|
||||
|
|
@ -1062,15 +1071,12 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
|
|||
// that object.
|
||||
bool is_complete = true;
|
||||
|
||||
// Some objects further require all of their nested objects to have
|
||||
// been completed (i.e. complete_pointers has been called on each
|
||||
// nested object) before they can themselves be completed.
|
||||
bool require_fully_complete = object->require_fully_complete();
|
||||
|
||||
vector_typedWritable references;
|
||||
|
||||
vector_int::const_iterator pi;
|
||||
for (pi = pointer_ids.begin(); pi != pointer_ids.end() && is_complete; ++pi) {
|
||||
for (pi = pref._objects.begin();
|
||||
pi != pref._objects.end() && is_complete;
|
||||
++pi) {
|
||||
int child_id = (*pi);
|
||||
if (child_id == 0) {
|
||||
// A NULL pointer is a NULL pointer.
|
||||
|
|
@ -1106,7 +1112,7 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
|
|||
|
||||
if (is_complete) {
|
||||
// Okay, here's the complete list of pointers for you!
|
||||
nassertr(references.size() == pointer_ids.size(), false);
|
||||
nassertr(references.size() == pref._objects.size(), false);
|
||||
|
||||
if (bam_cat.is_spam()) {
|
||||
bam_cat.spam()
|
||||
|
|
@ -1143,7 +1149,8 @@ resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool BamReader::
|
||||
resolve_cycler_pointers(PipelineCyclerBase *cycler,
|
||||
const vector_int &pointer_ids) {
|
||||
const vector_int &pointer_ids,
|
||||
bool require_fully_complete) {
|
||||
// Now make sure we have all of the pointers this cycler is
|
||||
// waiting for. If any of the pointers has not yet been read
|
||||
// in, we can't resolve this cycler--we can't do anything for a
|
||||
|
|
@ -1175,8 +1182,15 @@ resolve_cycler_pointers(PipelineCyclerBase *cycler,
|
|||
is_complete = false;
|
||||
|
||||
} else {
|
||||
// Yes, it's ready.
|
||||
references.push_back(child_obj._ptr);
|
||||
if (require_fully_complete &&
|
||||
_object_pointers.find(child_id) != _object_pointers.end()) {
|
||||
// It's not yet complete itself.
|
||||
is_complete = false;
|
||||
|
||||
} else {
|
||||
// Yes, it's ready.
|
||||
references.push_back(child_obj._ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,12 +149,15 @@ private:
|
|||
INLINE static void create_factory();
|
||||
|
||||
private:
|
||||
class PointerReference;
|
||||
|
||||
void free_object_ids(DatagramIterator &scan);
|
||||
int read_object_id(DatagramIterator &scan);
|
||||
int read_pta_id(DatagramIterator &scan);
|
||||
int p_read_object();
|
||||
bool resolve_object_pointers(TypedWritable *object, const vector_int &pointer_ids);
|
||||
bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids);
|
||||
bool resolve_object_pointers(TypedWritable *object, PointerReference &pref);
|
||||
bool resolve_cycler_pointers(PipelineCyclerBase *cycler, const vector_int &pointer_ids,
|
||||
bool require_fully_complete);
|
||||
void finalize();
|
||||
|
||||
INLINE bool get_datagram(Datagram &datagram);
|
||||
|
|
@ -215,12 +218,14 @@ private:
|
|||
// 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
|
||||
// call the appropriate complete_pointers() later.
|
||||
typedef phash_map<int, vector_int, int_hash> ObjectPointers;
|
||||
ObjectPointers _object_pointers;
|
||||
|
||||
// Ditto, for the PiplineCycler objects.
|
||||
typedef phash_map<PipelineCyclerBase *, vector_int, pointer_hash> CyclerPointers;
|
||||
CyclerPointers _cycler_pointers;
|
||||
class PointerReference {
|
||||
public:
|
||||
vector_int _objects;
|
||||
CyclerPointers _cycler_pointers;
|
||||
};
|
||||
typedef phash_map<int, PointerReference, int_hash> ObjectPointers;
|
||||
ObjectPointers _object_pointers;
|
||||
|
||||
// This is the number of extra objects that must still be read (and
|
||||
// saved in the _created_objs map) before returning from
|
||||
|
|
|
|||
Loading…
Reference in New Issue