mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
unpack to python object
This commit is contained in:
parent
faf063cbf8
commit
6845758d2b
@ -223,6 +223,19 @@ is_bogus_class() const {
|
|||||||
return _bogus_class;
|
return _bogus_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCClass::has_class_def
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the DCClass object has an associated
|
||||||
|
// Python class definition, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DCClass::
|
||||||
|
has_class_def() const {
|
||||||
|
return (_class_def != NULL);
|
||||||
|
}
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DCClass::set_class_def
|
// Function: DCClass::set_class_def
|
||||||
|
@ -55,6 +55,7 @@ PUBLISHED:
|
|||||||
bool is_bogus_class() const;
|
bool is_bogus_class() const;
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
|
bool has_class_def() const;
|
||||||
void set_class_def(PyObject *class_def);
|
void set_class_def(PyObject *class_def);
|
||||||
PyObject *get_class_def() const;
|
PyObject *get_class_def() const;
|
||||||
|
|
||||||
|
@ -60,6 +60,16 @@ get_number() const {
|
|||||||
return _number;
|
return _number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCField::as_field
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DCField *DCField::
|
||||||
|
as_field() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DCField::as_atomic_field
|
// Function: DCField::as_atomic_field
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
int get_number() const;
|
int get_number() const;
|
||||||
|
|
||||||
|
virtual DCField *as_field();
|
||||||
virtual DCAtomicField *as_atomic_field();
|
virtual DCAtomicField *as_atomic_field();
|
||||||
virtual DCMolecularField *as_molecular_field();
|
virtual DCMolecularField *as_molecular_field();
|
||||||
virtual DCParameter *as_parameter();
|
virtual DCParameter *as_parameter();
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "dcSwitch.h"
|
#include "dcSwitch.h"
|
||||||
#include "dcParserDefs.h"
|
#include "dcParserDefs.h"
|
||||||
#include "dcLexerDefs.h"
|
#include "dcLexerDefs.h"
|
||||||
|
#include "dcClassParameter.h"
|
||||||
|
#include "dcClass.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DCPacker::Constructor
|
// Function: DCPacker::Constructor
|
||||||
@ -217,6 +219,9 @@ begin_repack(const char *data, size_t length,
|
|||||||
_root = root;
|
_root = root;
|
||||||
_catalog = _root->get_catalog();
|
_catalog = _root->get_catalog();
|
||||||
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
||||||
|
if (_live_catalog == NULL) {
|
||||||
|
_pack_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
// We don't begin at the first field in repack mode. Instead, you
|
// We don't begin at the first field in repack mode. Instead, you
|
||||||
// must explicitly call seek().
|
// must explicitly call seek().
|
||||||
@ -268,6 +273,10 @@ seek(const string &field_name) {
|
|||||||
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
||||||
}
|
}
|
||||||
nassertr(_catalog != (DCPackerCatalog *)NULL, false);
|
nassertr(_catalog != (DCPackerCatalog *)NULL, false);
|
||||||
|
if (_live_catalog == NULL) {
|
||||||
|
_pack_error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int entry_index = _live_catalog->find_entry_by_name(field_name);
|
int entry_index = _live_catalog->find_entry_by_name(field_name);
|
||||||
if (entry_index < 0) {
|
if (entry_index < 0) {
|
||||||
@ -305,6 +314,10 @@ seek(const string &field_name) {
|
|||||||
_pack_error = true;
|
_pack_error = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (_live_catalog == NULL) {
|
||||||
|
_pack_error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int entry_index = _live_catalog->find_entry_by_name(field_name);
|
int entry_index = _live_catalog->find_entry_by_name(field_name);
|
||||||
if (entry_index < 0) {
|
if (entry_index < 0) {
|
||||||
@ -338,6 +351,11 @@ seek(const string &field_name) {
|
|||||||
_catalog->release_live_catalog(_live_catalog);
|
_catalog->release_live_catalog(_live_catalog);
|
||||||
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
_live_catalog = _catalog->get_live_catalog(_unpack_data, _unpack_length);
|
||||||
|
|
||||||
|
if (_live_catalog == NULL) {
|
||||||
|
_pack_error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
begin = _live_catalog->get_begin(entry_index);
|
begin = _live_catalog->get_begin(entry_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,6 +714,22 @@ unpack_object() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PT_class:
|
||||||
|
{
|
||||||
|
const DCClassParameter *class_param = ((DCPackerInterface *)get_current_field())->as_class_parameter();
|
||||||
|
if (class_param != (DCClassParameter *)NULL) {
|
||||||
|
DCClass *dclass = class_param->get_class();
|
||||||
|
if (dclass->has_class_def()) {
|
||||||
|
// If we know what kind of class object this is and it has a
|
||||||
|
// valid constructor, create the class object instead of
|
||||||
|
// just a tuple.
|
||||||
|
object = unpack_class_object(dclass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we don't know what kind of class object it is, or it doesn't
|
||||||
|
// have a constructor, fall through and make a tuple.
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// First, build up a list from the nested objects.
|
// First, build up a list from the nested objects.
|
||||||
@ -994,3 +1028,92 @@ set_unpack_data(const char *unpack_data, size_t unpack_length,
|
|||||||
_unpack_length = unpack_length;
|
_unpack_length = unpack_length;
|
||||||
_owns_unpack_data = owns_unpack_data;
|
_owns_unpack_data = owns_unpack_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCPacker::unpack_class_object
|
||||||
|
// Access: Private
|
||||||
|
// Description: Given that the current element is a ClassParameter
|
||||||
|
// for a Python class for which we have a valid
|
||||||
|
// constructor, unpack it and fill in its values.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PyObject *DCPacker::
|
||||||
|
unpack_class_object(DCClass *dclass) {
|
||||||
|
PyObject *class_def = dclass->get_class_def();
|
||||||
|
nassertr(class_def != (PyObject *)NULL, NULL);
|
||||||
|
|
||||||
|
PyObject *object = PyObject_CallObject(class_def, NULL);
|
||||||
|
if (object == (PyObject *)NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
push();
|
||||||
|
while (more_nested_fields()) {
|
||||||
|
const DCField *field = ((DCPackerInterface *)get_current_field())->as_field();
|
||||||
|
nassertr(field != (DCField *)NULL, object);
|
||||||
|
|
||||||
|
set_class_element(object, field);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCPacker::set_class_element
|
||||||
|
// Access: Private
|
||||||
|
// Description: Unpacks the current element and stuffs it on the
|
||||||
|
// Python class object in whatever way is appopriate.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void DCPacker::
|
||||||
|
set_class_element(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 unpack its nested objects directly into
|
||||||
|
// the class.
|
||||||
|
push();
|
||||||
|
while (more_nested_fields()) {
|
||||||
|
const DCField *field = ((DCPackerInterface *)get_current_field())->as_field();
|
||||||
|
nassertv(field != (DCField *)NULL);
|
||||||
|
set_class_element(object, field);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Otherwise, we just skip over the field.
|
||||||
|
unpack_skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If the field does have a name, we will want to store it on the
|
||||||
|
// class, either by calling a method (for a PT_field pack_type) or
|
||||||
|
// by setting a value (for any other kind of pack_type).
|
||||||
|
|
||||||
|
PyObject *element = unpack_object();
|
||||||
|
|
||||||
|
if (pack_type == PT_field) {
|
||||||
|
PyObject *func = PyObject_GetAttrString(object, (char *)field_name.c_str());
|
||||||
|
if (func != (PyObject *)NULL) {
|
||||||
|
PyObject *result = PyObject_CallObject(func, element);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
}
|
||||||
|
Py_DECREF(func);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PyObject_SetAttrString(object, (char *)field_name.c_str(), element);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "dcPackerCatalog.h"
|
#include "dcPackerCatalog.h"
|
||||||
#include "dcPython.h"
|
#include "dcPython.h"
|
||||||
|
|
||||||
|
class DCClass;
|
||||||
class DCSwitch;
|
class DCSwitch;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -134,6 +135,11 @@ private:
|
|||||||
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
void set_unpack_data(const char *unpack_data, size_t unpack_length,
|
||||||
bool owns_unpack_data);
|
bool owns_unpack_data);
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
PyObject *unpack_class_object(DCClass *dclass);
|
||||||
|
void set_class_element(PyObject *object, const DCField *field);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Mode {
|
enum Mode {
|
||||||
M_idle,
|
M_idle,
|
||||||
|
@ -138,7 +138,10 @@ get_live_catalog(const char *data, size_t length) const {
|
|||||||
r_fill_live_catalog(live_catalog, packer, last_switch);
|
r_fill_live_catalog(live_catalog, packer, last_switch);
|
||||||
bool okflag = packer.end_unpack();
|
bool okflag = packer.end_unpack();
|
||||||
|
|
||||||
nassertr(okflag, live_catalog);
|
if (!okflag) {
|
||||||
|
delete live_catalog;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (_root->has_fixed_structure()) {
|
if (_root->has_fixed_structure()) {
|
||||||
// If our root field has a fixed structure, then the live catalog
|
// If our root field has a fixed structure, then the live catalog
|
||||||
|
@ -69,6 +69,16 @@ DCPackerInterface::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCPackerInterface::as_field
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DCField *DCPackerInterface::
|
||||||
|
as_field() {
|
||||||
|
return (DCField *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DCPackerInterface::as_switch
|
// Function: DCPackerInterface::as_switch
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -79,6 +89,16 @@ as_switch() {
|
|||||||
return (DCSwitch *)NULL;
|
return (DCSwitch *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DCPackerInterface::as_class_parameter
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
DCClassParameter *DCPackerInterface::
|
||||||
|
as_class_parameter() {
|
||||||
|
return (DCClassParameter *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DCPackerInterface::calc_num_nested_fields
|
// Function: DCPackerInterface::calc_num_nested_fields
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
#include "dcbase.h"
|
#include "dcbase.h"
|
||||||
#include "dcSubatomicType.h"
|
#include "dcSubatomicType.h"
|
||||||
|
|
||||||
|
class DCField;
|
||||||
class DCSwitch;
|
class DCSwitch;
|
||||||
|
class DCClassParameter;
|
||||||
class DCPackData;
|
class DCPackData;
|
||||||
class DCPackerCatalog;
|
class DCPackerCatalog;
|
||||||
|
|
||||||
@ -74,7 +76,9 @@ public:
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE const string &get_name() const;
|
INLINE const string &get_name() const;
|
||||||
|
|
||||||
|
virtual DCField *as_field();
|
||||||
virtual DCSwitch *as_switch();
|
virtual DCSwitch *as_switch();
|
||||||
|
virtual DCClassParameter *as_class_parameter();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INLINE void set_name(const string &name);
|
INLINE void set_name(const string &name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user