add virtual inheritance

This commit is contained in:
David Rose 2006-01-10 17:10:50 +00:00
parent d48ec456e3
commit 68bdff57eb
13 changed files with 537 additions and 280 deletions

View File

@ -18,7 +18,8 @@
#define SOURCES \ #define SOURCES \
dcAtomicField.h dcClass.h dcClass.I \ dcAtomicField.h dcClass.h dcClass.I \
dcDeclaration.h \ dcDeclaration.h \
dcField.h dcFile.h \ dcField.h dcField.I \
dcFile.h dcFile.I \
dcKeyword.h dcKeywordList.h \ dcKeyword.h dcKeywordList.h \
dcLexer.lxx \ dcLexer.lxx \
dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h \ dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h \

View File

@ -27,6 +27,28 @@ get_dc_file() const {
return _dc_file; return _dc_file;
} }
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_name
// Access: Published
// Description: Returns the name of this class.
////////////////////////////////////////////////////////////////////
INLINE const string &DCClass::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// class. This is defined implicitly when the .dc
// file(s) are read.
////////////////////////////////////////////////////////////////////
INLINE int DCClass::
get_number() const {
return _number;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCClass::is_struct // Function: DCClass::is_struct
// Access: Published // Access: Published

View File

@ -40,8 +40,22 @@ ConfigVariableBool dc_multiple_inheritance
"supported, but field numbers will be numbered sequentially, " "supported, but field numbers will be numbered sequentially, "
"which may be required to support old code that assumed this.")); "which may be required to support old code that assumed this."));
ConfigVariableBool dc_virtual_inheritance
("dc-virtual-inheritance", false,
PRC_DESC("Set this true to support proper virtual inheritance in the "
"dc file, so that diamond-of-death type constructs can be used. "
"This also enables shadowing (overloading) of inherited method "
"names from a base class."));
#endif // WITHIN_PANDA #endif // WITHIN_PANDA
class SortFieldsByIndex {
public:
inline bool operator ()(const DCField *a, const DCField *b) const {
return a->get_number() < b->get_number();
}
};
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCClass::Constructor // Function: DCClass::Constructor
// Access: Public // Access: Public
@ -110,49 +124,26 @@ as_class() const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCClass::get_name // Function: DCClass::get_num_parents
// Access: Published // Access: Published
// Description: Returns the name of this class. // Description: Returns the number of base classes this class
//////////////////////////////////////////////////////////////////// // inherits from.
const string &DCClass::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// class. This is defined implicitly when the .dc
// file(s) are read.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int DCClass:: int DCClass::
get_number() const { get_num_parents() const {
return _number; return _parents.size();
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::has_parent
// Access: Published
// Description: Returns true if this class inherits from some other
// class, false if it does not.
////////////////////////////////////////////////////////////////////
bool DCClass::
has_parent() const {
return !_parents.empty();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCClass::get_parent // Function: DCClass::get_parent
// Access: Published // Access: Published
// Description: Returns the parent class this class inherits from, if // Description: Returns the nth parent class this class inherits
// any. It is an error to call this unless has_parent() // from.
// returned true.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCClass *DCClass:: DCClass *DCClass::
get_parent() const { get_parent(int n) const {
nassertr(has_parent(), NULL); nassertr(n >= 0 && n < (int)_parents.size(), NULL);
return _parents.front(); return _parents[n];
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -283,14 +274,25 @@ get_field_by_index(int index_number) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int DCClass:: int DCClass::
get_num_inherited_fields() const { get_num_inherited_fields() const {
int num_fields = get_num_fields(); if (dc_virtual_inheritance) {
if (_dc_file != (DCFile *)NULL) {
_dc_file->check_inherited_fields();
}
if (_inherited_fields.empty()) {
((DCClass *)this)->rebuild_inherited_fields();
}
return (int)_inherited_fields.size();
Parents::const_iterator pi; } else {
for (pi = _parents.begin(); pi != _parents.end(); ++pi) { int num_fields = get_num_fields();
num_fields += (*pi)->get_num_inherited_fields();
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
num_fields += (*pi)->get_num_inherited_fields();
}
return num_fields;
} }
return num_fields;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -307,17 +309,29 @@ get_num_inherited_fields() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCField *DCClass:: DCField *DCClass::
get_inherited_field(int n) const { get_inherited_field(int n) const {
Parents::const_iterator pi; if (dc_virtual_inheritance) {
for (pi = _parents.begin(); pi != _parents.end(); ++pi) { if (_dc_file != (DCFile *)NULL) {
int psize = (*pi)->get_num_inherited_fields(); _dc_file->check_inherited_fields();
if (n < psize) {
return (*pi)->get_inherited_field(n);
} }
if (_inherited_fields.empty()) {
((DCClass *)this)->rebuild_inherited_fields();
}
nassertr(n >= 0 && n < (int)_inherited_fields.size(), NULL);
return _inherited_fields[n];
n -= psize; } else {
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
int psize = (*pi)->get_num_inherited_fields();
if (n < psize) {
return (*pi)->get_inherited_field(n);
}
n -= psize;
}
return get_field(n);
} }
return get_field(n);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1263,6 +1277,75 @@ generate_hash(HashGenerator &hashgen) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: DCClass::clear_inherited_fields
// Access: Public
// Description: Empties the list of inherited fields for the class,
// so that it may be rebuilt. This is normally only
// called by DCFile::rebuild_inherited_fields().
////////////////////////////////////////////////////////////////////
void DCClass::
clear_inherited_fields() {
_inherited_fields.clear();
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::rebuild_inherited_fields
// Access: Public
// Description: Recomputes the list of inherited fields for the class.
////////////////////////////////////////////////////////////////////
void DCClass::
rebuild_inherited_fields() {
typedef pset<string> Names;
Names names;
_inherited_fields.clear();
// First, get a list of all of the inherited field names.
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());
}
}
// 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.
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);
} else {
names.insert(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);
_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());
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCClass::add_field // Function: DCClass::add_field
// Access: Public // Access: Public
@ -1270,10 +1353,16 @@ generate_hash(HashGenerator &hashgen) const {
// class becomes the owner of the pointer and will // class becomes the owner of the pointer and will
// delete it when it destructs. Returns true if the // delete it when it destructs. Returns true if the
// field is successfully added, or false if there was a // field is successfully added, or false if there was a
// name conflict. // name conflict or some other problem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCClass:: bool DCClass::
add_field(DCField *field) { add_field(DCField *field) {
nassertr(field->get_class() == this || field->get_class() == NULL, false);
field->set_class(this);
if (_dc_file != (DCFile *)NULL) {
_dc_file->mark_inherited_fields_stale();
}
if (!field->get_name().empty()) { if (!field->get_name().empty()) {
if (field->get_name() == _name) { if (field->get_name() == _name) {
// This field is a constructor. // This field is a constructor.
@ -1326,6 +1415,7 @@ add_field(DCField *field) {
void DCClass:: void DCClass::
add_parent(DCClass *parent) { add_parent(DCClass *parent) {
_parents.push_back(parent); _parents.push_back(parent);
_dc_file->mark_inherited_fields_stale();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -29,10 +29,12 @@
#include "configVariableBool.h" #include "configVariableBool.h"
extern ConfigVariableBool dc_multiple_inheritance; extern ConfigVariableBool dc_multiple_inheritance;
extern ConfigVariableBool dc_virtual_inheritance;
#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;
#endif // WITHIN_PANDA #endif // WITHIN_PANDA
@ -56,17 +58,18 @@ PUBLISHED:
INLINE DCFile *get_dc_file() const; INLINE DCFile *get_dc_file() const;
const string &get_name() const; INLINE const string &get_name() const;
int get_number() const; INLINE int get_number() const;
bool has_parent() const; int get_num_parents() const;
DCClass *get_parent() const; DCClass *get_parent(int n) const;
bool has_constructor() const; bool has_constructor() const;
DCField *get_constructor() const; DCField *get_constructor() const;
int get_num_fields() const; int get_num_fields() const;
DCField *get_field(int n) const; DCField *get_field(int n) const;
DCField *get_field_by_name(const string &name) const; DCField *get_field_by_name(const string &name) const;
DCField *get_field_by_index(int index_number) const; DCField *get_field_by_index(int index_number) const;
@ -129,6 +132,8 @@ public:
void output_instance(ostream &out, bool brief, const string &prename, void output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const; const string &name, const string &postname) const;
void generate_hash(HashGenerator &hashgen) const; void generate_hash(HashGenerator &hashgen) const;
void clear_inherited_fields();
void rebuild_inherited_fields();
bool add_field(DCField *field); bool add_field(DCField *field);
void add_parent(DCClass *parent); void add_parent(DCClass *parent);
@ -155,7 +160,7 @@ private:
DCField *_constructor; DCField *_constructor;
typedef pvector<DCField *> Fields; typedef pvector<DCField *> Fields;
Fields _fields; Fields _fields, _inherited_fields;
typedef pmap<string, DCField *> FieldsByName; typedef pmap<string, DCField *> FieldsByName;
FieldsByName _fields_by_name; FieldsByName _fields_by_name;

View File

@ -0,0 +1,226 @@
// Filename: dcField.I
// Created by: drose (10Jan06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DCField::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// field. This is defined implicitly when the .dc
// file(s) are read.
////////////////////////////////////////////////////////////////////
INLINE int DCField::
get_number() const {
return _number;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::get_class
// Access: Published
// Description: Returns the DCClass pointer for the class that
// contains this field.
////////////////////////////////////////////////////////////////////
INLINE DCClass *DCField::
get_class() const {
return _dclass;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::has_default_value
// Access: Published
// Description: Returns true if a default value has been explicitly
// established for this field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
has_default_value() const {
return _has_default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::get_default_value
// Access: Published
// Description: Returns the default value for this field. If a
// default value has been explicitly set
// (e.g. has_default_value() returns true), returns that
// value; otherwise, returns an implicit default for the
// field.
////////////////////////////////////////////////////////////////////
INLINE const string &DCField::
get_default_value() const {
if (_default_value_stale) {
((DCField *)this)->refresh_default_value();
}
return _default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_required
// Access: Published
// Description: Returns true if the "required" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_required() const {
return has_keyword("required");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_broadcast
// Access: Published
// Description: Returns true if the "broadcast" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_broadcast() const {
return has_keyword("broadcast");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ram
// Access: Published
// Description: Returns true if the "ram" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_ram() const {
return has_keyword("ram");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_db
// Access: Published
// Description: Returns true if the "db" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_db() const {
return has_keyword("db");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clsend
// Access: Published
// Description: Returns true if the "clsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_clsend() const {
return has_keyword("clsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clrecv
// Access: Published
// Description: Returns true if the "clrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_clrecv() const {
return has_keyword("clrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownsend
// Access: Published
// Description: Returns true if the "ownsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_ownsend() const {
return has_keyword("ownsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownrecv
// Access: Published
// Description: Returns true if the "ownrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_ownrecv() const {
return has_keyword("ownrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_airecv
// Access: Published
// Description: Returns true if the "airecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool DCField::
is_airecv() const {
return has_keyword("airecv");
}
////////////////////////////////////////////////////////////////////
// Function : DCField::output
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
INLINE void DCField::
output(ostream &out) const {
output(out, true);
}
////////////////////////////////////////////////////////////////////
// Function : DCField::
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
INLINE void DCField::
write(ostream &out, int indent_level) const {
write(out, false, indent_level);
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_number
// Access: Public
// Description: Assigns the unique number to this field. This is
// normally called only by the DCClass interface as the
// field is added.
////////////////////////////////////////////////////////////////////
INLINE void DCField::
set_number(int number) {
_number = number;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_class
// Access: Public
// Description: Assigns the class pointer to this field. This is
// normally called only by the DCClass interface as the
// field is added.
////////////////////////////////////////////////////////////////////
INLINE void DCField::
set_class(DCClass *dclass) {
_dclass = dclass;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::set_default_value
// Access: Public
// Description: Establishes a default value for this field.
////////////////////////////////////////////////////////////////////
INLINE void DCField::
set_default_value(const string &default_value) {
_default_value = default_value;
_has_default_value = true;
_default_value_stale = false;
}

View File

@ -32,9 +32,11 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCField:: DCField::
DCField() DCField() :
_dclass(NULL)
#ifdef WITHIN_PANDA #ifdef WITHIN_PANDA
: _field_update_pcollector("DCField") ,
_field_update_pcollector("DCField")
#endif #endif
{ {
_number = -1; _number = -1;
@ -57,7 +59,8 @@ DCField()
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCField:: DCField::
DCField(const string &name, DCClass *dclass) : DCField(const string &name, DCClass *dclass) :
DCPackerInterface(name) DCPackerInterface(name),
_dclass(dclass)
#ifdef WITHIN_PANDA #ifdef WITHIN_PANDA
, ,
_field_update_pcollector(dclass->_class_update_pcollector, name) _field_update_pcollector(dclass->_class_update_pcollector, name)
@ -85,18 +88,6 @@ DCField::
~DCField() { ~DCField() {
} }
////////////////////////////////////////////////////////////////////
// Function: DCField::get_number
// Access: Published
// Description: Returns a unique index number associated with this
// field. This is defined implicitly when the .dc
// file(s) are read.
////////////////////////////////////////////////////////////////////
int DCField::
get_number() const {
return _number;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCField::as_field // Function: DCField::as_field
// Access: Published, Virtual // Access: Published, Virtual
@ -250,155 +241,6 @@ validate_ranges(const string &packed_data) const {
return (packer.get_num_unpacked_bytes() == packed_data.length()); return (packer.get_num_unpacked_bytes() == packed_data.length());
} }
////////////////////////////////////////////////////////////////////
// Function: DCField::has_default_value
// Access: Published
// Description: Returns true if a default value has been explicitly
// established for this field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
has_default_value() const {
return _has_default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::get_default_value
// Access: Published
// Description: Returns the default value for this field. If a
// default value has been explicitly set
// (e.g. has_default_value() returns true), returns that
// value; otherwise, returns an implicit default for the
// field.
////////////////////////////////////////////////////////////////////
const string &DCField::
get_default_value() const {
if (_default_value_stale) {
((DCField *)this)->refresh_default_value();
}
return _default_value;
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_required
// Access: Published
// Description: Returns true if the "required" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_required() const {
return has_keyword("required");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_broadcast
// Access: Published
// Description: Returns true if the "broadcast" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_broadcast() const {
return has_keyword("broadcast");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ram
// Access: Published
// Description: Returns true if the "ram" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_ram() const {
return has_keyword("ram");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_db
// Access: Published
// Description: Returns true if the "db" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_db() const {
return has_keyword("db");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clsend
// Access: Published
// Description: Returns true if the "clsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_clsend() const {
return has_keyword("clsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_clrecv
// Access: Published
// Description: Returns true if the "clrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_clrecv() const {
return has_keyword("clrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownsend
// Access: Published
// Description: Returns true if the "ownsend" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_ownsend() const {
return has_keyword("ownsend");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_ownrecv
// Access: Published
// Description: Returns true if the "ownrecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_ownrecv() const {
return has_keyword("ownrecv");
}
////////////////////////////////////////////////////////////////////
// Function: DCField::is_airecv
// Access: Published
// Description: Returns true if the "airecv" flag is set for this
// field, false otherwise.
////////////////////////////////////////////////////////////////////
bool DCField::
is_airecv() const {
return has_keyword("airecv");
}
////////////////////////////////////////////////////////////////////
// Function : DCField::output
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
void DCField::
output(ostream &out) const {
output(out, true);
}
////////////////////////////////////////////////////////////////////
// Function : DCField::
// Access : Published
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
void DCField::
write(ostream &out, int indent_level) const {
write(out, false, indent_level);
}
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCField::pack_args // Function: DCField::pack_args
@ -623,7 +465,6 @@ ai_format_update(int do_id, CHANNEL_TYPE to_id, CHANNEL_TYPE from_id, PyObject *
packer.raw_pack_uint8(1); packer.raw_pack_uint8(1);
packer.RAW_PACK_CHANNEL(to_id); packer.RAW_PACK_CHANNEL(to_id);
packer.RAW_PACK_CHANNEL(from_id); packer.RAW_PACK_CHANNEL(from_id);
//packer.raw_pack_uint8('A');
packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD); packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
packer.raw_pack_uint32(do_id); packer.raw_pack_uint32(do_id);
packer.raw_pack_uint16(_number); packer.raw_pack_uint16(_number);
@ -683,27 +524,16 @@ pack_default_value(DCPackData &pack_data, bool &) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCField::set_number // Function: DCField::set_name
// Access: Public // Access: Public, Virtual
// Description: Assigns the unique number to this field. This is // Description: Sets the name of this field.
// normally called only by the DCClass interface as the
// field is added.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DCField:: void DCField::
set_number(int number) { set_name(const string &name) {
_number = number; DCPackerInterface::set_name(name);
} if (_dclass != (DCClass *)NULL) {
_dclass->_dc_file->mark_inherited_fields_stale();
//////////////////////////////////////////////////////////////////// }
// Function: DCField::set_default_value
// Access: Public
// Description: Establishes a default value for this field.
////////////////////////////////////////////////////////////////////
void DCField::
set_default_value(const string &default_value) {
_default_value = default_value;
_has_default_value = true;
_default_value_stale = false;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -48,7 +48,8 @@ public:
virtual ~DCField(); virtual ~DCField();
PUBLISHED: PUBLISHED:
int get_number() const; INLINE int get_number() const;
INLINE DCClass *get_class() const;
virtual DCField *as_field(); virtual DCField *as_field();
virtual const DCField *as_field() const; virtual const DCField *as_field() const;
@ -64,21 +65,21 @@ PUBLISHED:
bool validate_ranges(const string &packed_data) const; bool validate_ranges(const string &packed_data) const;
bool has_default_value() const; INLINE bool has_default_value() const;
const string &get_default_value() const; INLINE const string &get_default_value() const;
bool is_required() const; INLINE bool is_required() const;
bool is_broadcast() const; INLINE bool is_broadcast() const;
bool is_ram() const; INLINE bool is_ram() const;
bool is_db() const; INLINE bool is_db() const;
bool is_clsend() const; INLINE bool is_clsend() const;
bool is_clrecv() const; INLINE bool is_clrecv() const;
bool is_ownsend() const; INLINE bool is_ownsend() const;
bool is_ownrecv() const; INLINE bool is_ownrecv() const;
bool is_airecv() const; INLINE bool is_airecv() const;
void output(ostream &out) const; INLINE void output(ostream &out) const;
void write(ostream &out, int indent_level) const; INLINE void write(ostream &out, int indent_level) const;
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
bool pack_args(DCPacker &packer, PyObject *sequence) const; bool pack_args(DCPacker &packer, PyObject *sequence) const;
@ -96,14 +97,17 @@ public:
virtual void write(ostream &out, bool brief, int indent_level) const=0; virtual void write(ostream &out, bool brief, int indent_level) const=0;
virtual void generate_hash(HashGenerator &hashgen) const; virtual void generate_hash(HashGenerator &hashgen) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const; virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
virtual void set_name(const string &name);
void set_number(int number); INLINE void set_number(int number);
void set_default_value(const string &default_value); INLINE void set_class(DCClass *dclass);
INLINE void set_default_value(const string &default_value);
protected: protected:
void refresh_default_value(); void refresh_default_value();
protected: protected:
DCClass *_dclass;
int _number; int _number;
bool _default_value_stale; bool _default_value_stale;
bool _has_default_value; bool _has_default_value;
@ -121,4 +125,6 @@ INLINE ostream &operator << (ostream &out, const DCField &field) {
return out; return out;
} }
#include "dcField.I"
#endif #endif

View File

@ -0,0 +1,58 @@
// Filename: dcFile.I
// Created by: drose (10Jan06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: DCFile::all_objects_valid
// Access: Published
// Description: Returns true if all of the classes read from the DC
// file were defined and valid, or false if any of them
// were undefined ("bogus classes"). If this is true,
// we might have read a partial file.
////////////////////////////////////////////////////////////////////
INLINE bool DCFile::
all_objects_valid() const {
return _all_objects_valid;
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::check_inherited_fields
// Access: Public
// Description: Rebuilds all of the inherited fields tables, if
// necessary.
////////////////////////////////////////////////////////////////////
INLINE void DCFile::
check_inherited_fields() {
if (_inherited_fields_stale) {
rebuild_inherited_fields();
}
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::mark_inherited_fields_stale
// Access: Public
// Description: Indicates that something has changed in one or more
// of the inheritance chains or the set of fields; the
// next time check_inherited_fields() is called, the
// inherited fields tables of all classes will be
// rebuilt.
////////////////////////////////////////////////////////////////////
INLINE void DCFile::
mark_inherited_fields_stale() {
_inherited_fields_stale = true;
}

View File

@ -42,6 +42,7 @@
DCFile:: DCFile::
DCFile() { DCFile() {
_all_objects_valid = true; _all_objects_valid = true;
_inherited_fields_stale = false;
setup_default_keywords(); setup_default_keywords();
} }
@ -83,6 +84,7 @@ clear() {
setup_default_keywords(); setup_default_keywords();
_all_objects_valid = true; _all_objects_valid = true;
_inherited_fields_stale = false;
} }
#ifdef WITHIN_PANDA #ifdef WITHIN_PANDA
@ -342,19 +344,6 @@ get_field_by_index(int index_number) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: DCFile::all_objects_valid
// Access: Published
// Description: Returns true if all of the classes read from the DC
// file were defined and valid, or false if any of them
// were undefined ("bogus classes"). If this is true,
// we might have read a partial file.
////////////////////////////////////////////////////////////////////
bool DCFile::
all_objects_valid() const {
return _all_objects_valid;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCFile::get_num_import_modules // Function: DCFile::get_num_import_modules
// Access: Published // Access: Published
@ -510,6 +499,11 @@ get_hash() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DCFile:: void DCFile::
generate_hash(HashGenerator &hashgen) const { generate_hash(HashGenerator &hashgen) const {
if (dc_virtual_inheritance) {
// Just to make the hash number change in this case.
hashgen.add_int(1);
}
hashgen.add_int(_classes.size()); hashgen.add_int(_classes.size());
Classes::const_iterator ci; Classes::const_iterator ci;
for (ci = _classes.begin(); ci != _classes.end(); ++ci) { for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
@ -696,7 +690,7 @@ set_new_index_number(DCField *field) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCFile::setup_default_keywords // Function: DCFile::setup_default_keywords
// Access: Public // Access: Private
// Description: Adds an entry for each of the default keywords that // Description: Adds an entry for each of the default keywords that
// are defined for every DCFile for legacy reasons. // are defined for every DCFile for legacy reasons.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -729,3 +723,22 @@ setup_default_keywords() {
_things_to_delete.push_back(keyword); _things_to_delete.push_back(keyword);
} }
} }
////////////////////////////////////////////////////////////////////
// Function: DCFile::rebuild_inherited_fields
// Access: Private
// Description: Reconstructs the inherited fields table of all
// classes.
////////////////////////////////////////////////////////////////////
void DCFile::
rebuild_inherited_fields() {
_inherited_fields_stale = false;
Classes::iterator ci;
for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
(*ci)->clear_inherited_fields();
}
for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
(*ci)->rebuild_inherited_fields();
}
}

View File

@ -59,7 +59,7 @@ PUBLISHED:
DCField *get_field_by_index(int index_number) const; DCField *get_field_by_index(int index_number) const;
bool all_objects_valid() const; INLINE bool all_objects_valid() const;
int get_num_import_modules() const; int get_num_import_modules() const;
string get_import_module(int n) const; string get_import_module(int n) const;
@ -87,9 +87,12 @@ public:
void add_thing_to_delete(DCDeclaration *decl); void add_thing_to_delete(DCDeclaration *decl);
void set_new_index_number(DCField *field); void set_new_index_number(DCField *field);
INLINE void check_inherited_fields();
INLINE void mark_inherited_fields_stale();
private: private:
void setup_default_keywords(); void setup_default_keywords();
void rebuild_inherited_fields();
typedef pvector<DCClass *> Classes; typedef pvector<DCClass *> Classes;
Classes _classes; Classes _classes;
@ -124,8 +127,11 @@ private:
FieldsByIndex _fields_by_index; FieldsByIndex _fields_by_index;
bool _all_objects_valid; bool _all_objects_valid;
bool _inherited_fields_stale;
}; };
#include "dcFile.I"
#endif #endif

View File

@ -41,16 +41,6 @@ check_match(const DCPackerInterface *other) const {
return do_check_match(other); return do_check_match(other);
} }
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::set_name
// Access: Public
// Description: Sets the name of this field.
////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface::
set_name(const string &name) {
_name = name;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::has_fixed_byte_size // Function: DCPackerInterface::has_fixed_byte_size
// Access: Public // Access: Public

View File

@ -190,6 +190,16 @@ check_match(const string &description, DCFile *dcfile) const {
return false; return false;
} }
////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::set_name
// Access: Public, Virtual
// Description: Sets the name of this field.
////////////////////////////////////////////////////////////////////
void DCPackerInterface::
set_name(const string &name) {
_name = name;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::calc_num_nested_fields // Function: DCPackerInterface::calc_num_nested_fields
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -93,7 +93,7 @@ PUBLISHED:
bool check_match(const string &description, DCFile *dcfile = NULL) const; bool check_match(const string &description, DCFile *dcfile = NULL) const;
public: public:
INLINE void set_name(const string &name); virtual void set_name(const string &name);
INLINE bool has_fixed_byte_size() const; INLINE bool has_fixed_byte_size() const;
INLINE size_t get_fixed_byte_size() const; INLINE size_t get_fixed_byte_size() const;
INLINE bool has_fixed_structure() const; INLINE bool has_fixed_structure() const;