mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
add virtual inheritance
This commit is contained in:
parent
d48ec456e3
commit
68bdff57eb
@ -18,7 +18,8 @@
|
||||
#define SOURCES \
|
||||
dcAtomicField.h dcClass.h dcClass.I \
|
||||
dcDeclaration.h \
|
||||
dcField.h dcFile.h \
|
||||
dcField.h dcField.I \
|
||||
dcFile.h dcFile.I \
|
||||
dcKeyword.h dcKeywordList.h \
|
||||
dcLexer.lxx \
|
||||
dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h \
|
||||
|
@ -27,6 +27,28 @@ get_dc_file() const {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -40,8 +40,22 @@ ConfigVariableBool dc_multiple_inheritance
|
||||
"supported, but field numbers will be numbered sequentially, "
|
||||
"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
|
||||
|
||||
class SortFieldsByIndex {
|
||||
public:
|
||||
inline bool operator ()(const DCField *a, const DCField *b) const {
|
||||
return a->get_number() < b->get_number();
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::Constructor
|
||||
// Access: Public
|
||||
@ -110,49 +124,26 @@ as_class() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::get_name
|
||||
// Function: DCClass::get_num_parents
|
||||
// Access: Published
|
||||
// Description: Returns the name of this class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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.
|
||||
// Description: Returns the number of base classes this class
|
||||
// inherits from.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DCClass::
|
||||
get_number() const {
|
||||
return _number;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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();
|
||||
get_num_parents() const {
|
||||
return _parents.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::get_parent
|
||||
// Access: Published
|
||||
// Description: Returns the parent class this class inherits from, if
|
||||
// any. It is an error to call this unless has_parent()
|
||||
// returned true.
|
||||
// Description: Returns the nth parent class this class inherits
|
||||
// from.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCClass *DCClass::
|
||||
get_parent() const {
|
||||
nassertr(has_parent(), NULL);
|
||||
return _parents.front();
|
||||
get_parent(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_parents.size(), NULL);
|
||||
return _parents[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -283,14 +274,25 @@ get_field_by_index(int index_number) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DCClass::
|
||||
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;
|
||||
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
|
||||
num_fields += (*pi)->get_num_inherited_fields();
|
||||
} else {
|
||||
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 num_fields;
|
||||
}
|
||||
|
||||
return num_fields;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -307,17 +309,29 @@ get_num_inherited_fields() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCField *DCClass::
|
||||
get_inherited_field(int n) const {
|
||||
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);
|
||||
if (dc_virtual_inheritance) {
|
||||
if (_dc_file != (DCFile *)NULL) {
|
||||
_dc_file->check_inherited_fields();
|
||||
}
|
||||
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
|
||||
// Access: Public
|
||||
@ -1270,10 +1353,16 @@ generate_hash(HashGenerator &hashgen) const {
|
||||
// class becomes the owner of the pointer and will
|
||||
// delete it when it destructs. Returns true if the
|
||||
// field is successfully added, or false if there was a
|
||||
// name conflict.
|
||||
// name conflict or some other problem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCClass::
|
||||
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() == _name) {
|
||||
// This field is a constructor.
|
||||
@ -1326,6 +1415,7 @@ add_field(DCField *field) {
|
||||
void DCClass::
|
||||
add_parent(DCClass *parent) {
|
||||
_parents.push_back(parent);
|
||||
_dc_file->mark_inherited_fields_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -29,10 +29,12 @@
|
||||
#include "configVariableBool.h"
|
||||
|
||||
extern ConfigVariableBool dc_multiple_inheritance;
|
||||
extern ConfigVariableBool dc_virtual_inheritance;
|
||||
|
||||
#else // WITHIN_PANDA
|
||||
|
||||
static const bool dc_multiple_inheritance = true;
|
||||
static const bool dc_virtual_inheritance = true;
|
||||
|
||||
#endif // WITHIN_PANDA
|
||||
|
||||
@ -56,17 +58,18 @@ PUBLISHED:
|
||||
|
||||
INLINE DCFile *get_dc_file() const;
|
||||
|
||||
const string &get_name() const;
|
||||
int get_number() const;
|
||||
INLINE const string &get_name() const;
|
||||
INLINE int get_number() const;
|
||||
|
||||
bool has_parent() const;
|
||||
DCClass *get_parent() const;
|
||||
int get_num_parents() const;
|
||||
DCClass *get_parent(int n) const;
|
||||
|
||||
bool has_constructor() const;
|
||||
DCField *get_constructor() const;
|
||||
|
||||
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;
|
||||
|
||||
@ -129,6 +132,8 @@ public:
|
||||
void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
void generate_hash(HashGenerator &hashgen) const;
|
||||
void clear_inherited_fields();
|
||||
void rebuild_inherited_fields();
|
||||
|
||||
bool add_field(DCField *field);
|
||||
void add_parent(DCClass *parent);
|
||||
@ -155,7 +160,7 @@ private:
|
||||
DCField *_constructor;
|
||||
|
||||
typedef pvector<DCField *> Fields;
|
||||
Fields _fields;
|
||||
Fields _fields, _inherited_fields;
|
||||
|
||||
typedef pmap<string, DCField *> FieldsByName;
|
||||
FieldsByName _fields_by_name;
|
||||
|
226
direct/src/dcparser/dcField.I
Normal file
226
direct/src/dcparser/dcField.I
Normal 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;
|
||||
}
|
@ -32,9 +32,11 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCField::
|
||||
DCField()
|
||||
DCField() :
|
||||
_dclass(NULL)
|
||||
#ifdef WITHIN_PANDA
|
||||
: _field_update_pcollector("DCField")
|
||||
,
|
||||
_field_update_pcollector("DCField")
|
||||
#endif
|
||||
{
|
||||
_number = -1;
|
||||
@ -57,7 +59,8 @@ DCField()
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCField::
|
||||
DCField(const string &name, DCClass *dclass) :
|
||||
DCPackerInterface(name)
|
||||
DCPackerInterface(name),
|
||||
_dclass(dclass)
|
||||
#ifdef WITHIN_PANDA
|
||||
,
|
||||
_field_update_pcollector(dclass->_class_update_pcollector, name)
|
||||
@ -85,18 +88,6 @@ 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
|
||||
// Access: Published, Virtual
|
||||
@ -250,155 +241,6 @@ validate_ranges(const string &packed_data) const {
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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_CHANNEL(to_id);
|
||||
packer.RAW_PACK_CHANNEL(from_id);
|
||||
//packer.raw_pack_uint8('A');
|
||||
packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
|
||||
packer.raw_pack_uint32(do_id);
|
||||
packer.raw_pack_uint16(_number);
|
||||
@ -683,27 +524,16 @@ pack_default_value(DCPackData &pack_data, bool &) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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.
|
||||
// Function: DCField::set_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Sets the name of this field.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCField::
|
||||
set_number(int number) {
|
||||
_number = number;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
set_name(const string &name) {
|
||||
DCPackerInterface::set_name(name);
|
||||
if (_dclass != (DCClass *)NULL) {
|
||||
_dclass->_dc_file->mark_inherited_fields_stale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -48,7 +48,8 @@ public:
|
||||
virtual ~DCField();
|
||||
|
||||
PUBLISHED:
|
||||
int get_number() const;
|
||||
INLINE int get_number() const;
|
||||
INLINE DCClass *get_class() const;
|
||||
|
||||
virtual DCField *as_field();
|
||||
virtual const DCField *as_field() const;
|
||||
@ -64,21 +65,21 @@ PUBLISHED:
|
||||
|
||||
bool validate_ranges(const string &packed_data) const;
|
||||
|
||||
bool has_default_value() const;
|
||||
const string &get_default_value() const;
|
||||
INLINE bool has_default_value() const;
|
||||
INLINE const string &get_default_value() const;
|
||||
|
||||
bool is_required() const;
|
||||
bool is_broadcast() const;
|
||||
bool is_ram() const;
|
||||
bool is_db() const;
|
||||
bool is_clsend() const;
|
||||
bool is_clrecv() const;
|
||||
bool is_ownsend() const;
|
||||
bool is_ownrecv() const;
|
||||
bool is_airecv() const;
|
||||
INLINE bool is_required() const;
|
||||
INLINE bool is_broadcast() const;
|
||||
INLINE bool is_ram() const;
|
||||
INLINE bool is_db() const;
|
||||
INLINE bool is_clsend() const;
|
||||
INLINE bool is_clrecv() const;
|
||||
INLINE bool is_ownsend() const;
|
||||
INLINE bool is_ownrecv() const;
|
||||
INLINE bool is_airecv() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level) const;
|
||||
INLINE void output(ostream &out) const;
|
||||
INLINE void write(ostream &out, int indent_level) const;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
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 generate_hash(HashGenerator &hashgen) 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);
|
||||
void set_default_value(const string &default_value);
|
||||
INLINE void set_number(int number);
|
||||
INLINE void set_class(DCClass *dclass);
|
||||
INLINE void set_default_value(const string &default_value);
|
||||
|
||||
protected:
|
||||
void refresh_default_value();
|
||||
|
||||
protected:
|
||||
DCClass *_dclass;
|
||||
int _number;
|
||||
bool _default_value_stale;
|
||||
bool _has_default_value;
|
||||
@ -121,4 +125,6 @@ INLINE ostream &operator << (ostream &out, const DCField &field) {
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "dcField.I"
|
||||
|
||||
#endif
|
||||
|
58
direct/src/dcparser/dcFile.I
Normal file
58
direct/src/dcparser/dcFile.I
Normal 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;
|
||||
}
|
@ -42,6 +42,7 @@
|
||||
DCFile::
|
||||
DCFile() {
|
||||
_all_objects_valid = true;
|
||||
_inherited_fields_stale = false;
|
||||
|
||||
setup_default_keywords();
|
||||
}
|
||||
@ -83,6 +84,7 @@ clear() {
|
||||
setup_default_keywords();
|
||||
|
||||
_all_objects_valid = true;
|
||||
_inherited_fields_stale = false;
|
||||
}
|
||||
|
||||
#ifdef WITHIN_PANDA
|
||||
@ -342,19 +344,6 @@ get_field_by_index(int index_number) const {
|
||||
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
|
||||
// Access: Published
|
||||
@ -510,6 +499,11 @@ get_hash() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
}
|
||||
|
||||
hashgen.add_int(_classes.size());
|
||||
Classes::const_iterator ci;
|
||||
for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
|
||||
@ -696,7 +690,7 @@ set_new_index_number(DCField *field) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCFile::setup_default_keywords
|
||||
// Access: Public
|
||||
// Access: Private
|
||||
// Description: Adds an entry for each of the default keywords that
|
||||
// are defined for every DCFile for legacy reasons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -729,3 +723,22 @@ setup_default_keywords() {
|
||||
_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();
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ PUBLISHED:
|
||||
|
||||
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;
|
||||
string get_import_module(int n) const;
|
||||
@ -87,9 +87,12 @@ public:
|
||||
void add_thing_to_delete(DCDeclaration *decl);
|
||||
|
||||
void set_new_index_number(DCField *field);
|
||||
INLINE void check_inherited_fields();
|
||||
INLINE void mark_inherited_fields_stale();
|
||||
|
||||
private:
|
||||
void setup_default_keywords();
|
||||
void rebuild_inherited_fields();
|
||||
|
||||
typedef pvector<DCClass *> Classes;
|
||||
Classes _classes;
|
||||
@ -124,8 +127,11 @@ private:
|
||||
FieldsByIndex _fields_by_index;
|
||||
|
||||
bool _all_objects_valid;
|
||||
bool _inherited_fields_stale;
|
||||
};
|
||||
|
||||
#include "dcFile.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -41,16 +41,6 @@ check_match(const DCPackerInterface *other) const {
|
||||
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
|
||||
// Access: Public
|
||||
|
@ -190,6 +190,16 @@ check_match(const string &description, DCFile *dcfile) const {
|
||||
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
|
||||
// Access: Public, Virtual
|
||||
|
@ -93,7 +93,7 @@ PUBLISHED:
|
||||
bool check_match(const string &description, DCFile *dcfile = NULL) const;
|
||||
|
||||
public:
|
||||
INLINE void set_name(const string &name);
|
||||
virtual void set_name(const string &name);
|
||||
INLINE bool has_fixed_byte_size() const;
|
||||
INLINE size_t get_fixed_byte_size() const;
|
||||
INLINE bool has_fixed_structure() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user