@@ -900,12 +900,52 @@ write_datagram(BamWriter *manager, Datagram &dg) {
900
900
int ClipPlaneAttrib::
901
901
complete_pointers (TypedWritable **p_list, BamReader *manager) {
902
902
int pi = RenderAttrib::complete_pointers (p_list, manager);
903
- AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr ();
904
903
905
904
if (manager->get_file_minor_ver () >= 40 ) {
906
905
for (size_t i = 0 ; i < _off_planes.size (); ++i) {
907
906
pi += _off_planes[i].complete_pointers (p_list + pi, manager);
907
+ }
908
+
909
+ for (size_t i = 0 ; i < _on_planes.size (); ++i) {
910
+ pi += _on_planes[i].complete_pointers (p_list + pi, manager);
911
+ }
912
+
913
+ } else {
914
+ BamAuxData *aux = (BamAuxData *)manager->get_aux_data (this , " planes" );
915
+ nassertr (aux != NULL , pi);
908
916
917
+ int i;
918
+ aux->_off_list .reserve (aux->_num_off_planes );
919
+ for (i = 0 ; i < aux->_num_off_planes ; ++i) {
920
+ PandaNode *node;
921
+ DCAST_INTO_R (node, p_list[pi++], pi);
922
+ aux->_off_list .push_back (node);
923
+ }
924
+
925
+ aux->_on_list .reserve (aux->_num_on_planes );
926
+ for (i = 0 ; i < aux->_num_on_planes ; ++i) {
927
+ PandaNode *node;
928
+ DCAST_INTO_R (node, p_list[pi++], pi);
929
+ aux->_on_list .push_back (node);
930
+ }
931
+ }
932
+
933
+ return pi;
934
+ }
935
+
936
+ /* *
937
+ * Called by the BamReader to perform any final actions needed for setting up
938
+ * the object after all objects have been read and all pointers have been
939
+ * completed.
940
+ */
941
+ void ClipPlaneAttrib::
942
+ finalize (BamReader *manager) {
943
+ if (manager->get_file_minor_ver () >= 40 ) {
944
+ AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr ();
945
+
946
+ // Check if any of the nodes we loaded are mentioned in the
947
+ // AttribNodeRegistry. If so, replace them.
948
+ for (size_t i = 0 ; i < _off_planes.size (); ++i) {
909
949
int n = areg->find_node (_off_planes[i]);
910
950
if (n != -1 ) {
911
951
// If it's in the registry, replace it.
@@ -914,8 +954,6 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
914
954
}
915
955
916
956
for (size_t i = 0 ; i < _on_planes.size (); ++i) {
917
- pi += _on_planes[i].complete_pointers (p_list + pi, manager);
918
-
919
957
int n = areg->find_node (_on_planes[i]);
920
958
if (n != -1 ) {
921
959
// If it's in the registry, replace it.
@@ -924,53 +962,46 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
924
962
}
925
963
926
964
} else {
927
- Planes::iterator ci = _off_planes.begin ();
928
- while (ci != _off_planes.end ()) {
929
- PandaNode *node;
930
- DCAST_INTO_R (node, p_list[pi++], pi);
931
-
932
- // We go through some effort to look up the node in the registry without
933
- // creating a NodePath around it first (which would up, and then down,
934
- // the reference count, possibly deleting the node).
935
- int ni = areg->find_node (node->get_type (), node->get_name ());
936
- if (ni != -1 ) {
937
- (*ci) = areg->get_node (ni);
965
+ // Now it's safe to convert our saved PandaNodes into NodePaths.
966
+ BamAuxData *aux = (BamAuxData *)manager->get_aux_data (this , " planes" );
967
+ nassertv (aux != NULL );
968
+ nassertv (aux->_num_off_planes == (int )aux->_off_list .size ());
969
+ nassertv (aux->_num_on_planes == (int )aux->_on_list .size ());
970
+
971
+ AttribNodeRegistry *areg = AttribNodeRegistry::get_global_ptr ();
972
+
973
+ _off_planes.reserve (aux->_off_list .size ());
974
+ NodeList::iterator ni;
975
+ for (ni = aux->_off_list .begin (); ni != aux->_off_list .end (); ++ni) {
976
+ PandaNode *node = (*ni);
977
+ int n = areg->find_node (node->get_type (), node->get_name ());
978
+ if (n != -1 ) {
979
+ // If it's in the registry, add that NodePath.
980
+ _off_planes.push_back (areg->get_node (n));
938
981
} else {
939
- (*ci) = NodePath (node);
982
+ // Otherwise, add any arbitrary NodePath. Complain if it's ambiguous.
983
+ _off_planes.push_back (NodePath (node));
940
984
}
941
- ++ci;
942
985
}
943
986
944
- ci = _on_planes.begin ( );
945
- while (ci != _on_planes .end ()) {
946
- PandaNode *node;
947
- DCAST_INTO_R (node, p_list[pi++], pi );
948
-
949
- int ni = areg-> find_node (node-> get_type (), node-> get_name ());
950
- if (ni != - 1 ) {
951
- (*ci) = areg-> get_node (ni );
987
+ _on_planes.reserve (aux-> _on_list . size () );
988
+ for (ni = aux-> _on_list . begin (); ni != aux-> _on_list .end (); ++ni ) {
989
+ PandaNode *node = (*ni) ;
990
+ int n = areg-> find_node (node-> get_type (), node-> get_name () );
991
+ if (n != - 1 ) {
992
+ // If it's in the registry, add that NodePath.
993
+ _on_planes. push_back (areg-> get_node (n));
994
+ node = _on_planes. back (). node ( );
952
995
} else {
953
- (*ci) = NodePath (node);
996
+ // Otherwise, add any arbitrary NodePath. Complain if it's ambiguous.
997
+ _on_planes.push_back (NodePath (node));
954
998
}
955
- ++ci;
956
999
}
957
1000
}
958
1001
1002
+ // Now that the NodePaths have been filled in, we can sort the list.
959
1003
_off_planes.sort ();
960
1004
_on_planes.sort ();
961
-
962
- return pi;
963
- }
964
-
965
- /* *
966
- * Some objects require all of their nested pointers to have been completed
967
- * before the objects themselves can be completed. If this is the case,
968
- * override this method to return true, and be careful with circular
969
- * references (which would make the object unreadable from a bam file).
970
- */
971
- bool ClipPlaneAttrib::
972
- require_fully_complete () const {
973
- return true ;
974
1005
}
975
1006
976
1007
/* *
@@ -987,6 +1018,8 @@ make_from_bam(const FactoryParams ¶ms) {
987
1018
parse_params (params, scan, manager);
988
1019
attrib->fillin (scan, manager);
989
1020
1021
+ manager->register_finalize (attrib);
1022
+
990
1023
return attrib;
991
1024
}
992
1025
@@ -1000,26 +1033,24 @@ fillin(DatagramIterator &scan, BamReader *manager) {
1000
1033
1001
1034
_off_all_planes = scan.get_bool ();
1002
1035
1003
- int num_off_planes = scan.get_uint16 ();
1004
-
1005
- // Push back an empty NodePath for each off Plane for now, until we get the
1006
- // actual list of pointers later in complete_pointers().
1007
- _off_planes.resize (num_off_planes);
1008
1036
if (manager->get_file_minor_ver () >= 40 ) {
1009
- for (int i = 0 ; i < num_off_planes; i++) {
1037
+ _off_planes.resize (scan.get_uint16 ());
1038
+ for (size_t i = 0 ; i < _off_planes.size (); ++i) {
1010
1039
_off_planes[i].fillin (scan, manager);
1011
1040
}
1012
- } else {
1013
- manager->read_pointers (scan, num_off_planes);
1014
- }
1015
1041
1016
- int num_on_planes = scan.get_uint16 ();
1017
- _on_planes.resize (num_on_planes);
1018
- if (manager->get_file_minor_ver () >= 40 ) {
1019
- for (int i = 0 ; i < num_on_planes; i++) {
1042
+ _on_planes.resize (scan.get_uint16 ());
1043
+ for (size_t i = 0 ; i < _on_planes.size (); ++i) {
1020
1044
_on_planes[i].fillin (scan, manager);
1021
1045
}
1022
1046
} else {
1023
- manager->read_pointers (scan, num_on_planes);
1047
+ BamAuxData *aux = new BamAuxData;
1048
+ manager->set_aux_data (this , " planes" , aux);
1049
+
1050
+ aux->_num_off_planes = scan.get_uint16 ();
1051
+ manager->read_pointers (scan, aux->_num_off_planes );
1052
+
1053
+ aux->_num_on_planes = scan.get_uint16 ();
1054
+ manager->read_pointers (scan, aux->_num_on_planes );
1024
1055
}
1025
1056
}
0 commit comments