mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31: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 "
|
||||
"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
|
||||
|
||||
class SortFieldsByIndex {
|
||||
@ -1300,49 +1308,81 @@ rebuild_inherited_fields() {
|
||||
|
||||
_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;
|
||||
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
|
||||
const DCClass *parent = (*pi);
|
||||
int num_inherited_fields = parent->get_num_inherited_fields();
|
||||
for (int i = 0; i < num_inherited_fields; ++i) {
|
||||
const DCField *field = parent->get_inherited_field(i);
|
||||
names.insert(field->get_name());
|
||||
DCField *field = parent->get_inherited_field(i);
|
||||
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
|
||||
// immediately added to the _inherited_fields list, since the
|
||||
// unnamed fields are not inherited.
|
||||
// Now add the local fields at the end of the list. If any fields
|
||||
// in this list were already defined by a parent, we will shadow the
|
||||
// parent definition (that is, remove the parent's field from our
|
||||
// list of inherited fields).
|
||||
Fields::const_iterator fi;
|
||||
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
|
||||
DCField *field = (*fi);
|
||||
if (field->get_name().empty()) {
|
||||
_inherited_fields.push_back(field);
|
||||
// Unnamed fields are always added.
|
||||
_inherited_fields.push_back(field);
|
||||
|
||||
} 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
|
||||
// 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);
|
||||
// Now add the local field.
|
||||
_inherited_fields.push_back(field);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, sort the list in global field index order. This will
|
||||
// put the inherited fields at the top of the list.
|
||||
sort(_inherited_fields.begin(), _inherited_fields.end(),
|
||||
SortFieldsByIndex());
|
||||
if (dc_sort_inheritance_by_file) {
|
||||
// Temporary hack.
|
||||
sort(_inherited_fields.begin(), _inherited_fields.end(), 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 &&
|
||||
(dc_virtual_inheritance || !is_struct())) {
|
||||
((dc_virtual_inheritance && dc_sort_inheritance_by_file) || !is_struct())) {
|
||||
if (dc_multiple_inheritance) {
|
||||
_dc_file->set_new_index_number(field);
|
||||
} else {
|
||||
|
@ -30,11 +30,13 @@
|
||||
|
||||
extern ConfigVariableBool dc_multiple_inheritance;
|
||||
extern ConfigVariableBool dc_virtual_inheritance;
|
||||
extern ConfigVariableBool dc_sort_inheritance_by_file;
|
||||
|
||||
#else // WITHIN_PANDA
|
||||
|
||||
static const bool dc_multiple_inheritance = true;
|
||||
static const bool dc_virtual_inheritance = true;
|
||||
static const bool dc_sort_inheritance_by_file = false;
|
||||
|
||||
#endif // WITHIN_PANDA
|
||||
|
||||
@ -140,6 +142,8 @@ public:
|
||||
void set_number(int number);
|
||||
|
||||
private:
|
||||
void shadow_inherited_field(const string &name);
|
||||
|
||||
#ifdef WITHIN_PANDA
|
||||
PStatCollector _class_update_pcollector;
|
||||
PStatCollector _class_generate_pcollector;
|
||||
|
@ -501,7 +501,11 @@ void DCFile::
|
||||
generate_hash(HashGenerator &hashgen) const {
|
||||
if (dc_virtual_inheritance) {
|
||||
// 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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user