Wrap TypeHandle and ButtonHandle as ints in C wrappers

This commit is contained in:
rdb 2015-09-10 15:29:31 +02:00
parent 20f90f35b9
commit 57e5c8fb25
15 changed files with 257 additions and 58 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

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

View File

@ -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()";
}

View File

@ -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

View File

@ -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 << ")";
}
////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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);

View File

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

View File

@ -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

View File

@ -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);

View File

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