mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
fix inheritance ordering
This commit is contained in:
parent
f04e3c9ddc
commit
14374eef99
@ -48,6 +48,14 @@ ConfigVariableBool dc_virtual_inheritance
|
|||||||
"This also enables shadowing (overloading) of inherited method "
|
"This also enables shadowing (overloading) of inherited method "
|
||||||
"names from a base class."));
|
"names from a base class."));
|
||||||
|
|
||||||
|
ConfigVariableBool dc_sort_inheritance_by_file
|
||||||
|
("dc-sort-inheritance-by-file", true,
|
||||||
|
PRC_DESC("This is a temporary hack. This should be true if you are using "
|
||||||
|
"version 1.42 of the otp_server.exe binary, which sorted inherited "
|
||||||
|
"fields based on the order of the classes within the DC file, "
|
||||||
|
"rather than based on the order in which the references are made "
|
||||||
|
"within the class."));
|
||||||
|
|
||||||
#endif // WITHIN_PANDA
|
#endif // WITHIN_PANDA
|
||||||
|
|
||||||
class SortFieldsByIndex {
|
class SortFieldsByIndex {
|
||||||
@ -1300,49 +1308,81 @@ rebuild_inherited_fields() {
|
|||||||
|
|
||||||
_inherited_fields.clear();
|
_inherited_fields.clear();
|
||||||
|
|
||||||
// First, get a list of all of the inherited field names.
|
// First, all of the inherited fields from our parent are at the top
|
||||||
|
// of the list.
|
||||||
Parents::const_iterator pi;
|
Parents::const_iterator pi;
|
||||||
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
|
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
|
||||||
const DCClass *parent = (*pi);
|
const DCClass *parent = (*pi);
|
||||||
int num_inherited_fields = parent->get_num_inherited_fields();
|
int num_inherited_fields = parent->get_num_inherited_fields();
|
||||||
for (int i = 0; i < num_inherited_fields; ++i) {
|
for (int i = 0; i < num_inherited_fields; ++i) {
|
||||||
const DCField *field = parent->get_inherited_field(i);
|
DCField *field = parent->get_inherited_field(i);
|
||||||
names.insert(field->get_name());
|
if (field->get_name().empty()) {
|
||||||
|
// Unnamed fields are always inherited. Except in the hack case.
|
||||||
|
if (!dc_sort_inheritance_by_file) {
|
||||||
|
_inherited_fields.push_back(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
bool inserted = names.insert(field->get_name()).second;
|
||||||
|
if (inserted) {
|
||||||
|
// The earlier parent shadows the later parent.
|
||||||
|
_inherited_fields.push_back(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also get the local field names. Any local unnamed fields are
|
// Now add the local fields at the end of the list. If any fields
|
||||||
// immediately added to the _inherited_fields list, since the
|
// in this list were already defined by a parent, we will shadow the
|
||||||
// unnamed fields are not inherited.
|
// parent definition (that is, remove the parent's field from our
|
||||||
|
// list of inherited fields).
|
||||||
Fields::const_iterator fi;
|
Fields::const_iterator fi;
|
||||||
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
|
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
|
||||||
DCField *field = (*fi);
|
DCField *field = (*fi);
|
||||||
if (field->get_name().empty()) {
|
if (field->get_name().empty()) {
|
||||||
_inherited_fields.push_back(field);
|
// Unnamed fields are always added.
|
||||||
|
_inherited_fields.push_back(field);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
names.insert(field->get_name());
|
bool inserted = names.insert(field->get_name()).second;
|
||||||
}
|
if (!inserted) {
|
||||||
}
|
// This local field shadows an inherited field. Remove the
|
||||||
|
// parent's field from our list.
|
||||||
|
shadow_inherited_field(field->get_name());
|
||||||
|
}
|
||||||
|
|
||||||
// And now build up the table. We use get_field_by_name() to
|
// Now add the local field.
|
||||||
// extract each one, to guarantee that the index we build exactly
|
|
||||||
// matches the return value of get_field_by_name().
|
|
||||||
|
|
||||||
Names::const_iterator ni;
|
|
||||||
for (ni = names.begin(); ni != names.end(); ++ni) {
|
|
||||||
// Note that we only list the named fields in the inherited field
|
|
||||||
// list. Thus, the unnamed fields, if any, are not inherited.
|
|
||||||
if (!(*ni).empty()) {
|
|
||||||
DCField *field = get_field_by_name(*ni);
|
|
||||||
nassertv(field != (DCField *)NULL);
|
|
||||||
_inherited_fields.push_back(field);
|
_inherited_fields.push_back(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, sort the list in global field index order. This will
|
if (dc_sort_inheritance_by_file) {
|
||||||
// put the inherited fields at the top of the list.
|
// Temporary hack.
|
||||||
sort(_inherited_fields.begin(), _inherited_fields.end(),
|
sort(_inherited_fields.begin(), _inherited_fields.end(), SortFieldsByIndex());
|
||||||
SortFieldsByIndex());
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCClass::shadow_inherited_field
|
||||||
|
// Access: Private
|
||||||
|
// Description: This is called only by rebuild_inherited_fields().
|
||||||
|
// It removes the named field from the list of
|
||||||
|
// _inherited_fields, presumably in preparation for
|
||||||
|
// adding a new definition below.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DCClass::
|
||||||
|
shadow_inherited_field(const string &name) {
|
||||||
|
Fields::iterator fi;
|
||||||
|
for (fi = _inherited_fields.begin(); fi != _inherited_fields.end(); ++fi) {
|
||||||
|
DCField *field = (*fi);
|
||||||
|
if (field->get_name() == name) {
|
||||||
|
_inherited_fields.erase(fi);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, the named field wasn't in the list. Huh.
|
||||||
|
nassertv(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1388,7 +1428,7 @@ add_field(DCField *field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_dc_file != (DCFile *)NULL &&
|
if (_dc_file != (DCFile *)NULL &&
|
||||||
(dc_virtual_inheritance || !is_struct())) {
|
((dc_virtual_inheritance && dc_sort_inheritance_by_file) || !is_struct())) {
|
||||||
if (dc_multiple_inheritance) {
|
if (dc_multiple_inheritance) {
|
||||||
_dc_file->set_new_index_number(field);
|
_dc_file->set_new_index_number(field);
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,11 +30,13 @@
|
|||||||
|
|
||||||
extern ConfigVariableBool dc_multiple_inheritance;
|
extern ConfigVariableBool dc_multiple_inheritance;
|
||||||
extern ConfigVariableBool dc_virtual_inheritance;
|
extern ConfigVariableBool dc_virtual_inheritance;
|
||||||
|
extern ConfigVariableBool dc_sort_inheritance_by_file;
|
||||||
|
|
||||||
#else // WITHIN_PANDA
|
#else // WITHIN_PANDA
|
||||||
|
|
||||||
static const bool dc_multiple_inheritance = true;
|
static const bool dc_multiple_inheritance = true;
|
||||||
static const bool dc_virtual_inheritance = true;
|
static const bool dc_virtual_inheritance = true;
|
||||||
|
static const bool dc_sort_inheritance_by_file = false;
|
||||||
|
|
||||||
#endif // WITHIN_PANDA
|
#endif // WITHIN_PANDA
|
||||||
|
|
||||||
@ -140,6 +142,8 @@ public:
|
|||||||
void set_number(int number);
|
void set_number(int number);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void shadow_inherited_field(const string &name);
|
||||||
|
|
||||||
#ifdef WITHIN_PANDA
|
#ifdef WITHIN_PANDA
|
||||||
PStatCollector _class_update_pcollector;
|
PStatCollector _class_update_pcollector;
|
||||||
PStatCollector _class_generate_pcollector;
|
PStatCollector _class_generate_pcollector;
|
||||||
|
@ -501,7 +501,11 @@ void DCFile::
|
|||||||
generate_hash(HashGenerator &hashgen) const {
|
generate_hash(HashGenerator &hashgen) const {
|
||||||
if (dc_virtual_inheritance) {
|
if (dc_virtual_inheritance) {
|
||||||
// Just to make the hash number change in this case.
|
// Just to make the hash number change in this case.
|
||||||
hashgen.add_int(1);
|
if (dc_sort_inheritance_by_file) {
|
||||||
|
hashgen.add_int(1);
|
||||||
|
} else {
|
||||||
|
hashgen.add_int(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hashgen.add_int(_classes.size());
|
hashgen.add_int(_classes.size());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user