struct and switch are now inline

This commit is contained in:
David Rose 2004-06-30 00:50:25 +00:00
parent 09e9ed12df
commit 932359216f
34 changed files with 703 additions and 187 deletions

View File

@ -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 \

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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

View File

@ -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:

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View 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 &copy) :
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);
}

View 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 &copy);
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

View File

@ -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"