Browse Source

Wrap TypeHandle and ButtonHandle as ints in C wrappers

rdb 10 years ago
parent
commit
57e5c8fb25

+ 15 - 0
dtool/src/dtoolbase/typeHandle.I

@@ -263,3 +263,18 @@ INLINE TypeHandle::
 operator bool () const {
   return (_index != 0);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: TypeHandle::from_index
+//       Access: Public, Static
+//  Description: Creates a TypeHandle from a type index without
+//               error checking, for use by internal functions.
+//
+//               See TypeRegistry::find_type_by_id().
+////////////////////////////////////////////////////////////////////
+INLINE TypeHandle TypeHandle::
+from_index(int index) {
+  TypeHandle handle;
+  handle._index = index;
+  return handle;
+}

+ 4 - 1
dtool/src/dtoolbase/typeHandle.h

@@ -82,7 +82,7 @@ class TypedObject;
 //               ancestry of a particular type may be queried, and the
 //               type name may be retrieved for run-time display.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOL TypeHandle {
+class EXPCL_DTOOL TypeHandle FINAL {
 PUBLISHED:
   enum MemoryClass {
     MC_singleton,
@@ -140,6 +140,9 @@ PUBLISHED:
   INLINE static TypeHandle none();
   INLINE operator bool () const;
 
+public:
+  INLINE static TypeHandle from_index(int index);
+
 private:
   int _index;
   static TypeHandle _none;

+ 34 - 14
dtool/src/interrogate/functionRemap.cxx

@@ -17,6 +17,7 @@
 #include "interrogate.h"
 #include "parameterRemap.h"
 #include "parameterRemapThis.h"
+#include "parameterRemapHandleToInt.h"
 #include "parameterRemapUnchanged.h"
 #include "interfaceMaker.h"
 #include "interrogateBuilder.h"
@@ -146,8 +147,13 @@ call_function(ostream &out, int indent_level, bool convert_result,
   } else if (_type == T_typecast_method) {
     // A typecast method can be invoked implicitly.
     string cast_expr =
-      "(" + _return_type->get_orig_type()->get_local_name(&parser) +
-      ")(*" + container + ")";
+      "(" + _return_type->get_orig_type()->get_local_name(&parser) + ")";
+
+    if (TypeManager::is_handle(_cpptype)) {
+      cast_expr += "(" + container + ")";
+    } else {
+      cast_expr += "(*" + container + ")";
+    }
 
     if (!convert_result) {
       return_expr = cast_expr;
@@ -177,10 +183,7 @@ call_function(ostream &out, int indent_level, bool convert_result,
 
   } else if (_type == T_constructor) {
     // A special case for constructors.
-    string defconstruct = builder.in_defconstruct(_cpptype->get_local_name(&parser));
-    if (pexprs.empty() && !defconstruct.empty()) {
-      return_expr = defconstruct;
-    } else if (_extension) {
+    if (_extension) {
       // Extension constructors are a special case.  We assume there is a
       // default constructor for the class, and the actual construction is
       // done by an __init__ method.
@@ -192,8 +195,22 @@ call_function(ostream &out, int indent_level, bool convert_result,
         << get_call_str("result", pexprs) << ";\n";
 
       return_expr = "result";
+
     } else {
-      return_expr = "new " + get_call_str(container, pexprs);
+      string defconstruct = builder.in_defconstruct(_cpptype->get_local_name(&parser));
+      string call_expr;
+
+      if (pexprs.empty() && !defconstruct.empty()) {
+        call_expr = defconstruct;
+      } else {
+        call_expr = get_call_str(container, pexprs);
+      }
+
+      if (!_return_type->return_value_needs_management()) {
+        return_expr = _return_type->get_return_expr(call_expr);
+      } else {
+        return_expr = "new " + call_expr;
+      }
     }
     if (_void_return) {
       nout << "Error, constructor for " << *_cpptype << " returning void.\n";
@@ -448,12 +465,9 @@ get_call_str(const string &container, const vector_string &pexprs) const {
       } else if (_has_this && !container.empty()) {
         // If we have a "this" parameter, the calling convention is also
         // a bit different.
-        if (container == "local_this") {
-          // This isn't important, it just looks a bit prettier.
-          call << container << "->" << _cppfunc->get_local_name();
-        } else {
-          call << "(" << container << ")->" << _cppfunc->get_local_name();
-        }
+        call << "(";
+        _parameters[0]._remap->pass_parameter(call, container);
+        call << ")." << _cppfunc->get_local_name();
 
       } else {
         call << _cppfunc->get_local_name(&parser);
@@ -569,7 +583,13 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
       Parameter param;
       param._name = "this";
       param._has_name = true;
-      param._remap = new ParameterRemapThis(_cpptype, _const_method);
+      if (_const_method) {
+        CPPType *const_type = CPPType::new_type(new CPPConstType(_cpptype));
+        param._remap = interface_maker->remap_parameter(_cpptype, const_type);
+      } else {
+        param._remap = interface_maker->remap_parameter(_cpptype, _cpptype);
+      }
+      //  param._remap = new ParameterRemapThis(_cpptype, _const_method);
       _parameters.push_back(param);
       _first_true_parameter = 1;
     }

+ 27 - 0
dtool/src/interrogate/interfaceMakerC.cxx

@@ -16,6 +16,7 @@
 #include "interrogateBuilder.h"
 #include "interrogate.h"
 #include "functionRemap.h"
+#include "parameterRemapHandleToInt.h"
 #include "parameterRemapUnchanged.h"
 #include "typeManager.h"
 
@@ -89,6 +90,32 @@ write_functions(ostream &out) {
   InterfaceMaker::write_functions(out);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerC::remap_parameter
+//       Access: Public, Virtual
+//  Description: Allocates a new ParameterRemap object suitable to the
+//               indicated parameter type.  If struct_type is
+//               non-NULL, it is the type of the enclosing class for
+//               the function (method) in question.
+//
+//               The return value is a newly-allocated ParameterRemap
+//               object, if the parameter type is acceptable, or NULL
+//               if the parameter type cannot be handled.
+////////////////////////////////////////////////////////////////////
+ParameterRemap *InterfaceMakerC::
+remap_parameter(CPPType *struct_type, CPPType *param_type) {
+  // Wrap TypeHandle and ButtonHandle, which are practically just
+  // ints, as an integer instead of a pointer.  It makes things easier
+  // on the scripting language, especially if there has to be a
+  // dynamic downcasting system on the scripting language side.
+   if (TypeManager::is_handle(param_type)) {
+    return new ParameterRemapHandleToInt(param_type);
+
+  } else {
+    return InterfaceMaker::remap_parameter(struct_type, param_type);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: InterfaceMakerC::synthesize_this_parameter
 //       Access: Public, Virtual

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

@@ -36,6 +36,8 @@ public:
   virtual void write_prototypes(ostream &out,ostream *out_h);
   virtual void write_functions(ostream &out);
 
+  virtual ParameterRemap *remap_parameter(CPPType *struct_type, CPPType *param_type);
+
   virtual bool synthesize_this_parameter();
 
 protected:

+ 1 - 0
dtool/src/interrogate/interrogate_composite2.cxx

@@ -14,5 +14,6 @@
 #include "parameterRemapReferenceToPointer.cxx"
 #include "parameterRemapThis.cxx"
 #include "parameterRemapToString.cxx"
+#include "parameterRemapHandleToInt.cxx"
 #include "parameterRemapUnchanged.cxx"
 

+ 65 - 0
dtool/src/interrogate/parameterRemapHandleToInt.cxx

@@ -0,0 +1,65 @@
+// Filename: parameterRemapHandleToInt.cxx
+// Created by:  rdb (08Sep15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "parameterRemapHandleToInt.h"
+#include "interrogate.h"
+#include "interrogateBuilder.h"
+#include "typeManager.h"
+
+#include "cppType.h"
+#include "cppDeclaration.h"
+#include "cppConstType.h"
+#include "cppPointerType.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: ParameterRemapHandleToInt::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+ParameterRemapHandleToInt::
+ParameterRemapHandleToInt(CPPType *orig_type) :
+  ParameterRemap(orig_type)
+{
+  _new_type = TypeManager::get_int_type();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ParameterRemapHandleToInt::pass_parameter
+//       Access: Public, Virtual
+//  Description: Outputs an expression that converts the indicated
+//               variable from the new type to the original type, for
+//               passing into the actual C++ function.
+////////////////////////////////////////////////////////////////////
+void ParameterRemapHandleToInt::
+pass_parameter(ostream &out, const string &variable_name) {
+  CPPType *unwrapped = TypeManager::unwrap_const(_orig_type);
+
+  if (unwrapped->get_local_name(&parser) == "TypeHandle") {
+    out << "TypeHandle::from_index(" << variable_name << ")";
+  } else {
+    out << unwrapped->get_local_name(&parser) << "(" << variable_name << ")";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ParameterRemapHandleToInt::get_return_expr
+//       Access: Public, Virtual
+//  Description: Returns an expression that evalutes to the
+//               appropriate value type for returning from the
+//               function, given an expression of the original type.
+////////////////////////////////////////////////////////////////////
+string ParameterRemapHandleToInt::
+get_return_expr(const string &expression) {
+  return "(" + expression + ").get_index()";
+}

+ 40 - 0
dtool/src/interrogate/parameterRemapHandleToInt.h

@@ -0,0 +1,40 @@
+// Filename: parameterRemapHandleToInt.h
+// Created by:  rdb (08Sep15)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PARAMETERREMAPHANDLETOINT_H
+#define PARAMETERREMAPHANDLETOINT_H
+
+#include "dtoolbase.h"
+
+#include "parameterRemap.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ParameterRemapHandleToInt
+// Description : A ParameterRemap class that handles remapping a
+//               Handle parameter to an integer.  This makes it
+//               easier to set up a dynamic typing system on the
+//               scripting language side.
+//
+//               It also applies to ButtonHandle or any other class
+//               with the same semantics, because why not.
+////////////////////////////////////////////////////////////////////
+class ParameterRemapHandleToInt : public ParameterRemap {
+public:
+  ParameterRemapHandleToInt(CPPType *orig_type);
+
+  virtual void pass_parameter(ostream &out, const string &variable_name);
+  virtual string get_return_expr(const string &expression);
+};
+
+#endif

+ 2 - 2
dtool/src/interrogate/parameterRemapThis.cxx

@@ -45,8 +45,8 @@ ParameterRemapThis(CPPType *type, bool is_const) :
 //               passing into the actual C++ function.
 ////////////////////////////////////////////////////////////////////
 void ParameterRemapThis::
-pass_parameter(ostream &out, const string &) {
-  out << "**invalid**";
+pass_parameter(ostream &out, const string &variable_name) {
+  out << "(*" << variable_name << ")";
 }
 
 ////////////////////////////////////////////////////////////////////

+ 26 - 1
dtool/src/interrogate/typeManager.cxx

@@ -1820,6 +1820,31 @@ is_Py_buffer(CPPType *type) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_handle
+//       Access: Public, Static
+//  Description: Returns true if the indicated type is TypeHandle
+//               or a class with identical semantics like ButtonHandle.
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_handle(CPPType *type) {
+  switch (type->get_subtype()) {
+  case CPPDeclaration::ST_const:
+    return is_handle(type->as_const_type()->_wrapped_around);
+
+  case CPPDeclaration::ST_extension:
+  case CPPDeclaration::ST_struct:
+    return (type->get_local_name(&parser) == "TypeHandle" ||
+            type->get_local_name(&parser) == "ButtonHandle");
+
+  case CPPDeclaration::ST_typedef:
+    return is_handle(type->as_typedef_type()->_type);
+
+  default:
+    return false;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TypeManager::is_ostream
 //       Access: Public, Static
@@ -2631,7 +2656,7 @@ is_trivial(CPPType *source_type) {
     return is_trivial(source_type->as_typedef_type()->_type);
 
   default:
-    if (source_type->is_trivial()) {
+    if (source_type->is_trivial() || is_handle(source_type)) {
       return true;
     } else {
       // This is a bit of a hack.  is_trivial() returns false for types that

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

@@ -112,6 +112,7 @@ public:
   static bool is_PyUnicodeObject(CPPType *type);
   static bool is_pointer_to_Py_buffer(CPPType *type);
   static bool is_Py_buffer(CPPType *type);
+  static bool is_handle(CPPType *type);
   static bool involves_unpublished(CPPType *type);
   static bool involves_protected(CPPType *type);
 

+ 1 - 1
panda/src/express/config_express.N

@@ -1,4 +1,4 @@
-defconstruct TypeHandle new TypeHandle(TypeHandle::none())
+defconstruct TypeHandle TypeHandle(TypeHandle::none())
 
 forcetype PandaSystem
 forcetype DSearchPath

+ 37 - 37
panda/src/linmath/luse.N

@@ -1,46 +1,46 @@
 
-defconstruct LPoint2f new LPoint2f(0.0f)
-defconstruct LPoint3f new LPoint3f(0.0f)
-defconstruct LPoint4f new LPoint4f(0.0f)
-defconstruct LPoint2d new LPoint2d(0.0)
-defconstruct LPoint3d new LPoint3d(0.0)
-defconstruct LPoint4d new LPoint4d(0.0)
-defconstruct LPoint2i new LPoint2i(0)
-defconstruct LPoint3i new LPoint3i(0)
-defconstruct LPoint4i new LPoint4i(0)
+defconstruct LPoint2f LPoint2f(0.0f)
+defconstruct LPoint3f LPoint3f(0.0f)
+defconstruct LPoint4f LPoint4f(0.0f)
+defconstruct LPoint2d LPoint2d(0.0)
+defconstruct LPoint3d LPoint3d(0.0)
+defconstruct LPoint4d LPoint4d(0.0)
+defconstruct LPoint2i LPoint2i(0)
+defconstruct LPoint3i LPoint3i(0)
+defconstruct LPoint4i LPoint4i(0)
 
-defconstruct LVecBase2f new LVecBase2f(0.0f)
-defconstruct LVecBase3f new LVecBase3f(0.0f)
-defconstruct LVecBase4f new LVecBase4f(0.0f)
-defconstruct LVecBase2d new LVecBase2d(0.0)
-defconstruct LVecBase3d new LVecBase3d(0.0)
-defconstruct LVecBase4d new LVecBase4d(0.0)
-defconstruct LVecBase2i new LVecBase2i(0)
-defconstruct LVecBase3i new LVecBase3i(0)
-defconstruct LVecBase4i new LVecBase4i(0)
+defconstruct LVecBase2f LVecBase2f(0.0f)
+defconstruct LVecBase3f LVecBase3f(0.0f)
+defconstruct LVecBase4f LVecBase4f(0.0f)
+defconstruct LVecBase2d LVecBase2d(0.0)
+defconstruct LVecBase3d LVecBase3d(0.0)
+defconstruct LVecBase4d LVecBase4d(0.0)
+defconstruct LVecBase2i LVecBase2i(0)
+defconstruct LVecBase3i LVecBase3i(0)
+defconstruct LVecBase4i LVecBase4i(0)
 
-defconstruct LVector2f new LVector2f(0.0f)
-defconstruct LVector3f new LVector3f(0.0f)
-defconstruct LVector4f new LVector4f(0.0f)
-defconstruct LVector2d new LVector2d(0.0)
-defconstruct LVector3d new LVector3d(0.0)
-defconstruct LVector4d new LVector4d(0.0)
-defconstruct LVector2i new LVector2i(0)
-defconstruct LVector3i new LVector3i(0)
-defconstruct LVector4i new LVector4i(0)
+defconstruct LVector2f LVector2f(0.0f)
+defconstruct LVector3f LVector3f(0.0f)
+defconstruct LVector4f LVector4f(0.0f)
+defconstruct LVector2d LVector2d(0.0)
+defconstruct LVector3d LVector3d(0.0)
+defconstruct LVector4d LVector4d(0.0)
+defconstruct LVector2i LVector2i(0)
+defconstruct LVector3i LVector3i(0)
+defconstruct LVector4i LVector4i(0)
 
-defconstruct LMatrix3f new LMatrix3f(LMatrix3f::ident_mat())
-defconstruct LMatrix4f new LMatrix4f(LMatrix4f::ident_mat())
-defconstruct LMatrix3d new LMatrix3d(LMatrix3d::ident_mat())
-defconstruct LMatrix4d new LMatrix4d(LMatrix4d::ident_mat())
+defconstruct LMatrix3f LMatrix3f(LMatrix3f::ident_mat())
+defconstruct LMatrix4f LMatrix4f(LMatrix4f::ident_mat())
+defconstruct LMatrix3d LMatrix3d(LMatrix3d::ident_mat())
+defconstruct LMatrix4d LMatrix4d(LMatrix4d::ident_mat())
 
-defconstruct LQuaternionf new LQuaternionf(LQuaternionf::ident_quat())
-defconstruct LRotationf new LRotationf(LQuaternionf::ident_quat())
-defconstruct LOrientationf new LOrientationf(LQuaternionf::ident_quat())
+defconstruct LQuaternionf LQuaternionf(LQuaternionf::ident_quat())
+defconstruct LRotationf LRotationf(LQuaternionf::ident_quat())
+defconstruct LOrientationf LOrientationf(LQuaternionf::ident_quat())
 
-defconstruct LQuaterniond new LQuaterniond(LQuaterniond::ident_quat())
-defconstruct LRotationd new LRotationd(LQuaterniond::ident_quat())
-defconstruct LOrientationd new LOrientationd(LQuaterniond::ident_quat())
+defconstruct LQuaterniond LQuaterniond(LQuaterniond::ident_quat())
+defconstruct LRotationd LRotationd(LQuaterniond::ident_quat())
+defconstruct LOrientationd LOrientationd(LQuaterniond::ident_quat())
 
 # We don't want to accidentally include any of the _src files in the
 # generated output, since these files aren't intended to be included by

+ 1 - 1
panda/src/putil/buttonHandle.h

@@ -25,7 +25,7 @@
 //               device, including keyboard buttons and mouse buttons
 //               (but see KeyboardButton and MouseButton).
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA_PUTIL ButtonHandle {
+class EXPCL_PANDA_PUTIL ButtonHandle FINAL {
 PUBLISHED:
   INLINE ButtonHandle();
   INLINE ButtonHandle(int index);

+ 1 - 1
panda/src/putil/config_util.N

@@ -1,4 +1,4 @@
-defconstruct ButtonHandle new ButtonHandle(0)
+defconstruct ButtonHandle ButtonHandle(0)
 
 ignoremember _factory
 ignoremember get_factory