mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
various refinements
This commit is contained in:
parent
842dd7bf26
commit
836cc8224d
@ -482,6 +482,14 @@ pack_required_field(DCPacker &packer, PyObject *distobj,
|
|||||||
string field_name = field->get_name();
|
string field_name = field->get_name();
|
||||||
|
|
||||||
if (!PyObject_HasAttrString(distobj, (char *)field_name.c_str())) {
|
if (!PyObject_HasAttrString(distobj, (char *)field_name.c_str())) {
|
||||||
|
// If the attribute is not defined, but the field has a default
|
||||||
|
// value specified, quietly pack the default value.
|
||||||
|
if (field->has_default_value()) {
|
||||||
|
packer.pack_default_value();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no default value specified, it's an error.
|
||||||
ostringstream strm;
|
ostringstream strm;
|
||||||
strm << "Data element " << field_name
|
strm << "Data element " << field_name
|
||||||
<< ", required by dc file for dclass " << get_name()
|
<< ", required by dc file for dclass " << get_name()
|
||||||
@ -503,7 +511,7 @@ pack_required_field(DCPacker &packer, PyObject *distobj,
|
|||||||
const DCAtomicField *atom = field->as_atomic_field();
|
const DCAtomicField *atom = field->as_atomic_field();
|
||||||
if (atom == (DCAtomicField *)NULL) {
|
if (atom == (DCAtomicField *)NULL) {
|
||||||
ostringstream strm;
|
ostringstream strm;
|
||||||
strm << "Cannot pack non-atomic field " << field->get_name()
|
strm << "Cannot pack molecular field " << field->get_name()
|
||||||
<< " for generate";
|
<< " for generate";
|
||||||
nassert_raise(strm.str());
|
nassert_raise(strm.str());
|
||||||
return false;
|
return false;
|
||||||
@ -547,6 +555,14 @@ pack_required_field(DCPacker &packer, PyObject *distobj,
|
|||||||
// Now we have to look up the getter on the distributed object
|
// Now we have to look up the getter on the distributed object
|
||||||
// and call it.
|
// and call it.
|
||||||
if (!PyObject_HasAttrString(distobj, (char *)getter_name.c_str())) {
|
if (!PyObject_HasAttrString(distobj, (char *)getter_name.c_str())) {
|
||||||
|
// As above, if there's no getter but the field has a default
|
||||||
|
// value specified, quietly pack the default value.
|
||||||
|
if (field->has_default_value()) {
|
||||||
|
packer.pack_default_value();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, with no default value it's an error.
|
||||||
ostringstream strm;
|
ostringstream strm;
|
||||||
strm << "Distributed class " << get_name()
|
strm << "Distributed class " << get_name()
|
||||||
<< " doesn't have getter named " << getter_name
|
<< " doesn't have getter named " << getter_name
|
||||||
@ -671,10 +687,9 @@ ai_format_generate(PyObject *distobj, int do_id,
|
|||||||
int num_fields = get_num_inherited_fields();
|
int num_fields = get_num_inherited_fields();
|
||||||
for (int i = 0; i < num_fields; i++) {
|
for (int i = 0; i < num_fields; i++) {
|
||||||
DCField *field = get_inherited_field(i);
|
DCField *field = get_inherited_field(i);
|
||||||
DCAtomicField *atom = field->as_atomic_field();
|
if (field->is_required() && field->as_molecular_field() == NULL) {
|
||||||
if (atom != (DCAtomicField *)NULL && atom->is_required()) {
|
packer.begin_pack(field);
|
||||||
packer.begin_pack(atom);
|
if (!pack_required_field(packer, distobj, field)) {
|
||||||
if (!pack_required_field(packer, distobj, atom)) {
|
|
||||||
return Datagram();
|
return Datagram();
|
||||||
}
|
}
|
||||||
packer.end_pack();
|
packer.end_pack();
|
||||||
|
@ -464,7 +464,6 @@ push() {
|
|||||||
length = DCPackerInterface::do_unpack_uint32
|
length = DCPackerInterface::do_unpack_uint32
|
||||||
(_unpack_data + _unpack_p);
|
(_unpack_data + _unpack_p);
|
||||||
_unpack_p += 4;
|
_unpack_p += 4;
|
||||||
_pop_marker = _unpack_p + length;
|
|
||||||
} else {
|
} else {
|
||||||
length = DCPackerInterface::do_unpack_uint16
|
length = DCPackerInterface::do_unpack_uint16
|
||||||
(_unpack_data + _unpack_p);
|
(_unpack_data + _unpack_p);
|
||||||
@ -1122,17 +1121,12 @@ clear() {
|
|||||||
void DCPacker::
|
void DCPacker::
|
||||||
pack_class_object(const DCClass *dclass, PyObject *object) {
|
pack_class_object(const DCClass *dclass, PyObject *object) {
|
||||||
PyObject *str = PyObject_Str(object);
|
PyObject *str = PyObject_Str(object);
|
||||||
cerr << "pack_class_object(" << dclass->get_name() << ", "
|
|
||||||
<< PyString_AsString(str) << ")\n";
|
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
push();
|
push();
|
||||||
while (more_nested_fields()) {
|
while (more_nested_fields() && !_pack_error) {
|
||||||
const DCField *field = get_current_field()->as_field();
|
const DCField *field = get_current_field()->as_field();
|
||||||
nassertv(field != (DCField *)NULL);
|
nassertv(field != (DCField *)NULL);
|
||||||
|
get_class_element(dclass, object, field);
|
||||||
if (!dclass->pack_required_field(*this, object, field)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
@ -1257,3 +1251,50 @@ set_class_element(PyObject *class_def, PyObject *&object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCPacker::get_class_element
|
||||||
|
// Access: Private
|
||||||
|
// Description: Gets the current element from the Python object and
|
||||||
|
// packs it.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DCPacker::
|
||||||
|
get_class_element(const DCClass *dclass, PyObject *object,
|
||||||
|
const DCField *field) {
|
||||||
|
string field_name = field->get_name();
|
||||||
|
DCPackType pack_type = get_pack_type();
|
||||||
|
|
||||||
|
if (field_name.empty()) {
|
||||||
|
switch (pack_type) {
|
||||||
|
case PT_class:
|
||||||
|
case PT_switch:
|
||||||
|
// If the field has no name, but it is one of these container
|
||||||
|
// objects, we want to get its nested objects directly from
|
||||||
|
// the class.
|
||||||
|
push();
|
||||||
|
while (more_nested_fields() && !_pack_error) {
|
||||||
|
const DCField *field = get_current_field()->as_field();
|
||||||
|
nassertv(field != (DCField *)NULL);
|
||||||
|
get_class_element(dclass, object, field);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Otherwise, we just pack the default value.
|
||||||
|
pack_default_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If the field does have a name, we will want to get it from the
|
||||||
|
// class and pack it. It just so happens that there's already a
|
||||||
|
// method that does this on DCClass.
|
||||||
|
|
||||||
|
if (!dclass->pack_required_field(*this, object, field)) {
|
||||||
|
_pack_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
@ -183,6 +183,8 @@ private:
|
|||||||
PyObject *unpack_class_object(const DCClass *dclass);
|
PyObject *unpack_class_object(const DCClass *dclass);
|
||||||
void set_class_element(PyObject *class_def, PyObject *&object,
|
void set_class_element(PyObject *class_def, PyObject *&object,
|
||||||
const DCField *field);
|
const DCField *field);
|
||||||
|
void get_class_element(const DCClass *dclass, PyObject *object,
|
||||||
|
const DCField *field);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -328,7 +328,13 @@ update_switch_fields(const DCSwitchParameter *switch_parameter,
|
|||||||
// because we must have come across the DCSwitch when building the
|
// because we must have come across the DCSwitch when building the
|
||||||
// catalog the first time.
|
// catalog the first time.
|
||||||
SwitchPrefixes::const_iterator pi = _switch_prefixes.find(switch_parameter);
|
SwitchPrefixes::const_iterator pi = _switch_prefixes.find(switch_parameter);
|
||||||
nassertr(pi != _switch_prefixes.end(), NULL);
|
if (pi == _switch_prefixes.end()) {
|
||||||
|
// If it's not stored in the record, the switch must be hidden
|
||||||
|
// within some non-seekable object, like an array; in this case,
|
||||||
|
// never mind.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
string name_prefix = (*pi).second;
|
string name_prefix = (*pi).second;
|
||||||
|
|
||||||
// Start by creating a new DCPackerCatalog object that contains all
|
// Start by creating a new DCPackerCatalog object that contains all
|
||||||
|
@ -350,12 +350,36 @@ bool DCPackerInterface::
|
|||||||
unpack_skip(const char *data, size_t length, size_t &p,
|
unpack_skip(const char *data, size_t length, size_t &p,
|
||||||
bool &pack_error) const {
|
bool &pack_error) const {
|
||||||
if (_has_fixed_byte_size) {
|
if (_has_fixed_byte_size) {
|
||||||
|
// If this field has a fixed byte size, it's easy to skip.
|
||||||
p += _fixed_byte_size;
|
p += _fixed_byte_size;
|
||||||
if (p > length) {
|
if (p > length) {
|
||||||
pack_error = true;
|
pack_error = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_has_nested_fields && _num_length_bytes != 0) {
|
||||||
|
// If we have a length prefix, use that for skipping.
|
||||||
|
if (p + _num_length_bytes > length) {
|
||||||
|
pack_error = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (_num_length_bytes == 4) {
|
||||||
|
size_t this_length = do_unpack_uint32(data + p);
|
||||||
|
p += this_length + 4;
|
||||||
|
} else {
|
||||||
|
size_t this_length = do_unpack_uint16(data + p);
|
||||||
|
p += this_length + 2;
|
||||||
|
}
|
||||||
|
if (p > length) {
|
||||||
|
pack_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we don't know how to skip this field (presumably it
|
||||||
|
// can be skipped by skipping over its nested fields individually).
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -116,6 +116,7 @@ dc_cleanup_parser() {
|
|||||||
|
|
||||||
%type <u.atomic> atomic_name
|
%type <u.atomic> atomic_name
|
||||||
%type <u.s_int> server_flags
|
%type <u.s_int> server_flags
|
||||||
|
%type <u.s_int> no_server_flags
|
||||||
%type <u.dclass> dclass_or_struct
|
%type <u.dclass> dclass_or_struct
|
||||||
%type <u.dclass> dclass_name
|
%type <u.dclass> dclass_name
|
||||||
%type <u.dclass> dclass
|
%type <u.dclass> dclass
|
||||||
@ -303,6 +304,8 @@ dclass_fields:
|
|||||||
{
|
{
|
||||||
if (!current_class->add_field($2)) {
|
if (!current_class->add_field($2)) {
|
||||||
yyerror("Duplicate field name: " + $2->get_name());
|
yyerror("Duplicate field name: " + $2->get_name());
|
||||||
|
} else if ($2->get_number() < 0) {
|
||||||
|
yyerror("A non-network field cannot be stored on a dclass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -313,9 +316,10 @@ dclass_field:
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$->set_flags($2);
|
$$->set_flags($2);
|
||||||
}
|
}
|
||||||
| molecular_field
|
| molecular_field no_server_flags
|
||||||
| unnamed_parameter_with_default server_flags ';'
|
| unnamed_parameter_with_default server_flags ';'
|
||||||
{
|
{
|
||||||
|
yyerror("Unnamed parameters are not allowed on a dclass");
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$->set_flags($2);
|
$$->set_flags($2);
|
||||||
}
|
}
|
||||||
@ -388,13 +392,13 @@ struct_fields:
|
|||||||
;
|
;
|
||||||
|
|
||||||
struct_field:
|
struct_field:
|
||||||
atomic_field
|
atomic_field no_server_flags
|
||||||
| molecular_field
|
| molecular_field no_server_flags
|
||||||
| unnamed_parameter_with_default ';'
|
| unnamed_parameter_with_default no_server_flags ';'
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| named_parameter_with_default
|
| named_parameter_with_default no_server_flags
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
@ -987,6 +991,16 @@ server_flags:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
no_server_flags:
|
||||||
|
server_flags
|
||||||
|
{
|
||||||
|
if ($1 != 0) {
|
||||||
|
yyerror("Server flags are not allowed here.");
|
||||||
|
}
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
molecular_field:
|
molecular_field:
|
||||||
IDENTIFIER ':'
|
IDENTIFIER ':'
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user