Browse Source

support PyObject * as a pass-through

David Rose 21 years ago
parent
commit
f91058c967

+ 11 - 3
direct/src/ffi/FFIInterrogateDatabase.py

@@ -362,15 +362,23 @@ class FFIInterrogateDatabase:
     def constructClassTypeDescriptor(self, typeIndex):
         if self.isDefinedType(typeIndex):
             return self.typeIndexMap[typeIndex]
+        typeName = FFIRename.classNameFromCppName(getTypeName(typeIndex))
+        if typeName == "PyObject":
+            # A special case: the PyObject type is really a native
+            # Python object, not to be molested--it's not really an
+            # FFI class object.
+            descriptor = FFITypes.PyObjectTypeDescriptor()
+            self.typeIndexMap[typeIndex] = descriptor
+            return descriptor
+            
         descriptor = FFITypes.ClassTypeDescriptor()
         self.typeIndexMap[typeIndex] = descriptor
         #descriptor.environment = self.environment
-        descriptor.foreignTypeName = FFIRename.classNameFromCppName(getTypeName(typeIndex))
+        descriptor.foreignTypeName = typeName
 
-        if (descriptor.foreignTypeName == "TypedObject"):
+        if (typeName == "TypedObject"):
             print "Found typed object descriptor"
             FFITypes.TypedObjectDescriptor = descriptor
-            
         
         descriptor.isNested = interrogate_type_is_nested(typeIndex)
         if descriptor.isNested:

+ 2 - 1
direct/src/ffi/FFISpecs.py

@@ -47,7 +47,8 @@ class FunctionSpecification:
                     indent(file, nesting, 'assert((isinstance(' +
                            methodArgSpec.name + ', types.FloatType) or isinstance(' +
                            methodArgSpec.name + ', types.IntType)))\n')
-                else:
+
+                elif typeDesc.__class__ != FFITypes.PyObjectTypeDescriptor:
                     # Get the real return type (not derived)
                     if ((not typeDesc.isNested) and
                         # Do not put our own module in the import list

+ 13 - 0
direct/src/ffi/FFITypes.py

@@ -108,6 +108,19 @@ class PrimitiveTypeDescriptor(BaseTypeDescriptor):
         """
         indent(file, nesting, 'return returnValue\n')
 
+class PyObjectTypeDescriptor(BaseTypeDescriptor):
+    """
+    This is a special type descriptor for a PyObject * parameter,
+    which means a natural Python object of any type, to be passed
+    through without molestation.
+    """
+    def __init__(self):
+        BaseTypeDescriptor.__init__(self)
+                
+    def generateReturnValueWrapper(self, classTypeDesc, file, userManagesMemory,
+                                   needsDowncast, nesting):
+        indent(file, nesting, 'return returnValue\n')
+
 
 
 class EnumTypeDescriptor(PrimitiveTypeDescriptor):

+ 6 - 0
dtool/src/interrogate/interfaceMakerPython.cxx

@@ -72,6 +72,12 @@ test_assert(ostream &out, int indent_level) const {
       << "return (PyObject *)NULL;\n";
     indent(out, indent_level)
       << "}\n";
+    indent(out, indent_level)
+      << "if (PyErr_Occurred()) {\n";
+    indent(out, indent_level + 2)
+      << "return (PyObject *)NULL;\n";
+    indent(out, indent_level)
+      << "}\n";
     out << "#endif\n";
   }
 }

+ 10 - 0
dtool/src/interrogate/interfaceMakerPythonSimple.cxx

@@ -298,6 +298,12 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
       format_specifiers += "s";
       parameter_list += ", &" + param_name;
 
+    } else if (TypeManager::is_pointer_to_PyObject(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      pexpr_string = param_name;
+
     } else if (TypeManager::is_pointer(type)) {
       out << "int " << param_name;
       format_specifiers += "i";
@@ -409,6 +415,10 @@ pack_return_value(ostream &out, int indent_level,
     indent(out, indent_level)
       << "return PyString_FromString(" << return_expr << ");\n";
 
+  } else if (TypeManager::is_pointer_to_PyObject(type)) {
+    indent(out, indent_level)
+      << "return " << return_expr << ";\n";
+    
   } else if (TypeManager::is_pointer(type)) {
     indent(out, indent_level)
       << "return PyInt_FromLong((int)" << return_expr << ");\n";

+ 38 - 0
dtool/src/interrogate/typeManager.cxx

@@ -714,6 +714,44 @@ is_const_ref_to_pointer_to_base(CPPType *type) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_pointer_to_PyObject
+//       Access: Public, Static
+//  Description: Returns true if the indicated type is PyObject *.
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_pointer_to_PyObject(CPPType *type) {
+  switch (type->get_subtype()) {
+  case CPPDeclaration::ST_const:
+    return is_pointer_to_PyObject(type->as_const_type()->_wrapped_around);
+
+  case CPPDeclaration::ST_pointer:
+    return is_PyObject(type->as_pointer_type()->_pointing_at);
+
+  default:
+    return false;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_PyObject
+//       Access: Public, Static
+//  Description: Returns true if the indicated type is PyObject.
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_PyObject(CPPType *type) {
+  switch (type->get_subtype()) {
+  case CPPDeclaration::ST_const:
+    return is_PyObject(type->as_const_type()->_wrapped_around);
+
+  case CPPDeclaration::ST_extension:
+    return (type->get_local_name(&parser) == "PyObject");
+
+  default:
+    return false;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TypeManager::involves_unpublished
 //       Access: Public, Static

+ 2 - 0
dtool/src/interrogate/typeManager.h

@@ -77,6 +77,8 @@ public:
   static bool is_pointer_to_base(CPPType *type);
   static bool is_const_pointer_to_base(CPPType *type);
   static bool is_const_ref_to_pointer_to_base(CPPType *type);
+  static bool is_pointer_to_PyObject(CPPType *type);
+  static bool is_PyObject(CPPType *type);
   static bool involves_unpublished(CPPType *type);
   static bool involves_protected(CPPType *type);
 

+ 29 - 0
dtool/src/parser-inc/Python.h

@@ -0,0 +1,29 @@
+// Filename: Python.h
+// Created by:  drose (12May00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+// This file, and all the other files in this directory, aren't
+// intended to be compiled--they're just parsed by CPPParser (and
+// interrogate) in lieu of the actual system headers, to generate the
+// interrogate database.
+
+#ifndef PYTHON_H
+#define PYTHON_H
+
+class PyObject;
+
+#endif  // PYTHON_H

+ 2 - 1
dtool/src/parser-inc/Sources.pp

@@ -2,4 +2,5 @@
     algorithm deque ft2build.h iostream list map memory \
     pair queue set stack stdcompare.h stdtypedefs.h \
     string vector windows.h zlib.h md5.h files.h hex.h \
-    nurbs.hh stddef.h krb5.h
+    nurbs.hh stddef.h krb5.h Python.h
+