From 7349221f42c344291320aca9bd65b7abd44c4d25 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 22 Jun 2007 22:36:32 +0000 Subject: [PATCH] add get_python_pointer() --- panda/src/express/memoryUsagePointers.cxx | 71 +++++++++++++++++++++++ panda/src/express/memoryUsagePointers.h | 11 ++++ 2 files changed, 82 insertions(+) diff --git a/panda/src/express/memoryUsagePointers.cxx b/panda/src/express/memoryUsagePointers.cxx index a7e4eed5f5..72a39ce6f7 100644 --- a/panda/src/express/memoryUsagePointers.cxx +++ b/panda/src/express/memoryUsagePointers.cxx @@ -24,6 +24,18 @@ #include "referenceCount.h" #include "typedReferenceCount.h" +#ifdef HAVE_PYTHON +// Pick up a few declarations so we can create Python wrappers in +// get_python_pointer(), below. + +#include "py_panda.h" + +extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedObject; +extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedReferenceCount; +extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_ReferenceCount; + +#endif // HAVE_PYTHON + //////////////////////////////////////////////////////////////////// // Function: MemoryUsagePointers::Constructor // Access: Published @@ -141,6 +153,65 @@ get_age(int n) const { return _entries[n]._age; } +#ifdef HAVE_PYTHON +//////////////////////////////////////////////////////////////////// +// Function: MemoryUsagePointers::get_python_pointer +// Access: Published +// Description: Returns the nth object, represented as a Python +// object of the appropriate type. Reference counting +// will be properly set on the Python object. +// +// get_typed_pointer() is almost as good as this, but +// (a) it does not set the reference count, and (b) it +// does not work for objects that do not inherit from +// TypedObject. This will work for any object whose +// type is known, which has a Python representation. +//////////////////////////////////////////////////////////////////// +PyObject *MemoryUsagePointers:: +get_python_pointer(int n) const { + nassertr(n >= 0 && n < get_num_pointers(), NULL); + TypedObject *typed_ptr = _entries[n]._typed_ptr; + ReferenceCount *ref_ptr = _entries[n]._ref_ptr; + + bool memory_rules = false; + if (ref_ptr != (ReferenceCount *)NULL) { + memory_rules = true; + ref_ptr->ref(); + } + + if (typed_ptr != (TypedObject *)NULL) { + return DTool_CreatePyInstanceTyped(typed_ptr, Dtool_TypedObject, + memory_rules, false, + typed_ptr->get_type_index()); + } + + if (ref_ptr == (ReferenceCount *)NULL) { + return Py_BuildValue(""); + } + + TypeHandle type = _entries[n]._type; + if (type != TypeHandle::none()) { + // Use TypedReferenceCount if we have it. + if (type.is_derived_from(TypedReferenceCount::get_class_type())) { + TypedReferenceCount *typed_ref_ptr = (TypedReferenceCount *)ref_ptr; + + return DTool_CreatePyInstanceTyped(typed_ref_ptr, Dtool_TypedReferenceCount, + memory_rules, false, + type.get_index()); + } + + // Otherwise, trust that there is a downcast path to the actual type. + return DTool_CreatePyInstanceTyped(ref_ptr, Dtool_ReferenceCount, + memory_rules, false, + type.get_index()); + } + + // If worse comes to worst, just return a ReferenceCount wrapper. + return DTool_CreatePyInstance(ref_ptr, Dtool_ReferenceCount, + memory_rules, false); +} +#endif + //////////////////////////////////////////////////////////////////// // Function: MemoryUsagePointers::clear // Access: Published diff --git a/panda/src/express/memoryUsagePointers.h b/panda/src/express/memoryUsagePointers.h index 277416f85e..1ab696c1a5 100644 --- a/panda/src/express/memoryUsagePointers.h +++ b/panda/src/express/memoryUsagePointers.h @@ -28,6 +28,13 @@ #include "referenceCount.h" #include "pvector.h" +#ifdef HAVE_PYTHON + +#undef _POSIX_C_SOURCE +#include + +#endif // HAVE_PYTHON + //////////////////////////////////////////////////////////////////// // Class : MemoryUsagePointers // Description : This is a list of pointers returned by a MemoryUsage @@ -61,6 +68,10 @@ PUBLISHED: string get_type_name(int n) const; double get_age(int n) const; +#ifdef HAVE_PYTHON + PyObject *get_python_pointer(int n) const; +#endif + void clear(); void output(ostream &out) const;