mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
struct and switch are now inline
This commit is contained in:
parent
09e9ed12df
commit
932359216f
@ -24,7 +24,8 @@
|
||||
dcPacker.h dcPacker.I \
|
||||
dcPackerCatalog.h dcPackerCatalog.I \
|
||||
dcPackerInterface.h dcPackerInterface.I \
|
||||
dcParameter.h dcClassParameter.h dcArrayParameter.h dcSimpleParameter.h \
|
||||
dcParameter.h dcClassParameter.h dcArrayParameter.h \
|
||||
dcSimpleParameter.h dcSwitchParameter.h \
|
||||
dcNumericRange.h dcNumericRange.I \
|
||||
dcSwitch.h \
|
||||
dcTypedef.h \
|
||||
@ -41,8 +42,8 @@
|
||||
dcPacker.cxx \
|
||||
dcPackerCatalog.cxx \
|
||||
dcPackerInterface.cxx \
|
||||
dcParameter.cxx dcClassParameter.cxx \
|
||||
dcArrayParameter.cxx dcSimpleParameter.cxx \
|
||||
dcParameter.cxx dcClassParameter.cxx dcArrayParameter.cxx \
|
||||
dcSimpleParameter.cxx dcSwitchParameter.cxx \
|
||||
dcSwitch.cxx \
|
||||
dcTypedef.cxx \
|
||||
dcindent.cxx \
|
||||
|
@ -188,10 +188,10 @@ validate_num_nested_fields(int num_nested_fields) const {
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCArrayParameter::
|
||||
output_instance(ostream &out, const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
if (get_typedef() != (DCTypedef *)NULL) {
|
||||
output_typedef_name(out, prename, name, postname);
|
||||
output_typedef_name(out, brief, prename, name, postname);
|
||||
|
||||
} else {
|
||||
ostringstream strm;
|
||||
@ -200,7 +200,8 @@ output_instance(ostream &out, const string &prename, const string &name,
|
||||
_array_size_range.output(strm);
|
||||
strm << "]";
|
||||
|
||||
_element_type->output_instance(out, prename, name, strm.str() + postname);
|
||||
_element_type->output_instance(out, brief, prename, name,
|
||||
strm.str() + postname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
virtual DCPackerInterface *get_nested_field(int n) const;
|
||||
virtual bool validate_num_nested_fields(int num_nested_fields) const;
|
||||
|
||||
virtual void output_instance(ostream &out, const string &prename,
|
||||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -266,15 +266,13 @@ compare_flags(const DCAtomicField &other) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::write
|
||||
// Function: DCAtomicField::output
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< _name << "(";
|
||||
output(ostream &out, bool brief) const {
|
||||
out << _name << "(";
|
||||
|
||||
if (!_elements.empty()) {
|
||||
Elements::const_iterator ei = _elements.begin();
|
||||
@ -317,6 +315,18 @@ write(ostream &out, bool brief, int indent_level) const {
|
||||
}
|
||||
|
||||
out << ";";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCAtomicField::write
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCAtomicField::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level);
|
||||
output(out, brief);
|
||||
if (!brief && _number >= 0) {
|
||||
out << " // field " << _number;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ PUBLISHED:
|
||||
bool compare_flags(const DCAtomicField &other) const;
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out, bool brief) const;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -57,6 +57,16 @@ DCClass::
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::as_class
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCClass *DCClass::
|
||||
as_class() {
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::get_name
|
||||
// Access: Published
|
||||
@ -263,7 +273,7 @@ set_class_def(PyObject *class_def) {
|
||||
PyObject *DCClass::
|
||||
get_class_def() const {
|
||||
if (_class_def == NULL) {
|
||||
return Py_BuildValue("");
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(_class_def);
|
||||
@ -435,7 +445,7 @@ pack_required_field(DCPacker &packer, PyObject *distobj,
|
||||
ostringstream strm;
|
||||
strm << "Data element " << field_name
|
||||
<< ", required by dc file for dclass " << get_name()
|
||||
<< ", not defined on object.";
|
||||
<< ", not defined on object";
|
||||
nassert_raise(strm.str());
|
||||
return false;
|
||||
}
|
||||
@ -661,9 +671,12 @@ void DCClass::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level);
|
||||
if (_is_struct) {
|
||||
out << "struct " << _name;
|
||||
out << "struct";
|
||||
} else {
|
||||
out << "dclass " << _name;
|
||||
out << "dclass";
|
||||
}
|
||||
if (!_name.empty()) {
|
||||
out << " " << _name;
|
||||
}
|
||||
|
||||
if (!_parents.empty()) {
|
||||
@ -690,6 +703,48 @@ write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level) << "};\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::output_instance
|
||||
// Access: Public
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClass::
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
if (_is_struct) {
|
||||
out << "struct";
|
||||
} else {
|
||||
out << "dclass";
|
||||
}
|
||||
if (!_name.empty()) {
|
||||
out << " " << _name;
|
||||
}
|
||||
|
||||
if (!_parents.empty()) {
|
||||
Parents::const_iterator pi = _parents.begin();
|
||||
out << " : " << (*pi)->_name;
|
||||
++pi;
|
||||
while (pi != _parents.end()) {
|
||||
out << ", " << (*pi)->_name;
|
||||
++pi;
|
||||
}
|
||||
}
|
||||
|
||||
out << " {";
|
||||
|
||||
Fields::const_iterator fi;
|
||||
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
|
||||
(*fi)->output(out, brief);
|
||||
out << "; ";
|
||||
}
|
||||
|
||||
out << "}";
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::generate_hash
|
||||
// Access: Public, Virtual
|
||||
|
@ -38,6 +38,8 @@ public:
|
||||
~DCClass();
|
||||
|
||||
PUBLISHED:
|
||||
virtual DCClass *as_class();
|
||||
|
||||
const string &get_name() const;
|
||||
int get_number() const;
|
||||
|
||||
@ -83,6 +85,8 @@ PUBLISHED:
|
||||
|
||||
public:
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
bool add_field(DCField *field);
|
||||
|
@ -123,16 +123,13 @@ get_nested_field(int n) const {
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCClassParameter::
|
||||
output_instance(ostream &out, const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
if (get_typedef() != (DCTypedef *)NULL) {
|
||||
output_typedef_name(out, prename, name, postname);
|
||||
output_typedef_name(out, brief, prename, name, postname);
|
||||
|
||||
} else {
|
||||
out << get_name();
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
_dclass->output_instance(out, brief, prename, name, postname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual DCPackerInterface *get_nested_field(int n) const;
|
||||
|
||||
virtual void output_instance(ostream &out, const string &prename,
|
||||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -27,3 +27,23 @@
|
||||
DCDeclaration::
|
||||
~DCDeclaration() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCDeclaration::as_class
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCClass *DCDeclaration::
|
||||
as_class() {
|
||||
return (DCClass *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCDeclaration::as_switch
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitch *DCDeclaration::
|
||||
as_switch() {
|
||||
return (DCSwitch *)NULL;
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#include "dcbase.h"
|
||||
|
||||
class DCClass;
|
||||
class DCSwitch;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DCDeclaration
|
||||
// Description : This is a common interface for a declaration in a DC
|
||||
@ -34,6 +37,12 @@
|
||||
class EXPCL_DIRECT DCDeclaration {
|
||||
public:
|
||||
virtual ~DCDeclaration();
|
||||
|
||||
PUBLISHED:
|
||||
virtual DCClass *as_class();
|
||||
virtual DCSwitch *as_switch();
|
||||
|
||||
public:
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const=0;
|
||||
};
|
||||
|
||||
|
@ -66,6 +66,7 @@ PUBLISHED:
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out, bool brief) const=0;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const=0;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dcFile.h"
|
||||
#include "dcClass.h"
|
||||
#include "dcSwitch.h"
|
||||
#include "dcParserDefs.h"
|
||||
#include "dcLexerDefs.h"
|
||||
#include "dcTypedef.h"
|
||||
@ -65,7 +67,7 @@ clear() {
|
||||
|
||||
_classes.clear();
|
||||
_imports.clear();
|
||||
_classes_by_name.clear();
|
||||
_things_by_name.clear();
|
||||
}
|
||||
|
||||
#ifdef WITHIN_PANDA
|
||||
@ -273,15 +275,32 @@ get_class(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCClass *DCFile::
|
||||
get_class_by_name(const string &name) const {
|
||||
ClassesByName::const_iterator ni;
|
||||
ni = _classes_by_name.find(name);
|
||||
if (ni != _classes_by_name.end()) {
|
||||
return (*ni).second;
|
||||
ThingsByName::const_iterator ni;
|
||||
ni = _things_by_name.find(name);
|
||||
if (ni != _things_by_name.end()) {
|
||||
return (*ni).second->as_class();
|
||||
}
|
||||
|
||||
return (DCClass *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCFile::get_switch_by_name
|
||||
// Access: Published
|
||||
// Description: Returns the switch that has the indicated name, or
|
||||
// NULL if there is no such switch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitch *DCFile::
|
||||
get_switch_by_name(const string &name) const {
|
||||
ThingsByName::const_iterator ni;
|
||||
ni = _things_by_name.find(name);
|
||||
if (ni != _things_by_name.end()) {
|
||||
return (*ni).second->as_switch();
|
||||
}
|
||||
|
||||
return (DCSwitch *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCFile::all_objects_valid
|
||||
// Access: Published
|
||||
@ -426,11 +445,13 @@ generate_hash(HashGenerator &hashgen) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCFile::
|
||||
add_class(DCClass *dclass) {
|
||||
bool inserted = _classes_by_name.insert
|
||||
(ClassesByName::value_type(dclass->get_name(), dclass)).second;
|
||||
|
||||
if (!inserted) {
|
||||
return false;
|
||||
if (!dclass->get_name().empty()) {
|
||||
bool inserted = _things_by_name.insert
|
||||
(ThingsByName::value_type(dclass->get_name(), dclass)).second;
|
||||
|
||||
if (!inserted) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dclass->set_number(get_num_classes());
|
||||
@ -447,6 +468,31 @@ add_class(DCClass *dclass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCFile::add_switch
|
||||
// Access: Public
|
||||
// Description: Adds the newly-allocated switch definition
|
||||
// to the file. The DCFile becomes the owner of the
|
||||
// pointer and will delete it when it destructs.
|
||||
// Returns true if the switch is successfully added, or
|
||||
// false if there was a name conflict.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCFile::
|
||||
add_switch(DCSwitch *dswitch) {
|
||||
if (!dswitch->get_name().empty()) {
|
||||
bool inserted = _things_by_name.insert
|
||||
(ThingsByName::value_type(dswitch->get_name(), dswitch)).second;
|
||||
|
||||
if (!inserted) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_declarations.push_back(dswitch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCFile::add_import_module
|
||||
// Access: Public
|
||||
|
@ -20,8 +20,9 @@
|
||||
#define DCFILE_H
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "dcClass.h"
|
||||
|
||||
class DCClass;
|
||||
class DCSwitch;
|
||||
class HashGenerator;
|
||||
class DCTypedef;
|
||||
class DCDeclaration;
|
||||
@ -51,6 +52,7 @@ PUBLISHED:
|
||||
int get_num_classes() const;
|
||||
DCClass *get_class(int n) const;
|
||||
DCClass *get_class_by_name(const string &name) const;
|
||||
DCSwitch *get_switch_by_name(const string &name) const;
|
||||
|
||||
bool all_objects_valid() const;
|
||||
|
||||
@ -68,6 +70,7 @@ PUBLISHED:
|
||||
public:
|
||||
void generate_hash(HashGenerator &hashgen) const;
|
||||
bool add_class(DCClass *dclass);
|
||||
bool add_switch(DCSwitch *dswitch);
|
||||
void add_import_module(const string &import_module);
|
||||
void add_import_symbol(const string &import_symbol);
|
||||
bool add_typedef(DCTypedef *dtypedef);
|
||||
@ -76,8 +79,8 @@ private:
|
||||
typedef pvector<DCClass *> Classes;
|
||||
Classes _classes;
|
||||
|
||||
typedef pmap<string, DCClass *> ClassesByName;
|
||||
ClassesByName _classes_by_name;
|
||||
typedef pmap<string, DCDeclaration *> ThingsByName;
|
||||
ThingsByName _things_by_name;
|
||||
|
||||
typedef pvector<string> ImportSymbols;
|
||||
class Import {
|
||||
|
@ -102,14 +102,13 @@ add_atomic(DCAtomicField *atomic) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCMolecularField::write
|
||||
// Function: DCMolecularField::output
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCMolecularField::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level) << _name;
|
||||
output(ostream &out, bool brief) const {
|
||||
out << _name;
|
||||
|
||||
if (!_fields.empty()) {
|
||||
Fields::const_iterator fi = _fields.begin();
|
||||
@ -122,6 +121,18 @@ write(ostream &out, bool brief, int indent_level) const {
|
||||
}
|
||||
|
||||
out << ";";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCMolecularField::write
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCMolecularField::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
indent(out, indent_level);
|
||||
output(out, brief);
|
||||
if (!brief) {
|
||||
out << " // field " << _number;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ PUBLISHED:
|
||||
public:
|
||||
void add_atomic(DCAtomicField *atomic);
|
||||
|
||||
virtual void output(ostream &out, bool brief) const;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -127,7 +127,7 @@ get_current_field() const {
|
||||
// get_current_parent() will contain the particular
|
||||
// SwitchCase that was selected by the switch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const DCSwitch *DCPacker::
|
||||
INLINE const DCSwitchParameter *DCPacker::
|
||||
get_last_switch() const {
|
||||
return _last_switch;
|
||||
}
|
||||
@ -1122,9 +1122,9 @@ advance() {
|
||||
// But if the parent is a switch record, we make a special case so
|
||||
// we can get the alternate fields.
|
||||
if (_current_parent != (DCPackerInterface *)NULL) {
|
||||
const DCSwitch *dswitch = ((DCPackerInterface *)_current_parent)->as_switch();
|
||||
if (dswitch != (DCSwitch *)NULL) {
|
||||
handle_switch(dswitch);
|
||||
const DCSwitchParameter *switch_parameter = ((DCPackerInterface *)_current_parent)->as_switch_parameter();
|
||||
if (switch_parameter != (DCSwitchParameter *)NULL) {
|
||||
handle_switch(switch_parameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "dcParserDefs.h"
|
||||
#include "dcLexerDefs.h"
|
||||
#include "dcClassParameter.h"
|
||||
#include "dcSwitchParameter.h"
|
||||
#include "dcClass.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -351,7 +352,7 @@ seek(const string &field_name) {
|
||||
|
||||
const DCPackerCatalog::Entry &entry = _live_catalog->get_entry(entry_index);
|
||||
|
||||
if (((DCPackerInterface *)entry._parent)->as_switch() != (DCSwitch *)NULL) {
|
||||
if (((DCPackerInterface *)entry._parent)->as_switch_parameter() != (DCSwitchParameter *)NULL) {
|
||||
// If the parent is a DCSwitch, that can only mean that the
|
||||
// seeked field is a switch parameter. We can't support seeking
|
||||
// to a switch parameter and modifying it directly--what would
|
||||
@ -653,13 +654,20 @@ pack_object(PyObject *object) {
|
||||
}
|
||||
|
||||
} else {
|
||||
int size = PySequence_Size(object);
|
||||
bool is_instance = false;
|
||||
|
||||
DCClass *dclass = NULL;
|
||||
const DCClassParameter *class_param = ((DCPackerInterface *)get_current_field())->as_class_parameter();
|
||||
if (class_param != (DCClassParameter *)NULL) {
|
||||
dclass = class_param->get_class();
|
||||
}
|
||||
|
||||
int size = PySequence_Size(object);
|
||||
if (dclass->has_class_def()) {
|
||||
PyObject *class_def = dclass->get_class_def();
|
||||
is_instance = (PyObject_IsInstance(object, dclass->get_class_def()) != 0);
|
||||
Py_DECREF(class_def);
|
||||
}
|
||||
}
|
||||
|
||||
// If dclass is not NULL, the packer is expecting a class object.
|
||||
// There are then two cases: (1) the user has supplied a matching
|
||||
@ -678,10 +686,7 @@ pack_object(PyObject *object) {
|
||||
|
||||
// (3) Otherwise, it is considered to be a class object.
|
||||
|
||||
if (dclass != (DCClass *)NULL &&
|
||||
((dclass->get_class_def() != (PyObject *)NULL &&
|
||||
PyObject_IsInstance(object, dclass->get_class_def())) ||
|
||||
size < 0)) {
|
||||
if (dclass != (DCClass *)NULL && (is_instance || size < 0)) {
|
||||
// The supplied object is either an instance of the expected
|
||||
// class object, or the size is less than 0--this is case (1) or
|
||||
// (3).
|
||||
@ -689,7 +694,7 @@ pack_object(PyObject *object) {
|
||||
|
||||
} else if (size >= 0) {
|
||||
// The supplied object is not an instance of the expected class
|
||||
// object, and it does return a valid size. This is case (2).
|
||||
// object, but it does have a size. This is case (2).
|
||||
push();
|
||||
int size = PySequence_Size(object);
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -1021,20 +1026,19 @@ output_hex_string(ostream &out, const string &str) {
|
||||
// appropriate case of the switch record.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPacker::
|
||||
handle_switch(const DCSwitch *dswitch) {
|
||||
handle_switch(const DCSwitchParameter *switch_parameter) {
|
||||
// First, get the value from the key. This is either found in the
|
||||
// unpack or the pack data, depending on what mode we're in.
|
||||
const DCPackerInterface *new_parent = NULL;
|
||||
|
||||
if (_mode == M_pack || _mode == M_repack) {
|
||||
const char *data = _pack_data.get_data();
|
||||
new_parent = dswitch->apply_switch(data + _push_marker,
|
||||
_pack_data.get_length() - _push_marker);
|
||||
new_parent = switch_parameter->apply_switch
|
||||
(data + _push_marker, _pack_data.get_length() - _push_marker);
|
||||
|
||||
} else if (_mode == M_unpack) {
|
||||
new_parent = dswitch->apply_switch(_unpack_data + _push_marker,
|
||||
_unpack_p - _push_marker);
|
||||
|
||||
new_parent = switch_parameter->apply_switch
|
||||
(_unpack_data + _push_marker, _unpack_p - _push_marker);
|
||||
}
|
||||
|
||||
if (new_parent == (DCPackerInterface *)NULL) {
|
||||
@ -1043,7 +1047,7 @@ handle_switch(const DCSwitch *dswitch) {
|
||||
return;
|
||||
}
|
||||
|
||||
_last_switch = dswitch;
|
||||
_last_switch = switch_parameter;
|
||||
|
||||
// Now substitute in the switch case for the previous parent (which
|
||||
// replaces the switch node itself). This will suddenly make a slew
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "dcPython.h"
|
||||
|
||||
class DCClass;
|
||||
class DCSwitch;
|
||||
class DCSwitchParametera;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DCPacker
|
||||
@ -69,7 +69,7 @@ PUBLISHED:
|
||||
|
||||
INLINE const DCPackerInterface *get_current_parent() const;
|
||||
INLINE const DCPackerInterface *get_current_field() const;
|
||||
INLINE const DCSwitch *get_last_switch() const;
|
||||
INLINE const DCSwitchParameter *get_last_switch() const;
|
||||
INLINE DCPackType get_pack_type() const;
|
||||
|
||||
void push();
|
||||
@ -174,7 +174,7 @@ public:
|
||||
|
||||
private:
|
||||
INLINE void advance();
|
||||
void handle_switch(const DCSwitch *dswitch);
|
||||
void handle_switch(const DCSwitchParameter *switch_parameter);
|
||||
void clear();
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
@ -226,7 +226,7 @@ private:
|
||||
// use.
|
||||
size_t _pop_marker;
|
||||
int _num_nested_fields;
|
||||
const DCSwitch *_last_switch;
|
||||
const DCSwitchParameter *_last_switch;
|
||||
|
||||
bool _pack_error;
|
||||
bool _range_error;
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "dcPackerCatalog.h"
|
||||
#include "dcPackerInterface.h"
|
||||
#include "dcPacker.h"
|
||||
#include "dcSwitch.h"
|
||||
#include "dcSwitchParameter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCPackerCatalog::Constructor
|
||||
@ -135,7 +135,7 @@ get_live_catalog(const char *data, size_t length) const {
|
||||
DCPacker packer;
|
||||
packer.set_unpack_data(data, length, false);
|
||||
packer.begin_unpack(_root);
|
||||
const DCSwitch *last_switch = NULL;
|
||||
const DCSwitchParameter *last_switch = NULL;
|
||||
r_fill_live_catalog(live_catalog, packer, last_switch);
|
||||
bool okflag = packer.end_unpack();
|
||||
|
||||
@ -207,7 +207,7 @@ r_fill_catalog(const string &name_prefix, const DCPackerInterface *field,
|
||||
const DCPackerInterface *parent, int field_index) {
|
||||
string next_name_prefix = name_prefix;
|
||||
|
||||
if (!field->get_name().empty()) {
|
||||
if (parent != (const DCPackerInterface *)NULL && !field->get_name().empty()) {
|
||||
// Record this entry in the catalog.
|
||||
next_name_prefix += field->get_name();
|
||||
add_entry(next_name_prefix, field, parent, field_index);
|
||||
@ -215,14 +215,14 @@ r_fill_catalog(const string &name_prefix, const DCPackerInterface *field,
|
||||
next_name_prefix += ".";
|
||||
}
|
||||
|
||||
const DCSwitch *dswitch = ((DCPackerInterface *)field)->as_switch();
|
||||
if (dswitch != (DCSwitch *)NULL) {
|
||||
const DCSwitchParameter *switch_parameter = ((DCPackerInterface *)field)->as_switch_parameter();
|
||||
if (switch_parameter != (DCSwitchParameter *)NULL) {
|
||||
// If we come upon a DCSwitch while building the catalog, save the
|
||||
// name_prefix at this point so we'll have it again when we later
|
||||
// encounter the switch while unpacking a live record (and so we
|
||||
// can return to this point in the recursion from
|
||||
// update_switch_fields).
|
||||
_switch_prefixes[dswitch] = next_name_prefix;
|
||||
_switch_prefixes[switch_parameter] = next_name_prefix;
|
||||
}
|
||||
|
||||
// Add any children.
|
||||
@ -247,7 +247,7 @@ r_fill_catalog(const string &name_prefix, const DCPackerInterface *field,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCPackerCatalog::
|
||||
r_fill_live_catalog(LiveCatalog *live_catalog, DCPacker &packer,
|
||||
const DCSwitch *&last_switch) const {
|
||||
const DCSwitchParameter *&last_switch) const {
|
||||
const DCPackerInterface *current_field = packer.get_current_field();
|
||||
|
||||
int field_index = live_catalog->find_entry_by_field(current_field);
|
||||
@ -281,6 +281,7 @@ r_fill_live_catalog(LiveCatalog *live_catalog, DCPacker &packer,
|
||||
nassertv(switch_case != (DCPackerInterface *)NULL);
|
||||
const DCPackerCatalog *switch_catalog =
|
||||
live_catalog->_catalog->update_switch_fields(last_switch, switch_case);
|
||||
nassertv(switch_catalog != (DCPackerCatalog *)NULL);
|
||||
live_catalog->_catalog = switch_catalog;
|
||||
|
||||
// And we also have to expand the live catalog to hold the new
|
||||
@ -315,7 +316,7 @@ r_fill_live_catalog(LiveCatalog *live_catalog, DCPacker &packer,
|
||||
// pointer is kept by this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const DCPackerCatalog *DCPackerCatalog::
|
||||
update_switch_fields(const DCSwitch *dswitch,
|
||||
update_switch_fields(const DCSwitchParameter *switch_parameter,
|
||||
const DCPackerInterface *switch_case) const {
|
||||
SwitchCatalogs::const_iterator si = _switch_catalogs.find(switch_case);
|
||||
if (si != _switch_catalogs.end()) {
|
||||
@ -326,7 +327,7 @@ update_switch_fields(const DCSwitch *dswitch,
|
||||
// descend from this switch. This should be stored in this record
|
||||
// because we must have come across the DCSwitch when building the
|
||||
// catalog the first time.
|
||||
SwitchPrefixes::const_iterator pi = _switch_prefixes.find(dswitch);
|
||||
SwitchPrefixes::const_iterator pi = _switch_prefixes.find(switch_parameter);
|
||||
nassertr(pi != _switch_prefixes.end(), NULL);
|
||||
string name_prefix = (*pi).second;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
class DCPackerInterface;
|
||||
class DCPacker;
|
||||
class DCSwitch;
|
||||
class DCSwitchParameter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DCPackerCatalog
|
||||
@ -92,9 +92,9 @@ private:
|
||||
void r_fill_catalog(const string &name_prefix, const DCPackerInterface *field,
|
||||
const DCPackerInterface *parent, int field_index);
|
||||
void r_fill_live_catalog(LiveCatalog *live_catalog, DCPacker &packer,
|
||||
const DCSwitch *&last_switch) const;
|
||||
const DCSwitchParameter *&last_switch) const;
|
||||
|
||||
const DCPackerCatalog *update_switch_fields(const DCSwitch *dswitch,
|
||||
const DCPackerCatalog *update_switch_fields(const DCSwitchParameter *dswitch,
|
||||
const DCPackerInterface *switch_case) const;
|
||||
|
||||
|
||||
@ -113,7 +113,7 @@ private:
|
||||
typedef pmap<const DCPackerInterface *, DCPackerCatalog *> SwitchCatalogs;
|
||||
SwitchCatalogs _switch_catalogs;
|
||||
|
||||
typedef pmap<const DCSwitch *, string> SwitchPrefixes;
|
||||
typedef pmap<const DCSwitchParameter *, string> SwitchPrefixes;
|
||||
SwitchPrefixes _switch_prefixes;
|
||||
|
||||
friend class DCPackerInterface;
|
||||
|
@ -84,9 +84,9 @@ as_field() {
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitch *DCPackerInterface::
|
||||
as_switch() {
|
||||
return (DCSwitch *)NULL;
|
||||
DCSwitchParameter *DCPackerInterface::
|
||||
as_switch_parameter() {
|
||||
return (DCSwitchParameter *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -326,17 +326,5 @@ make_catalog() {
|
||||
nassertv(_catalog == (DCPackerCatalog *)NULL);
|
||||
_catalog = new DCPackerCatalog(this);
|
||||
|
||||
if (has_nested_fields()) {
|
||||
int num_nested = get_num_nested_fields();
|
||||
// num_nested might be -1, indicating there are a dynamic number
|
||||
// of fields (e.g. an array). But in that case, none of the
|
||||
// fields will be named anyway, so we don't care about them, so
|
||||
// it's ok that the following loop will not visit any fields.
|
||||
for (int i = 0; i < num_nested; i++) {
|
||||
DCPackerInterface *nested = get_nested_field(i);
|
||||
if (nested != (DCPackerInterface *)NULL) {
|
||||
_catalog->r_fill_catalog("", nested, this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
_catalog->r_fill_catalog("", this, NULL, 0);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "dcSubatomicType.h"
|
||||
|
||||
class DCField;
|
||||
class DCSwitch;
|
||||
class DCSwitchParameter;
|
||||
class DCClassParameter;
|
||||
class DCPackData;
|
||||
class DCPackerCatalog;
|
||||
@ -77,7 +77,7 @@ PUBLISHED:
|
||||
INLINE const string &get_name() const;
|
||||
|
||||
virtual DCField *as_field();
|
||||
virtual DCSwitch *as_switch();
|
||||
virtual DCSwitchParameter *as_switch_parameter();
|
||||
virtual DCClassParameter *as_class_parameter();
|
||||
|
||||
public:
|
||||
@ -159,6 +159,9 @@ public:
|
||||
|
||||
const DCPackerCatalog *get_catalog() const;
|
||||
|
||||
private:
|
||||
void make_catalog();
|
||||
|
||||
protected:
|
||||
string _name;
|
||||
bool _has_fixed_byte_size;
|
||||
@ -170,8 +173,6 @@ protected:
|
||||
DCPackType _pack_type;
|
||||
|
||||
private:
|
||||
void make_catalog();
|
||||
|
||||
DCPackerCatalog *_catalog;
|
||||
};
|
||||
|
||||
|
@ -122,7 +122,7 @@ set_typedef(const DCTypedef *dtypedef) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::output
|
||||
// Access: Public
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCParameter::
|
||||
@ -131,21 +131,34 @@ output(ostream &out, bool brief) const {
|
||||
if (!brief) {
|
||||
name = get_name();
|
||||
}
|
||||
output_instance(out, "", name, "");
|
||||
output_instance(out, brief, "", name, "");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::write
|
||||
// Access: Public
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCParameter::
|
||||
write(ostream &out, bool, int indent_level) const {
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
// we must always output the name when the parameter occurs by
|
||||
// itself within a class, so we ignore brief and pass false up to
|
||||
// output().
|
||||
// itself within a class, so we pass get_name() even if brief is
|
||||
// true.
|
||||
write_instance(out, brief, indent_level, "", get_name(), "");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::write_instance
|
||||
// Access: Public, Virtual
|
||||
// Description: Formats the parameter in the C++-like dc syntax as a
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCParameter::
|
||||
write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
indent(out, indent_level);
|
||||
output(out, false);
|
||||
output_instance(out, brief, prename, name, postname);
|
||||
out << ";\n";
|
||||
}
|
||||
|
||||
@ -156,14 +169,31 @@ write(ostream &out, bool, int indent_level) const {
|
||||
// the typedef name instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCParameter::
|
||||
output_typedef_name(ostream &out, const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
output_typedef_name(ostream &out, bool, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
out << get_typedef()->get_name();
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::write_typedef_name
|
||||
// Access: Public
|
||||
// Description: Formats the instance like write_instance, but uses
|
||||
// the typedef name instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCParameter::
|
||||
write_typedef_name(ostream &out, bool, int indent_level, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
indent(out, indent_level)
|
||||
<< get_typedef()->get_name();
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
out << ";\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCParameter::generate_hash
|
||||
// Access: Public, Virtual
|
||||
|
@ -60,12 +60,18 @@ PUBLISHED:
|
||||
public:
|
||||
void set_typedef(const DCTypedef *dtypedef);
|
||||
|
||||
void output(ostream &out, bool brief) const;
|
||||
virtual void output(ostream &out, bool brief) const;
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
virtual void output_instance(ostream &out, const string &prename,
|
||||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const=0;
|
||||
void output_typedef_name(ostream &out, const string &prename,
|
||||
virtual void write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
void output_typedef_name(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
void write_typedef_name(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
private:
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "dcAtomicField.h"
|
||||
#include "dcMolecularField.h"
|
||||
#include "dcClassParameter.h"
|
||||
#include "dcSwitchParameter.h"
|
||||
#include "dcArrayParameter.h"
|
||||
#include "dcSimpleParameter.h"
|
||||
#include "dcTypedef.h"
|
||||
@ -116,12 +117,13 @@ dc_cleanup_parser() {
|
||||
|
||||
%type <u.flag> kw_struct_or_kw_dclass
|
||||
%type <u.dclass> dclass_name
|
||||
%type <u.dclass> dclass
|
||||
%type <u.dswitch> switch
|
||||
%type <u.atomic> atomic_name
|
||||
%type <u.field> dclass_field
|
||||
%type <u.field> switch_field
|
||||
%type <u.field> atomic_field
|
||||
%type <u.field> molecular_field
|
||||
%type <u.field> switch
|
||||
%type <u.subatomic> type_token
|
||||
%type <u.parameter> type_name
|
||||
%type <u.parameter> type_definition
|
||||
@ -150,24 +152,37 @@ dc:
|
||||
empty
|
||||
| dc ';'
|
||||
| dc dclass
|
||||
{
|
||||
if (!dc_file->add_class($2)) {
|
||||
DCClass *old_class = dc_file->get_class_by_name($2->get_name());
|
||||
if (old_class != (DCClass *)NULL && old_class->is_bogus_class()) {
|
||||
yyerror("Base class defined after its first reference: " + $2->get_name());
|
||||
} else {
|
||||
yyerror("Duplicate class name: " + $2->get_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
| dc switch
|
||||
{
|
||||
if (!dc_file->add_switch($2)) {
|
||||
yyerror("Duplicate class name: " + $2->get_name());
|
||||
}
|
||||
}
|
||||
| dc import
|
||||
| dc typedef_decl
|
||||
;
|
||||
|
||||
dclass:
|
||||
kw_struct_or_kw_dclass IDENTIFIER
|
||||
kw_struct_or_kw_dclass optional_name
|
||||
{
|
||||
$$ = current_class;
|
||||
current_class = new DCClass($2, $1, false);
|
||||
if (!dc_file->add_class(current_class)) {
|
||||
DCClass *old_class = dc_file->get_class_by_name(current_class->get_name());
|
||||
if (old_class->is_bogus_class()) {
|
||||
yyerror("Base class defined after its first reference: " + current_class->get_name());
|
||||
} else {
|
||||
yyerror("Duplicate class name: " + current_class->get_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
dclass_derivation '{' dclass_fields '}'
|
||||
{
|
||||
$$ = current_class;
|
||||
current_class = $<u.dclass>3;
|
||||
}
|
||||
;
|
||||
|
||||
kw_struct_or_kw_dclass:
|
||||
@ -291,7 +306,6 @@ dclass_fields:
|
||||
dclass_field:
|
||||
atomic_field
|
||||
| molecular_field
|
||||
| switch
|
||||
| unnamed_parameter ';'
|
||||
{
|
||||
$$ = $1;
|
||||
@ -332,6 +346,7 @@ atomic_element:
|
||||
| parameter '='
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
current_packer->begin_pack($1);
|
||||
}
|
||||
parameter_value
|
||||
@ -435,14 +450,29 @@ type_name:
|
||||
// Create an implicit typedef for this.
|
||||
dtypedef = new DCTypedef(new DCClassParameter(dclass), true);
|
||||
} else {
|
||||
// It's an undefined typedef. Create a bogus forward reference.
|
||||
dtypedef = new DCTypedef($1);
|
||||
// Maybe it's a switch name.
|
||||
DCSwitch *dswitch = dc_file->get_switch_by_name($1);
|
||||
if (dswitch != (DCSwitch *)NULL) {
|
||||
// This also gets an implicit typedef.
|
||||
dtypedef = new DCTypedef(new DCSwitchParameter(dswitch), true);
|
||||
} else {
|
||||
// It's an undefined typedef. Create a bogus forward reference.
|
||||
dtypedef = new DCTypedef($1);
|
||||
}
|
||||
}
|
||||
|
||||
dc_file->add_typedef(dtypedef);
|
||||
}
|
||||
|
||||
$$ = dtypedef->make_new_parameter();
|
||||
}
|
||||
| dclass
|
||||
{
|
||||
$$ = new DCClassParameter($1);
|
||||
}
|
||||
| switch
|
||||
{
|
||||
$$ = new DCSwitchParameter($1);
|
||||
}
|
||||
;
|
||||
|
||||
@ -917,6 +947,7 @@ switch_case:
|
||||
KW_CASE
|
||||
{
|
||||
current_packer = &default_packer;
|
||||
current_packer->clear_data();
|
||||
current_packer->begin_pack(current_switch->get_key_parameter());
|
||||
}
|
||||
parameter_value ':'
|
||||
@ -930,8 +961,7 @@ switch_case:
|
||||
;
|
||||
|
||||
switch_field:
|
||||
switch
|
||||
| unnamed_parameter ';'
|
||||
unnamed_parameter ';'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
class DCFile;
|
||||
class DCClass;
|
||||
class DCSwitch;
|
||||
class DCField;
|
||||
class DCAtomicField;
|
||||
class DCParameter;
|
||||
@ -52,6 +53,7 @@ public:
|
||||
double real;
|
||||
bool flag;
|
||||
DCClass *dclass;
|
||||
DCSwitch *dswitch;
|
||||
DCField *field;
|
||||
DCAtomicField *atomic;
|
||||
DCSubatomicType subatomic;
|
||||
|
@ -1942,10 +1942,10 @@ unpack_skip(const char *data, size_t length, size_t &p) const {
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSimpleParameter::
|
||||
output_instance(ostream &out, const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
if (get_typedef() != (DCTypedef *)NULL) {
|
||||
output_typedef_name(out, prename, name, postname);
|
||||
output_typedef_name(out, brief, prename, name, postname);
|
||||
|
||||
} else {
|
||||
out << _type;
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
bool &pack_error, bool &range_error) const;
|
||||
virtual bool unpack_skip(const char *data, size_t length, size_t &p) const;
|
||||
|
||||
virtual void output_instance(ostream &out, const string &prename,
|
||||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
|
@ -29,21 +29,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitch::
|
||||
DCSwitch(const string &name, DCParameter *key_parameter) :
|
||||
DCField(name),
|
||||
_name(name),
|
||||
_key_parameter(key_parameter)
|
||||
{
|
||||
_has_fixed_byte_size = _key_parameter->has_fixed_byte_size();
|
||||
_fixed_byte_size = _key_parameter->get_fixed_byte_size();
|
||||
_has_fixed_structure = false;
|
||||
|
||||
// The DCSwitch presents just one nested field initially, which is
|
||||
// the key parameter. When we pack or unpack that, the DCPacker
|
||||
// calls apply_switch(), which returns a new record that presents
|
||||
// the remaining nested fields.
|
||||
_has_nested_fields = true;
|
||||
_num_nested_fields = 1;
|
||||
|
||||
_pack_type = PT_switch;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -72,6 +60,16 @@ as_switch() {
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::get_name
|
||||
// Access: Published
|
||||
// Description: Returns the name of this switch.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const string &DCSwitch::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::get_key_parameter
|
||||
// Access: Published
|
||||
@ -115,6 +113,17 @@ get_case_by_value(const string &case_value) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::get_case
|
||||
// Access: Published
|
||||
// Description: Returns the DCPackerInterface that packs the nth case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCPackerInterface *DCSwitch::
|
||||
get_case(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_cases.size(), NULL);
|
||||
return _cases[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::get_value
|
||||
// Access: Published
|
||||
@ -170,23 +179,6 @@ get_field_by_name(int case_index, const string &name) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::get_nested_field
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the DCPackerInterface object that represents
|
||||
// the nth nested field. This may return NULL if there
|
||||
// is no such field (but it shouldn't do this if n is in
|
||||
// the range 0 <= n < get_num_nested_fields()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCPackerInterface *DCSwitch::
|
||||
get_nested_field(int) const {
|
||||
// The DCSwitch presents just one nested field initially, which is
|
||||
// the key parameter. When we pack or unpack that, the DCPacker
|
||||
// calls apply_switch(), which returns a new record that presents
|
||||
// the remaining nested fields.
|
||||
return _key_parameter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::add_case
|
||||
// Access: Public
|
||||
@ -225,26 +217,6 @@ add_field(DCField *field) {
|
||||
if (!_cases.back()->add_field(field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// See if we now have a fixed byte size for the overall switch.
|
||||
// This will be true only if all of the individual cases have the
|
||||
// same fixed byte size.
|
||||
_fixed_byte_size = _cases.back()->get_fixed_byte_size();
|
||||
|
||||
Cases::const_iterator ci;
|
||||
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
|
||||
const SwitchCase *dcase = (*ci);
|
||||
if (!dcase->has_fixed_byte_size() ||
|
||||
dcase->get_fixed_byte_size() != _fixed_byte_size) {
|
||||
|
||||
// Nope, we have a variable byte size.
|
||||
_has_fixed_byte_size = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sonofagun, we do have a fixed byte size.
|
||||
_has_fixed_byte_size = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -276,6 +248,58 @@ apply_switch(const char *value_data, size_t length) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitch::
|
||||
write(ostream &out, bool brief, int indent_level) const {
|
||||
write_instance(out, brief, indent_level, "", "", "");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCClass::output_instance
|
||||
// Access: Public
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitch::
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
out << "switch";
|
||||
if (!_name.empty()) {
|
||||
out << " " << _name;
|
||||
}
|
||||
out << " (";
|
||||
_key_parameter->output(out, brief);
|
||||
out << ") {";
|
||||
|
||||
Cases::const_iterator ci;
|
||||
for (ci = _cases.begin(); ci != _cases.end(); ++ci) {
|
||||
const SwitchCase *dcase = (*ci);
|
||||
out << "case " << _key_parameter->format_data(dcase->_value) << ": ";
|
||||
|
||||
Fields::const_iterator fi;
|
||||
if (!dcase->_fields.empty()) {
|
||||
fi = dcase->_fields.begin();
|
||||
++fi;
|
||||
while (fi != dcase->_fields.end()) {
|
||||
(*fi)->output(out, brief);
|
||||
out << "; ";
|
||||
++fi;
|
||||
}
|
||||
}
|
||||
}
|
||||
out << "}";
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitch::write_instance
|
||||
// Access: Public, Virtual
|
||||
// Description: Generates a parseable description of the object to
|
||||
// the indicated output stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitch::
|
||||
write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
indent(out, indent_level)
|
||||
<< "switch";
|
||||
if (!_name.empty()) {
|
||||
@ -302,7 +326,11 @@ write(ostream &out, bool brief, int indent_level) const {
|
||||
}
|
||||
}
|
||||
indent(out, indent_level)
|
||||
<< "};\n";
|
||||
<< "}";
|
||||
if (!prename.empty() || !name.empty() || !postname.empty()) {
|
||||
out << " " << prename << name << postname;
|
||||
}
|
||||
out << ";\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -313,7 +341,7 @@ write(ostream &out, bool brief, int indent_level) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitch::
|
||||
generate_hash(HashGenerator &hashgen) const {
|
||||
DCField::generate_hash(hashgen);
|
||||
hashgen.add_string(_name);
|
||||
|
||||
_key_parameter->generate_hash(hashgen);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define DCSWITCH_H
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "dcField.h"
|
||||
#include "dcDeclaration.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DCSwitch
|
||||
@ -29,7 +29,7 @@
|
||||
// alternative unpacking schemes based on the first
|
||||
// field read.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_DIRECT DCSwitch : public DCField {
|
||||
class EXPCL_DIRECT DCSwitch : public DCDeclaration {
|
||||
public:
|
||||
DCSwitch(const string &name, DCParameter *key_parameter);
|
||||
virtual ~DCSwitch();
|
||||
@ -37,10 +37,12 @@ public:
|
||||
PUBLISHED:
|
||||
virtual DCSwitch *as_switch();
|
||||
|
||||
const string &get_name() const;
|
||||
DCParameter *get_key_parameter() const;
|
||||
|
||||
int get_num_cases() const;
|
||||
int get_case_by_value(const string &case_value) const;
|
||||
DCPackerInterface *get_case(int n) const;
|
||||
|
||||
string get_value(int case_index) const;
|
||||
int get_num_fields(int case_index) const;
|
||||
@ -48,17 +50,21 @@ PUBLISHED:
|
||||
DCField *get_field_by_name(int case_index, const string &name) const;
|
||||
|
||||
public:
|
||||
virtual DCPackerInterface *get_nested_field(int n) const;
|
||||
|
||||
int add_case(const string &value);
|
||||
bool add_field(DCField *field);
|
||||
|
||||
const DCPackerInterface *apply_switch(const char *value_data, size_t length) const;
|
||||
|
||||
virtual void write(ostream &out, bool brief, int indent_level) const;
|
||||
void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
void write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
private:
|
||||
string _name;
|
||||
DCParameter *_key_parameter;
|
||||
|
||||
typedef pvector<DCField *> Fields;
|
||||
|
198
direct/src/dcparser/dcSwitchParameter.cxx
Executable file
198
direct/src/dcparser/dcSwitchParameter.cxx
Executable file
@ -0,0 +1,198 @@
|
||||
// Filename: dcSwitchParameter.cxx
|
||||
// Created by: drose (18Jun04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dcSwitchParameter.h"
|
||||
#include "dcSwitch.h"
|
||||
#include "hashGenerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitchParameter::
|
||||
DCSwitchParameter(DCSwitch *dswitch) :
|
||||
_dswitch(dswitch)
|
||||
{
|
||||
set_name(dswitch->get_name());
|
||||
|
||||
_has_fixed_byte_size = false;
|
||||
_has_fixed_structure = false;
|
||||
|
||||
// The DCSwitch presents just one nested field initially, which is
|
||||
// the key parameter. When we pack or unpack that, the DCPacker
|
||||
// calls apply_switch(), which returns a new record that presents
|
||||
// the remaining nested fields.
|
||||
_has_nested_fields = true;
|
||||
_num_nested_fields = 1;
|
||||
|
||||
_pack_type = PT_switch;
|
||||
|
||||
DCParameter *key_parameter = dswitch->get_key_parameter();
|
||||
if (key_parameter->has_fixed_byte_size()) {
|
||||
// See if we have a fixed byte size for the overall switch. This
|
||||
// will be true only if all of the individual cases have the same
|
||||
// fixed byte size.
|
||||
int num_cases = _dswitch->get_num_cases();
|
||||
_has_fixed_byte_size = true;
|
||||
_fixed_byte_size = 0;
|
||||
|
||||
if (num_cases > 0) {
|
||||
_fixed_byte_size = _dswitch->get_case(0)->get_fixed_byte_size();
|
||||
|
||||
for (int i = 0; i < num_cases && _has_fixed_byte_size; i++) {
|
||||
const DCPackerInterface *dcase = _dswitch->get_case(i);
|
||||
if (!dcase->has_fixed_byte_size() ||
|
||||
dcase->get_fixed_byte_size() != _fixed_byte_size) {
|
||||
|
||||
// Nope, we have a variable byte size.
|
||||
_has_fixed_byte_size = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_fixed_byte_size += key_parameter->get_fixed_byte_size();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitchParameter::
|
||||
DCSwitchParameter(const DCSwitchParameter ©) :
|
||||
DCParameter(copy),
|
||||
_dswitch(copy._dswitch)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::as_switch_parameter
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitchParameter *DCSwitchParameter::
|
||||
as_switch_parameter() {
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::make_copy
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCParameter *DCSwitchParameter::
|
||||
make_copy() const {
|
||||
return new DCSwitchParameter(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::is_valid
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns false if the type is an invalid type
|
||||
// (e.g. declared from an undefined typedef), true if
|
||||
// it is valid.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DCSwitchParameter::
|
||||
is_valid() const {
|
||||
return true; //_dswitch->is_valid();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::get_switch
|
||||
// Access: Published
|
||||
// Description: Returns the switch object this parameter represents.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCSwitch *DCSwitchParameter::
|
||||
get_switch() const {
|
||||
return _dswitch;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::get_nested_field
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the DCPackerInterface object that represents
|
||||
// the nth nested field. This may return NULL if there
|
||||
// is no such field (but it shouldn't do this if n is in
|
||||
// the range 0 <= n < get_num_nested_fields()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DCPackerInterface *DCSwitchParameter::
|
||||
get_nested_field(int) const {
|
||||
return _dswitch->get_key_parameter();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::apply_switch
|
||||
// Access: Public
|
||||
// Description: Returns the DCPackerInterface that presents the
|
||||
// alternative fields for the case indicated by the
|
||||
// given packed value string, or NULL if the value
|
||||
// string does not match one of the expected cases.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const DCPackerInterface *DCSwitchParameter::
|
||||
apply_switch(const char *value_data, size_t length) const {
|
||||
return _dswitch->apply_switch(value_data, length);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::output_instance
|
||||
// Access: Public, Virtual
|
||||
// Description: Formats the parameter in the C++-like dc syntax as a
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitchParameter::
|
||||
output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const {
|
||||
if (get_typedef() != (DCTypedef *)NULL) {
|
||||
output_typedef_name(out, brief, prename, name, postname);
|
||||
|
||||
} else {
|
||||
_dswitch->output_instance(out, brief, prename, name, postname);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::write_instance
|
||||
// Access: Public, Virtual
|
||||
// Description: Formats the parameter in the C++-like dc syntax as a
|
||||
// typename and identifier.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitchParameter::
|
||||
write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const {
|
||||
if (get_typedef() != (DCTypedef *)NULL) {
|
||||
write_typedef_name(out, brief, indent_level, prename, name, postname);
|
||||
|
||||
} else {
|
||||
_dswitch->write_instance(out, brief, indent_level, prename, name, postname);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DCSwitchParameter::generate_hash
|
||||
// Access: Public, Virtual
|
||||
// Description: Accumulates the properties of this type into the
|
||||
// hash.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DCSwitchParameter::
|
||||
generate_hash(HashGenerator &hashgen) const {
|
||||
DCParameter::generate_hash(hashgen);
|
||||
_dswitch->generate_hash(hashgen);
|
||||
}
|
61
direct/src/dcparser/dcSwitchParameter.h
Executable file
61
direct/src/dcparser/dcSwitchParameter.h
Executable file
@ -0,0 +1,61 @@
|
||||
// Filename: dcClassParameter.h
|
||||
// Created by: drose (29Jun04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DCSWITCHPARAMETER_H
|
||||
#define DCSWITCHPARAMETER_H
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "dcParameter.h"
|
||||
|
||||
class DCSwitch;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DCSwitchParameter
|
||||
// Description : This represents a switch object used as a
|
||||
// parameter itself, which packs the appropriate fields
|
||||
// of the switch into the message.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
|
||||
public:
|
||||
DCSwitchParameter(DCSwitch *dswitch);
|
||||
DCSwitchParameter(const DCSwitchParameter ©);
|
||||
|
||||
PUBLISHED:
|
||||
virtual DCSwitchParameter *as_switch_parameter();
|
||||
virtual DCParameter *make_copy() const;
|
||||
virtual bool is_valid() const;
|
||||
|
||||
DCSwitch *get_switch() const;
|
||||
|
||||
public:
|
||||
virtual DCPackerInterface *get_nested_field(int n) const;
|
||||
|
||||
const DCPackerInterface *apply_switch(const char *value_data, size_t length) const;
|
||||
|
||||
virtual void output_instance(ostream &out, bool brief, const string &prename,
|
||||
const string &name, const string &postname) const;
|
||||
virtual void write_instance(ostream &out, bool brief, int indent_level,
|
||||
const string &prename, const string &name,
|
||||
const string &postname) const;
|
||||
virtual void generate_hash(HashGenerator &hashgen) const;
|
||||
|
||||
private:
|
||||
DCSwitch *_dswitch;
|
||||
};
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@
|
||||
#include "dcClassParameter.cxx"
|
||||
#include "dcArrayParameter.cxx"
|
||||
#include "dcSimpleParameter.cxx"
|
||||
#include "dcSwitchParameter.cxx"
|
||||
#include "dcField.cxx"
|
||||
#include "dcFile.cxx"
|
||||
#include "dcMolecularField.cxx"
|
||||
|
Loading…
x
Reference in New Issue
Block a user