support multiple inheritance in dc file

This commit is contained in:
David Rose 2005-02-25 23:32:34 +00:00
parent b78fb88cf3
commit edf017e3f6
11 changed files with 354 additions and 196 deletions

View File

@ -17,9 +17,19 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_dc_file
// Access: Published
// Description: Returns the DCFile object that contains the class.
////////////////////////////////////////////////////////////////////
INLINE DCFile *DCClass::
get_dc_file() const {
return _dc_file;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::is_struct
// Access: Public
// Access: Published
// Description: Returns true if the class has been identified with
// the "struct" keyword in the dc file, false if it was
// declared with "dclass".
@ -31,7 +41,7 @@ is_struct() const {
////////////////////////////////////////////////////////////////////
// Function: DCClass::is_bogus_class
// Access: Public
// Access: Published
// Description: Returns true if the class has been flagged as a bogus
// class. This is set for classes that are generated by
// the parser as placeholder for missing classes, as
@ -45,7 +55,7 @@ is_bogus_class() const {
////////////////////////////////////////////////////////////////////
// Function: DCClass::start_generate
// Access: Public
// Access: Published
// Description: Starts the PStats timer going on the "generate" task,
// that is, marks the beginning of the process of
// generating a new object, for the purposes of timing
@ -63,7 +73,7 @@ start_generate() {
////////////////////////////////////////////////////////////////////
// Function: DCClass::stop_generate
// Access: Public
// Access: Published
// Description: Stops the PStats timer on the "generate" task.
// This should balance with a preceding call to
// start_generate().

View File

@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "dcClass.h"
#include "dcFile.h"
#include "dcAtomicField.h"
#include "hashGenerator.h"
#include "dcindent.h"
@ -31,6 +32,14 @@
PStatCollector DCClass::_update_pcollector("App:Show code:readerPollTask:Update");
PStatCollector DCClass::_generate_pcollector("App:Show code:readerPollTask:Generate");
#endif // CPPPARSER
ConfigVariableBool dc_multiple_inheritance
("dc-multiple-inheritance", false,
PRC_DESC("Set this true to support multiple inheritance in the dc file. "
"If this is false, the old way, multiple inheritance is not "
"supported, but field numbers will be numbered sequentially, "
"which may be required to support old code that assumed this."));
#endif // WITHIN_PANDA
////////////////////////////////////////////////////////////////////
@ -39,11 +48,12 @@ PStatCollector DCClass::_generate_pcollector("App:Show code:readerPollTask:Gener
// Description:
////////////////////////////////////////////////////////////////////
DCClass::
DCClass(const string &name, bool is_struct, bool bogus_class) :
DCClass(DCFile *dc_file, const string &name, bool is_struct, bool bogus_class) :
#ifdef WITHIN_PANDA
_class_update_pcollector(_update_pcollector, name),
_class_generate_pcollector(_generate_pcollector, name),
#endif
_dc_file(dc_file),
_name(name),
_is_struct(is_struct),
_bogus_class(bogus_class)
@ -230,6 +240,39 @@ get_field_by_name(const string &name) const {
return (DCField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_field_by_index
// Access: Published
// Description: Returns a pointer to the DCField that has the
// indicated index number. If the numbered field is not
// found in the current class, the parent classes will
// be searched, so the value returned may not actually
// be a field within this class. Returns NULL if there
// is no such field defined.
////////////////////////////////////////////////////////////////////
DCField *DCClass::
get_field_by_index(int index_number) const {
FieldsByIndex::const_iterator ni;
ni = _fields_by_index.find(index_number);
if (ni != _fields_by_index.end()) {
return (*ni).second;
}
// We didn't have such a field, so check our parents.
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
DCField *result = (*pi)->get_field_by_index(index_number);
if (result != (DCField *)NULL) {
// Cache this result for future lookups.
((DCClass *)this)->_fields_by_index[index_number] = result;
return result;
}
}
// Nobody knew what this field is.
return (DCField *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_num_inherited_fields
// Access: Published
@ -238,33 +281,40 @@ get_field_by_name(const string &name) const {
////////////////////////////////////////////////////////////////////
int DCClass::
get_num_inherited_fields() const {
if (!_parents.empty()) {
// This won't work for multiple dclass inheritance.
return _parents.front()->get_num_inherited_fields() + get_num_fields();
int num_fields = get_num_fields();
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
num_fields += (*pi)->get_num_inherited_fields();
}
return get_num_fields();
return num_fields;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_inherited_field
// Access: Published
// Description: Returns the nth field field in the class and all of
// its ancestors. This *is* the field corresponding to
// the given index number, since the fields are ordered
// consecutively beginning at the earliest inherited
// fields.
// its ancestors.
//
// This *used* to be the same thing as
// get_field_by_index(), back when the fields were
// numbered sequentially within a class's inheritance
// hierarchy. Now that fields have a globally unique
// index number, this is no longer true.
////////////////////////////////////////////////////////////////////
DCField *DCClass::
get_inherited_field(int n) const {
if (!_parents.empty()) {
// This won't work for multiple dclass inheritance.
int psize = _parents.front()->get_num_inherited_fields();
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
int psize = (*pi)->get_num_inherited_fields();
if (n < psize) {
return _parents.front()->get_inherited_field(n);
return (*pi)->get_inherited_field(n);
}
n -= psize;
}
return get_field(n);
}
@ -351,8 +401,16 @@ receive_update(PyObject *distobj, DatagramIterator &di) const {
packer.set_unpack_data(di.get_remaining_bytes());
int field_id = packer.raw_unpack_uint16();
DCField *field = get_inherited_field(field_id);
nassertv_always(field != NULL);
DCField *field = get_field_by_index(field_id);
if (field == (DCField *)NULL) {
ostringstream strm;
strm
<< "Received update for field " << field_id << ", not in class "
<< get_name();
nassert_raise(strm.str());
return;
}
packer.begin_unpack(field);
field->receive_update(packer, distobj);
packer.end_unpack();
@ -750,7 +808,7 @@ client_format_generate(PyObject *distobj, int do_id,
// Specify all of the required fields.
int num_fields = get_num_inherited_fields();
for (int i = 0; i < num_fields; i++) {
for (int i = 0; i < num_fields; ++i) {
DCField *field = get_inherited_field(i);
if (field->is_required() && field->as_molecular_field() == NULL) {
packer.begin_pack(field);
@ -1104,8 +1162,19 @@ add_field(DCField *field) {
}
if (!is_struct()) {
if (dc_multiple_inheritance) {
_dc_file->set_new_index_number(field);
} else {
field->set_number(get_num_inherited_fields());
}
bool inserted = _fields_by_index.insert
(FieldsByIndex::value_type(field->get_number(), field)).second;
// It shouldn't be possible for that to fail.
nassertr(inserted, false);
}
_fields.push_back(field);
return true;
}

View File

@ -26,7 +26,15 @@
#ifdef WITHIN_PANDA
#include "pStatCollector.h"
#endif
#include "configVariableBool.h"
extern ConfigVariableBool dc_multiple_inheritance;
#else // WITHIN_PANDA
static const bool dc_multiple_inheritance = true;
#endif // WITHIN_PANDA
class HashGenerator;
class DCParameter;
@ -38,13 +46,16 @@ class DCParameter;
////////////////////////////////////////////////////////////////////
class EXPCL_DIRECT DCClass : public DCDeclaration {
public:
DCClass(const string &name, bool is_struct, bool bogus_class);
DCClass(DCFile *dc_file, const string &name,
bool is_struct, bool bogus_class);
~DCClass();
PUBLISHED:
virtual DCClass *as_class();
virtual const DCClass *as_class() const;
INLINE DCFile *get_dc_file() const;
const string &get_name() const;
int get_number() const;
@ -57,6 +68,7 @@ PUBLISHED:
int get_num_fields() const;
DCField *get_field(int n) const;
DCField *get_field_by_name(const string &name) const;
DCField *get_field_by_index(int index_number) const;
int get_num_inherited_fields() const;
DCField *get_inherited_field(int n) const;
@ -124,6 +136,8 @@ private:
static PStatCollector _generate_pcollector;
#endif
DCFile *_dc_file;
string _name;
bool _is_struct;
bool _bogus_class;
@ -140,6 +154,9 @@ private:
typedef pmap<string, DCField *> FieldsByName;
FieldsByName _fields_by_name;
typedef pmap<int, DCField *> FieldsByIndex;
FieldsByIndex _fields_by_index;
#ifdef HAVE_PYTHON
PyObject *_class_def;
#endif

View File

@ -645,6 +645,12 @@ generate_hash(HashGenerator &hashgen) const {
// field with the other fields, so adding it explicitly will be
// redundant. However, the field name is significant.
hashgen.add_string(_name);
// Actually, we add _number anyway, since we need to ensure the hash
// code comes out different in the dc_multiple_inheritance case.
if (dc_multiple_inheritance) {
hashgen.add_int(_number);
}
}
////////////////////////////////////////////////////////////////////

View File

@ -91,7 +91,8 @@ clear() {
////////////////////////////////////////////////////////////////////
bool DCFile::
read_all() {
ConfigVariableList dc_files("dc-file", "The list of dc files to load.");
static ConfigVariableList dc_files
("dc-file", PRC_DESC("The list of dc files to load."));
if (dc_files.size() == 0) {
cerr << "No files specified via dc-file Config.prc variable!\n";
@ -129,11 +130,8 @@ read_all() {
////////////////////////////////////////////////////////////////////
bool DCFile::
read(Filename filename) {
ifstream in;
#ifdef WITHIN_PANDA
#ifdef WITHIN_PANDA
filename.set_text();
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
istream *in = vfs->open_read_file(filename);
if (in == (istream *)NULL) {
@ -146,19 +144,14 @@ read(Filename filename) {
// the in pointer does not call the appropriate global delete
// function; instead apparently calling the system delete
// function. So we call the delete function by hand instead.
#ifndef NDEBUG
in->~istream();
(*global_operator_delete)(in);
#else
delete in;
#endif
vfs->close_read_file(in);
return okflag;
}
filename.open_read(in);
#else
#else // WITHIN_PANDA
ifstream in;
in.open(filename.c_str());
#endif
if (!in) {
cerr << "Cannot open " << filename << " for reading.\n";
@ -166,6 +159,8 @@ read(Filename filename) {
}
return read(in, filename);
#endif // WITHIN_PANDA
}
////////////////////////////////////////////////////////////////////
@ -319,6 +314,29 @@ get_switch_by_name(const string &name) const {
return (DCSwitch *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::get_field_by_index
// Access: Published, Static
// Description: Returns a pointer to the one DCField that has the
// indicated index number, of all the DCFields across
// all classes in the file.
//
// This method is only valid if dc-multiple-inheritance
// is set true in the Config.prc file. Without this
// setting, different DCFields may share the same index
// number, so this global lookup is not possible.
////////////////////////////////////////////////////////////////////
DCField *DCFile::
get_field_by_index(int index_number) const {
nassertr(dc_multiple_inheritance, NULL);
if (index_number >= 0 && index_number < (int)_fields_by_index.size()) {
return _fields_by_index[index_number];
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::all_objects_valid
// Access: Published
@ -592,3 +610,17 @@ void DCFile::
add_thing_to_delete(DCDeclaration *decl) {
_things_to_delete.push_back(decl);
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::set_new_index_number
// Access: Public
// Description: Sets the next sequential available index number on
// the indicated field. This is only meant to be called
// by DCClass::add_field(), while the dc file is being
// parsed.
////////////////////////////////////////////////////////////////////
void DCFile::
set_new_index_number(DCField *field) {
field->set_number((int)_fields_by_index.size());
_fields_by_index.push_back(field);
}

View File

@ -23,6 +23,7 @@
class DCClass;
class DCSwitch;
class DCField;
class HashGenerator;
class DCTypedef;
class DCDeclaration;
@ -54,6 +55,8 @@ PUBLISHED:
DCClass *get_class_by_name(const string &name) const;
DCSwitch *get_switch_by_name(const string &name) const;
DCField *get_field_by_index(int index_number) const;
bool all_objects_valid() const;
int get_num_import_modules() const;
@ -76,6 +79,8 @@ public:
bool add_typedef(DCTypedef *dtypedef);
void add_thing_to_delete(DCDeclaration *decl);
void set_new_index_number(DCField *field);
private:
typedef pvector<DCClass *> Classes;
Classes _classes;
@ -103,6 +108,9 @@ private:
Declarations _declarations;
Declarations _things_to_delete;
typedef pvector<DCField *> FieldsByIndex;
FieldsByIndex _fields_by_index;
bool _all_objects_valid;
};

View File

@ -268,22 +268,22 @@ static const short yyrline[] =
0, 172, 174, 175, 181, 183, 184, 195, 201, 202,
205, 207, 213, 215, 221, 226, 226, 233, 235, 241,
246, 252, 270, 272, 275, 275, 288, 311, 313, 316,
323, 331, 333, 334, 346, 357, 358, 366, 375, 375,
388, 411, 413, 416, 423, 431, 433, 434, 444, 452,
453, 457, 463, 463, 476, 478, 481, 483, 486, 495,
495, 506, 510, 512, 512, 540, 542, 542, 570, 572,
575, 577, 580, 585, 589, 595, 600, 609, 625, 639,
641, 676, 692, 710, 715, 722, 729, 738, 744, 750,
760, 765, 772, 779, 786, 792, 798, 806, 808, 818,
824, 839, 854, 860, 870, 873, 884, 898, 902, 906,
911, 915, 918, 928, 932, 937, 941, 945, 949, 953,
953, 961, 961, 969, 969, 977, 983, 989, 995, 1003,
1005, 1008, 1010, 1013, 1015, 1018, 1023, 1027, 1031, 1035,
1039, 1043, 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075,
1079, 1083, 1087, 1091, 1095, 1101, 1106, 1110, 1114, 1118,
1122, 1126, 1130, 1134, 1138, 1144, 1154, 1154, 1165, 1181,
1188, 1201, 1206, 1209, 1209, 1223, 1225, 1226, 1227, 1239,
1239, 1256, 1261, 1267
323, 336, 338, 339, 351, 362, 363, 371, 380, 380,
393, 416, 418, 421, 428, 436, 438, 439, 449, 457,
458, 462, 468, 468, 481, 483, 486, 488, 491, 500,
500, 511, 515, 517, 517, 545, 547, 547, 575, 577,
580, 582, 585, 590, 594, 600, 605, 614, 630, 644,
646, 681, 697, 715, 720, 727, 734, 743, 749, 755,
765, 770, 777, 784, 791, 797, 803, 811, 813, 823,
829, 844, 859, 865, 875, 878, 889, 903, 907, 911,
916, 920, 923, 933, 937, 942, 946, 950, 954, 958,
958, 966, 966, 974, 974, 982, 988, 994, 1000, 1008,
1010, 1013, 1015, 1018, 1020, 1023, 1028, 1032, 1036, 1040,
1044, 1048, 1052, 1056, 1060, 1064, 1068, 1072, 1076, 1080,
1084, 1088, 1092, 1096, 1100, 1106, 1111, 1115, 1119, 1123,
1127, 1131, 1135, 1139, 1143, 1149, 1159, 1159, 1170, 1186,
1193, 1206, 1211, 1214, 1214, 1228, 1230, 1231, 1232, 1244,
1244, 1261, 1266, 1272
};
#endif
@ -1402,13 +1402,18 @@ case 29:
case 30:
#line 324 "dcParser.yxx"
{
if (!dc_multiple_inheritance) {
yyerror("Multiple inheritance is not supported without \"dc-multiple-inheritance 1\" in your Config.prc file.");
} else {
if (yyvsp[0].u.dclass != (DCClass *)NULL) {
current_class->add_parent(yyvsp[0].u.dclass);
}
}
}
break;
case 33:
#line 335 "dcParser.yxx"
#line 340 "dcParser.yxx"
{
if (yyvsp[0].u.field == (DCField *)NULL) {
// Pass this error up.
@ -1420,7 +1425,7 @@ case 33:
}
break;
case 34:
#line 348 "dcParser.yxx"
#line 353 "dcParser.yxx"
{
if (yyvsp[-1].u.field != (DCField *)NULL) {
if (yyvsp[-1].u.field->get_name().empty()) {
@ -1432,7 +1437,7 @@ case 34:
}
break;
case 36:
#line 359 "dcParser.yxx"
#line 364 "dcParser.yxx"
{
yyerror("Unnamed parameters are not allowed on a dclass");
if (yyvsp[-2].u.parameter != (DCField *)NULL) {
@ -1442,7 +1447,7 @@ case 36:
}
break;
case 37:
#line 367 "dcParser.yxx"
#line 372 "dcParser.yxx"
{
if (yyvsp[-1].u.parameter != (DCField *)NULL) {
yyvsp[-1].u.parameter->set_flags(yyvsp[0].u.s_int);
@ -1451,21 +1456,21 @@ case 37:
}
break;
case 38:
#line 377 "dcParser.yxx"
#line 382 "dcParser.yxx"
{
yyval.u.dclass = current_class;
current_class = new DCClass(yyvsp[0].str, true, false);
}
break;
case 39:
#line 382 "dcParser.yxx"
#line 387 "dcParser.yxx"
{
yyval.u.dclass = current_class;
current_class = yyvsp[-4].u.dclass;
}
break;
case 40:
#line 390 "dcParser.yxx"
#line 395 "dcParser.yxx"
{
if (dc_file == (DCFile *)NULL) {
yyerror("No DCFile available, so no struct names are predefined.");
@ -1487,7 +1492,7 @@ case 40:
}
break;
case 43:
#line 418 "dcParser.yxx"
#line 423 "dcParser.yxx"
{
if (yyvsp[0].u.dclass != (DCClass *)NULL) {
current_class->add_parent(yyvsp[0].u.dclass);
@ -1495,7 +1500,7 @@ case 43:
}
break;
case 44:
#line 424 "dcParser.yxx"
#line 429 "dcParser.yxx"
{
if (yyvsp[0].u.dclass != (DCClass *)NULL) {
current_class->add_parent(yyvsp[0].u.dclass);
@ -1503,7 +1508,7 @@ case 44:
}
break;
case 47:
#line 435 "dcParser.yxx"
#line 440 "dcParser.yxx"
{
if (yyvsp[0].u.field == (DCField *)NULL) {
// Pass this error up.
@ -1513,7 +1518,7 @@ case 47:
}
break;
case 48:
#line 446 "dcParser.yxx"
#line 451 "dcParser.yxx"
{
if (yyvsp[-1].u.field->get_name().empty()) {
yyerror("Field name required.");
@ -1522,33 +1527,33 @@ case 48:
}
break;
case 50:
#line 454 "dcParser.yxx"
#line 459 "dcParser.yxx"
{
yyval.u.field = yyvsp[-2].u.parameter;
}
break;
case 51:
#line 458 "dcParser.yxx"
#line 463 "dcParser.yxx"
{
yyval.u.field = yyvsp[-1].u.parameter;
}
break;
case 52:
#line 465 "dcParser.yxx"
#line 470 "dcParser.yxx"
{
yyval.u.field = current_atomic;
current_atomic = new DCAtomicField(yyvsp[-1].str, current_class);
}
break;
case 53:
#line 470 "dcParser.yxx"
#line 475 "dcParser.yxx"
{
yyval.u.field = current_atomic;
current_atomic = yyvsp[-2].u.atomic;
}
break;
case 58:
#line 488 "dcParser.yxx"
#line 493 "dcParser.yxx"
{
if (yyvsp[0].u.parameter != (DCParameter *)NULL) {
current_atomic->add_element(yyvsp[0].u.parameter);
@ -1556,19 +1561,19 @@ case 58:
}
break;
case 59:
#line 497 "dcParser.yxx"
#line 502 "dcParser.yxx"
{
current_parameter = yyvsp[0].u.parameter;
}
break;
case 60:
#line 501 "dcParser.yxx"
#line 506 "dcParser.yxx"
{
yyval.u.parameter = yyvsp[0].u.parameter;
}
break;
case 63:
#line 513 "dcParser.yxx"
#line 518 "dcParser.yxx"
{
current_packer = &default_packer;
current_packer->clear_data();
@ -1578,7 +1583,7 @@ case 63:
}
break;
case 64:
#line 521 "dcParser.yxx"
#line 526 "dcParser.yxx"
{
bool is_valid = false;
if (yyvsp[-3].u.parameter != (DCField *)NULL) {
@ -1598,7 +1603,7 @@ case 64:
}
break;
case 66:
#line 543 "dcParser.yxx"
#line 548 "dcParser.yxx"
{
current_packer = &default_packer;
current_packer->clear_data();
@ -1608,7 +1613,7 @@ case 66:
}
break;
case 67:
#line 551 "dcParser.yxx"
#line 556 "dcParser.yxx"
{
bool is_valid = false;
if (yyvsp[-3].u.parameter != (DCField *)NULL) {
@ -1628,31 +1633,31 @@ case 67:
}
break;
case 72:
#line 582 "dcParser.yxx"
#line 587 "dcParser.yxx"
{
yyval.u.field = yyvsp[-1].u.field;
}
break;
case 73:
#line 586 "dcParser.yxx"
#line 591 "dcParser.yxx"
{
yyval.u.field = yyvsp[-1].u.parameter;
}
break;
case 74:
#line 590 "dcParser.yxx"
#line 595 "dcParser.yxx"
{
yyval.u.field = yyvsp[-1].u.parameter;
}
break;
case 75:
#line 597 "dcParser.yxx"
#line 602 "dcParser.yxx"
{
yyval.u.parameter = new DCSimpleParameter(yyvsp[0].u.subatomic);
}
break;
case 76:
#line 601 "dcParser.yxx"
#line 606 "dcParser.yxx"
{
DCSimpleParameter *simple_param = yyvsp[-3].u.parameter->as_simple_parameter();
nassertr(simple_param != (DCSimpleParameter *)NULL, 0);
@ -1663,7 +1668,7 @@ case 76:
}
break;
case 77:
#line 610 "dcParser.yxx"
#line 615 "dcParser.yxx"
{
DCSimpleParameter *simple_param = yyvsp[-2].u.parameter->as_simple_parameter();
nassertr(simple_param != (DCSimpleParameter *)NULL, 0);
@ -1681,7 +1686,7 @@ case 77:
}
break;
case 78:
#line 626 "dcParser.yxx"
#line 631 "dcParser.yxx"
{
DCSimpleParameter *simple_param = yyvsp[-2].u.parameter->as_simple_parameter();
nassertr(simple_param != (DCSimpleParameter *)NULL, 0);
@ -1695,7 +1700,7 @@ case 78:
}
break;
case 80:
#line 642 "dcParser.yxx"
#line 647 "dcParser.yxx"
{
if (dc_file == (DCFile *)NULL) {
yyerror("Invalid type.");
@ -1732,7 +1737,7 @@ case 80:
}
break;
case 81:
#line 677 "dcParser.yxx"
#line 682 "dcParser.yxx"
{
// This is an inline struct definition.
if (yyvsp[0].u.dclass == (DCClass *)NULL) {
@ -1750,7 +1755,7 @@ case 81:
}
break;
case 82:
#line 693 "dcParser.yxx"
#line 698 "dcParser.yxx"
{
// This is an inline switch definition.
if (yyvsp[0].u.dswitch == (DCSwitch *)NULL) {
@ -1768,13 +1773,13 @@ case 82:
}
break;
case 83:
#line 712 "dcParser.yxx"
#line 717 "dcParser.yxx"
{
double_range.clear();
}
break;
case 84:
#line 716 "dcParser.yxx"
#line 721 "dcParser.yxx"
{
double_range.clear();
if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) {
@ -1783,7 +1788,7 @@ case 84:
}
break;
case 85:
#line 723 "dcParser.yxx"
#line 728 "dcParser.yxx"
{
double_range.clear();
if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) {
@ -1792,7 +1797,7 @@ case 85:
}
break;
case 86:
#line 730 "dcParser.yxx"
#line 735 "dcParser.yxx"
{
double_range.clear();
if (yyvsp[0].u.real >= 0) {
@ -1803,7 +1808,7 @@ case 86:
}
break;
case 87:
#line 739 "dcParser.yxx"
#line 744 "dcParser.yxx"
{
if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) {
yyerror("Overlapping range");
@ -1811,7 +1816,7 @@ case 87:
}
break;
case 88:
#line 745 "dcParser.yxx"
#line 750 "dcParser.yxx"
{
if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) {
yyerror("Overlapping range");
@ -1819,7 +1824,7 @@ case 88:
}
break;
case 89:
#line 751 "dcParser.yxx"
#line 756 "dcParser.yxx"
{
if (yyvsp[0].u.real >= 0) {
yyerror("Syntax error");
@ -1829,13 +1834,13 @@ case 89:
}
break;
case 90:
#line 762 "dcParser.yxx"
#line 767 "dcParser.yxx"
{
uint_range.clear();
}
break;
case 91:
#line 766 "dcParser.yxx"
#line 771 "dcParser.yxx"
{
uint_range.clear();
if (!uint_range.add_range(yyvsp[0].u.s_uint, yyvsp[0].u.s_uint)) {
@ -1844,7 +1849,7 @@ case 91:
}
break;
case 92:
#line 773 "dcParser.yxx"
#line 778 "dcParser.yxx"
{
uint_range.clear();
if (!uint_range.add_range(yyvsp[-2].u.s_uint, yyvsp[0].u.s_uint)) {
@ -1853,7 +1858,7 @@ case 92:
}
break;
case 93:
#line 780 "dcParser.yxx"
#line 785 "dcParser.yxx"
{
uint_range.clear();
if (!uint_range.add_range(yyvsp[-1].u.s_uint, yyvsp[0].u.s_uint)) {
@ -1862,7 +1867,7 @@ case 93:
}
break;
case 94:
#line 787 "dcParser.yxx"
#line 792 "dcParser.yxx"
{
if (!uint_range.add_range(yyvsp[0].u.s_uint, yyvsp[0].u.s_uint)) {
yyerror("Overlapping range");
@ -1870,7 +1875,7 @@ case 94:
}
break;
case 95:
#line 793 "dcParser.yxx"
#line 798 "dcParser.yxx"
{
if (!uint_range.add_range(yyvsp[-2].u.s_uint, yyvsp[0].u.s_uint)) {
yyerror("Overlapping range");
@ -1878,7 +1883,7 @@ case 95:
}
break;
case 96:
#line 799 "dcParser.yxx"
#line 804 "dcParser.yxx"
{
if (!uint_range.add_range(yyvsp[-1].u.s_uint, yyvsp[0].u.s_uint)) {
yyerror("Overlapping range");
@ -1886,7 +1891,7 @@ case 96:
}
break;
case 98:
#line 809 "dcParser.yxx"
#line 814 "dcParser.yxx"
{
if (yyvsp[-3].u.parameter == (DCParameter *)NULL) {
yyval.u.parameter = NULL;
@ -1896,14 +1901,14 @@ case 98:
}
break;
case 99:
#line 820 "dcParser.yxx"
#line 825 "dcParser.yxx"
{
current_parameter->set_name(yyvsp[0].str);
yyval.u.parameter = current_parameter;
}
break;
case 100:
#line 825 "dcParser.yxx"
#line 830 "dcParser.yxx"
{
DCSimpleParameter *simple_param = yyvsp[-2].u.parameter->as_simple_parameter();
if (simple_param == NULL || simple_param->get_typedef() != (DCTypedef *)NULL) {
@ -1920,7 +1925,7 @@ case 100:
}
break;
case 101:
#line 840 "dcParser.yxx"
#line 845 "dcParser.yxx"
{
DCSimpleParameter *simple_param = yyvsp[-2].u.parameter->as_simple_parameter();
if (simple_param == NULL || simple_param->get_typedef() != (DCTypedef *)NULL) {
@ -1937,13 +1942,13 @@ case 101:
}
break;
case 102:
#line 855 "dcParser.yxx"
#line 860 "dcParser.yxx"
{
yyval.u.parameter = yyvsp[-3].u.parameter->append_array_specification(uint_range);
}
break;
case 103:
#line 862 "dcParser.yxx"
#line 867 "dcParser.yxx"
{
if (yyvsp[0].str.length() != 1) {
yyerror("Single character required.");
@ -1954,7 +1959,7 @@ case 103:
}
break;
case 105:
#line 875 "dcParser.yxx"
#line 880 "dcParser.yxx"
{
yyval.u.s_uint = (unsigned int)yyvsp[0].u.uint64;
if (yyval.u.s_uint != yyvsp[0].u.uint64) {
@ -1964,7 +1969,7 @@ case 105:
}
break;
case 106:
#line 886 "dcParser.yxx"
#line 891 "dcParser.yxx"
{
yyval.u.s_uint = (unsigned int)-yyvsp[0].u.int64;
if (yyvsp[0].u.int64 >= 0) {
@ -1977,19 +1982,19 @@ case 106:
}
break;
case 109:
#line 908 "dcParser.yxx"
#line 913 "dcParser.yxx"
{
yyval.u.real = (double)yyvsp[0].u.uint64;
}
break;
case 110:
#line 912 "dcParser.yxx"
#line 917 "dcParser.yxx"
{
yyval.u.real = (double)yyvsp[0].u.int64;
}
break;
case 112:
#line 920 "dcParser.yxx"
#line 925 "dcParser.yxx"
{
if (yyvsp[0].str.length() != 1) {
yyerror("Single character required.");
@ -2000,73 +2005,73 @@ case 112:
}
break;
case 114:
#line 934 "dcParser.yxx"
#line 939 "dcParser.yxx"
{
current_packer->pack_int64(yyvsp[0].u.int64);
}
break;
case 115:
#line 938 "dcParser.yxx"
#line 943 "dcParser.yxx"
{
current_packer->pack_uint64(yyvsp[0].u.uint64);
}
break;
case 116:
#line 942 "dcParser.yxx"
#line 947 "dcParser.yxx"
{
current_packer->pack_double(yyvsp[0].u.real);
}
break;
case 117:
#line 946 "dcParser.yxx"
#line 951 "dcParser.yxx"
{
current_packer->pack_string(yyvsp[0].str);
}
break;
case 118:
#line 950 "dcParser.yxx"
#line 955 "dcParser.yxx"
{
current_packer->pack_literal_value(yyvsp[0].str);
}
break;
case 119:
#line 954 "dcParser.yxx"
#line 959 "dcParser.yxx"
{
current_packer->push();
}
break;
case 120:
#line 958 "dcParser.yxx"
#line 963 "dcParser.yxx"
{
current_packer->pop();
}
break;
case 121:
#line 962 "dcParser.yxx"
#line 967 "dcParser.yxx"
{
current_packer->push();
}
break;
case 122:
#line 966 "dcParser.yxx"
#line 971 "dcParser.yxx"
{
current_packer->pop();
}
break;
case 123:
#line 970 "dcParser.yxx"
#line 975 "dcParser.yxx"
{
current_packer->push();
}
break;
case 124:
#line 974 "dcParser.yxx"
#line 979 "dcParser.yxx"
{
current_packer->pop();
}
break;
case 125:
#line 978 "dcParser.yxx"
#line 983 "dcParser.yxx"
{
for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) {
current_packer->pack_int64(yyvsp[-2].u.int64);
@ -2074,7 +2079,7 @@ case 125:
}
break;
case 126:
#line 984 "dcParser.yxx"
#line 989 "dcParser.yxx"
{
for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) {
current_packer->pack_uint64(yyvsp[-2].u.uint64);
@ -2082,7 +2087,7 @@ case 126:
}
break;
case 127:
#line 990 "dcParser.yxx"
#line 995 "dcParser.yxx"
{
for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) {
current_packer->pack_double(yyvsp[-2].u.real);
@ -2090,7 +2095,7 @@ case 127:
}
break;
case 128:
#line 996 "dcParser.yxx"
#line 1001 "dcParser.yxx"
{
for (unsigned int i = 0; i < yyvsp[0].u.s_uint; i++) {
current_packer->pack_literal_value(yyvsp[-2].str);
@ -2098,187 +2103,187 @@ case 128:
}
break;
case 135:
#line 1020 "dcParser.yxx"
#line 1025 "dcParser.yxx"
{
yyval.u.subatomic = ST_int8;
}
break;
case 136:
#line 1024 "dcParser.yxx"
#line 1029 "dcParser.yxx"
{
yyval.u.subatomic = ST_int16;
}
break;
case 137:
#line 1028 "dcParser.yxx"
#line 1033 "dcParser.yxx"
{
yyval.u.subatomic = ST_int32;
}
break;
case 138:
#line 1032 "dcParser.yxx"
#line 1037 "dcParser.yxx"
{
yyval.u.subatomic = ST_int64;
}
break;
case 139:
#line 1036 "dcParser.yxx"
#line 1041 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint8;
}
break;
case 140:
#line 1040 "dcParser.yxx"
#line 1045 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint16;
}
break;
case 141:
#line 1044 "dcParser.yxx"
#line 1049 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint32;
}
break;
case 142:
#line 1048 "dcParser.yxx"
#line 1053 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint64;
}
break;
case 143:
#line 1052 "dcParser.yxx"
#line 1057 "dcParser.yxx"
{
yyval.u.subatomic = ST_float64;
}
break;
case 144:
#line 1056 "dcParser.yxx"
#line 1061 "dcParser.yxx"
{
yyval.u.subatomic = ST_string;
}
break;
case 145:
#line 1060 "dcParser.yxx"
#line 1065 "dcParser.yxx"
{
yyval.u.subatomic = ST_blob;
}
break;
case 146:
#line 1064 "dcParser.yxx"
#line 1069 "dcParser.yxx"
{
yyval.u.subatomic = ST_blob32;
}
break;
case 147:
#line 1068 "dcParser.yxx"
#line 1073 "dcParser.yxx"
{
yyval.u.subatomic = ST_int8array;
}
break;
case 148:
#line 1072 "dcParser.yxx"
#line 1077 "dcParser.yxx"
{
yyval.u.subatomic = ST_int16array;
}
break;
case 149:
#line 1076 "dcParser.yxx"
#line 1081 "dcParser.yxx"
{
yyval.u.subatomic = ST_int32array;
}
break;
case 150:
#line 1080 "dcParser.yxx"
#line 1085 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint8array;
}
break;
case 151:
#line 1084 "dcParser.yxx"
#line 1089 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint16array;
}
break;
case 152:
#line 1088 "dcParser.yxx"
#line 1093 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint32array;
}
break;
case 153:
#line 1092 "dcParser.yxx"
#line 1097 "dcParser.yxx"
{
yyval.u.subatomic = ST_uint32uint8array;
}
break;
case 154:
#line 1096 "dcParser.yxx"
#line 1101 "dcParser.yxx"
{
yyval.u.subatomic = ST_char;
}
break;
case 155:
#line 1103 "dcParser.yxx"
#line 1108 "dcParser.yxx"
{
yyval.u.s_int = 0;
}
break;
case 156:
#line 1107 "dcParser.yxx"
#line 1112 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_required;
}
break;
case 157:
#line 1111 "dcParser.yxx"
#line 1116 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_broadcast;
}
break;
case 158:
#line 1115 "dcParser.yxx"
#line 1120 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_p2p;
}
break;
case 159:
#line 1119 "dcParser.yxx"
#line 1124 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_ram;
}
break;
case 160:
#line 1123 "dcParser.yxx"
#line 1128 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_db;
}
break;
case 161:
#line 1127 "dcParser.yxx"
#line 1132 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_clsend;
}
break;
case 162:
#line 1131 "dcParser.yxx"
#line 1136 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_clrecv;
}
break;
case 163:
#line 1135 "dcParser.yxx"
#line 1140 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_ownsend;
}
break;
case 164:
#line 1139 "dcParser.yxx"
#line 1144 "dcParser.yxx"
{
yyval.u.s_int = yyvsp[-1].u.s_int | DCAtomicField::F_airecv;
}
break;
case 165:
#line 1146 "dcParser.yxx"
#line 1151 "dcParser.yxx"
{
if (yyvsp[0].u.s_int != 0) {
yyerror("Server flags are not allowed here.");
@ -2287,19 +2292,19 @@ case 165:
}
break;
case 166:
#line 1156 "dcParser.yxx"
#line 1161 "dcParser.yxx"
{
current_molecular = new DCMolecularField(yyvsp[-1].str, current_class);
}
break;
case 167:
#line 1160 "dcParser.yxx"
#line 1165 "dcParser.yxx"
{
yyval.u.field = current_molecular;
}
break;
case 168:
#line 1167 "dcParser.yxx"
#line 1172 "dcParser.yxx"
{
DCField *field = current_class->get_field_by_name(yyvsp[0].str);
yyval.u.atomic = (DCAtomicField *)NULL;
@ -2314,7 +2319,7 @@ case 168:
}
break;
case 169:
#line 1183 "dcParser.yxx"
#line 1188 "dcParser.yxx"
{
if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) {
current_molecular->add_atomic(yyvsp[0].u.atomic);
@ -2322,7 +2327,7 @@ case 169:
}
break;
case 170:
#line 1189 "dcParser.yxx"
#line 1194 "dcParser.yxx"
{
if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) {
current_molecular->add_atomic(yyvsp[0].u.atomic);
@ -2335,27 +2340,27 @@ case 170:
}
break;
case 171:
#line 1203 "dcParser.yxx"
#line 1208 "dcParser.yxx"
{
yyval.str = "";
}
break;
case 173:
#line 1211 "dcParser.yxx"
#line 1216 "dcParser.yxx"
{
yyval.u.dswitch = current_switch;
current_switch = new DCSwitch(yyvsp[-4].str, yyvsp[-2].u.parameter);
}
break;
case 174:
#line 1216 "dcParser.yxx"
#line 1221 "dcParser.yxx"
{
yyval.u.dswitch = current_switch;
current_switch = (DCSwitch *)yyvsp[-2].u.parameter;
}
break;
case 178:
#line 1228 "dcParser.yxx"
#line 1233 "dcParser.yxx"
{
if (current_switch->get_num_cases() == 0) {
yyerror("case declaration required before first element");
@ -2367,7 +2372,7 @@ case 178:
}
break;
case 179:
#line 1241 "dcParser.yxx"
#line 1246 "dcParser.yxx"
{
current_packer = &default_packer;
current_packer->clear_data();
@ -2375,7 +2380,7 @@ case 179:
}
break;
case 180:
#line 1247 "dcParser.yxx"
#line 1252 "dcParser.yxx"
{
if (!current_packer->end_pack()) {
yyerror("Invalid value for switch parameter");
@ -2385,13 +2390,13 @@ case 180:
}
break;
case 181:
#line 1258 "dcParser.yxx"
#line 1263 "dcParser.yxx"
{
yyval.u.field = yyvsp[-1].u.parameter;
}
break;
case 182:
#line 1262 "dcParser.yxx"
#line 1267 "dcParser.yxx"
{
yyval.u.field = yyvsp[0].u.parameter;
}
@ -2629,4 +2634,4 @@ yyreturn:
#endif
return yyresult;
}
#line 1270 "dcParser.yxx"
#line 1275 "dcParser.yxx"

View File

@ -276,7 +276,7 @@ dclass:
KW_DCLASS optional_name
{
$$ = current_class;
current_class = new DCClass($2, false, false);
current_class = new DCClass(dc_file, $2, false, false);
}
dclass_derivation '{' dclass_fields '}'
{
@ -296,7 +296,7 @@ dclass_name:
DCClass *dclass = dc_file->get_class_by_name($1);
if (dclass == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dclass = new DCClass($1, false, true);
dclass = new DCClass(dc_file, $1, false, true);
dc_file->add_class(dclass);
}
if (dclass->is_struct()) {
@ -322,9 +322,14 @@ dclass_base_list:
}
| dclass_base_list ',' dclass_name
{
if (!dc_multiple_inheritance) {
yyerror("Multiple inheritance is not supported without \"dc-multiple-inheritance 1\" in your Config.prc file.");
} else {
if ($3 != (DCClass *)NULL) {
current_class->add_parent($3);
}
}
}
;
@ -376,7 +381,7 @@ struct:
KW_STRUCT optional_name
{
$$ = current_class;
current_class = new DCClass($2, true, false);
current_class = new DCClass(dc_file, $2, true, false);
}
struct_derivation '{' struct_fields '}'
{
@ -396,7 +401,7 @@ struct_name:
DCClass *dstruct = dc_file->get_class_by_name($1);
if (dstruct == (DCClass *)NULL) {
// Create a bogus class as a forward reference.
dstruct = new DCClass($1, false, true);
dstruct = new DCClass(dc_file, $1, false, true);
dc_file->add_class(dstruct);
}
if (!dstruct->is_struct()) {

View File

@ -2475,7 +2475,7 @@ create_nested_field(DCSubatomicType type, unsigned int divisor) {
DCPackerInterface *DCSimpleParameter::
create_uint32uint8_type() {
if (_uint32uint8_type == NULL) {
DCClass *dclass = new DCClass("", true, false);
DCClass *dclass = new DCClass(NULL, "", true, false);
dclass->add_field(new DCSimpleParameter(ST_uint32));
dclass->add_field(new DCSimpleParameter(ST_uint8));
_uint32uint8_type = new DCClassParameter(dclass);

View File

@ -14,6 +14,7 @@ from direct.distributed.PyDatagram import PyDatagram
from direct.distributed.PyDatagramIterator import PyDatagramIterator
#from PointerToConnection import PointerToConnection
import time
import types
class ServerRepository:
@ -265,7 +266,12 @@ class ServerRepository:
doid = dgi.getUint32()
fieldid = dgi.getUint16()
dclass = self.DOIDtoDClass[doid]
dcfield = dclass.getField(fieldid)
dcfield = dclass.getFieldByIndex(fieldid)
if dcfield == None:
self.notify.error(
"Received update for field %s on object %s; no such field for class %s." % (
fieldid, doid, dclass.getName()))
return
if (dcfield.isBroadcast()):
if (dcfield.isP2p()):
self.sendToZoneExcept(self.DOIDtoZones[doid], datagram, 0)

View File

@ -510,11 +510,11 @@ describe_message(ostream &out, const string &prefix,
} else {
out << prefix << "update for " << dclass->get_name()
<< " " << do_id << ": ";
if (field_id < 0 || field_id >= dclass->get_num_inherited_fields()) {
DCField *field = dclass->get_field_by_index(field_id);
if (field == (DCField *)NULL) {
out << "unknown field " << field_id << "\n";
} else {
DCField *field = dclass->get_inherited_field(field_id);
out << field->get_name();
packer.begin_unpack(field);
packer.unpack_and_format(out);