Use dynamic type lookup for interrogate to eliminate inter-module dependencies
It is now no longer necessary to link to core.pyd Also includes a slight coercion optimization for trivial types
This commit is contained in:
parent
8e58e9e11c
commit
11ed8a4d8d
|
|
@ -1,4 +1,4 @@
|
|||
.TH INTERROGATE_MODULE 1 "26 December 2014" "" Panda3D
|
||||
.TH INTERROGATE_MODULE 1 "02 June 2015" "" Panda3D
|
||||
.SH NAME
|
||||
interrogate_module \- generate module-level code for interrogate
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -64,6 +64,9 @@ may be specified. If all are omitted, the default is \fB\-c\fP.
|
|||
Generate code within each wrapper function to adjust the global
|
||||
variable "in_interpreter" to indicated whether code is running
|
||||
within the Panda C++ environment or within the high-level language.
|
||||
.TP
|
||||
.BI "\-import " module_name
|
||||
Used to import an external dependency module.
|
||||
.SH "SEE ALSO"
|
||||
.BR interrogate (1),
|
||||
.BR test_interrogate (1)
|
||||
|
|
|
|||
|
|
@ -76,6 +76,17 @@ is_tbd() const {
|
|||
return _element_type->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPArrayType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPArrayType::
|
||||
is_trivial() const {
|
||||
return _element_type->is_trivial();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPArrayType::is_equivalent
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
virtual CPPType *resolve_type(CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ is_tbd() const {
|
|||
return _wrapped_around->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPConstType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPConstType::
|
||||
is_trivial() const {
|
||||
return _wrapped_around->is_trivial();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPConstType::is_equivalent
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -102,6 +102,17 @@ is_tbd() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExtensionType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPExtensionType::
|
||||
is_trivial() const {
|
||||
return (_type == T_enum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPExtensionType::substitute_decl
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
|
|
|
|||
|
|
@ -159,6 +159,17 @@ is_tbd() const {
|
|||
return _parameters->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPFunctionType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPFunctionType::
|
||||
is_trivial() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPFunctionType::output
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -29,14 +29,16 @@ class CPPIdentifier;
|
|||
class CPPFunctionType : public CPPType {
|
||||
public:
|
||||
enum Flags {
|
||||
F_const_method = 0x01,
|
||||
F_operator_typecast = 0x02,
|
||||
F_constructor = 0x04,
|
||||
F_destructor = 0x08,
|
||||
F_method_pointer = 0x10,
|
||||
F_unary_op = 0x20,
|
||||
F_operator = 0x40,
|
||||
F_noexcept = 0x80,
|
||||
F_const_method = 0x001,
|
||||
F_operator_typecast = 0x002,
|
||||
F_constructor = 0x004,
|
||||
F_destructor = 0x008,
|
||||
F_method_pointer = 0x010,
|
||||
F_unary_op = 0x020,
|
||||
F_operator = 0x040,
|
||||
F_noexcept = 0x080,
|
||||
F_copy_constructor = 0x200,
|
||||
F_move_constructor = 0x400,
|
||||
};
|
||||
|
||||
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
|
||||
|
|
@ -57,6 +59,7 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
bool complete) const;
|
||||
|
|
|
|||
|
|
@ -347,9 +347,33 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
|
|||
CPPType *void_type = CPPType::new_type
|
||||
(new CPPSimpleType(CPPSimpleType::T_void));
|
||||
|
||||
int flags = func->_flags | CPPFunctionType::F_constructor;
|
||||
|
||||
// Check if it might be a copy or move constructor.
|
||||
CPPParameterList *params = func->_parameters;
|
||||
if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
|
||||
CPPType *param_type = params->_parameters[0]->_type;
|
||||
CPPReferenceType *ref_type = param_type->as_reference_type();
|
||||
|
||||
if (ref_type != NULL) {
|
||||
param_type = ref_type->_pointing_at;
|
||||
|
||||
if (param_type->get_subtype() == CPPDeclaration::ST_const) {
|
||||
param_type = param_type->as_const_type()->_wrapped_around;
|
||||
}
|
||||
|
||||
if (class_name == param_type->get_simple_name()) {
|
||||
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
flags |= CPPFunctionType::F_move_constructor;
|
||||
} else {
|
||||
flags |= CPPFunctionType::F_copy_constructor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_type = CPPType::new_type
|
||||
(new CPPFunctionType(void_type, func->_parameters,
|
||||
func->_flags | CPPFunctionType::F_constructor));
|
||||
(new CPPFunctionType(void_type, func->_parameters, flags));
|
||||
|
||||
} else if (method_name == "~" + class_name) {
|
||||
CPPType *void_type = CPPType::new_type
|
||||
|
|
|
|||
|
|
@ -166,7 +166,16 @@ add_scoped_pointer_modifier(CPPIdentifier *scoping) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CPPInstanceIdentifier::
|
||||
add_array_modifier(CPPExpression *expr) {
|
||||
_modifiers.push_back(Modifier::array_type(expr));
|
||||
// Special case for operator new[] and delete[]. We're not really
|
||||
// adding an array modifier to them, but appending [] to the
|
||||
// identifier. This is to work around a parser ambiguity.
|
||||
if (_ident != NULL && (_ident->get_simple_name() == "operator delete" ||
|
||||
_ident->get_simple_name() == "operator new")) {
|
||||
|
||||
_ident->_names.back().append_name("[]");
|
||||
} else {
|
||||
_modifiers.push_back(Modifier::array_type(expr));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -103,6 +103,17 @@ is_tbd() const {
|
|||
return _pointing_at->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPPointerType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPPointerType::
|
||||
is_trivial() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPPointerType::is_equivalent
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -102,6 +102,17 @@ is_tbd() const {
|
|||
return _pointing_at->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPReferenceType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPReferenceType::
|
||||
is_trivial() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPReferenceType::is_equivalent
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -35,9 +35,6 @@ public:
|
|||
CPPType *_pointing_at;
|
||||
ValueCategory _value_category;
|
||||
|
||||
inline bool is_lvalue() const;
|
||||
inline bool is_rvalue() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
|
|
@ -47,6 +44,7 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,17 @@ is_tbd() const {
|
|||
return (_type == T_unknown);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPSimpleType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPSimpleType::
|
||||
is_trivial() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPSimpleType::is_parameter_expr
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public:
|
|||
int _flags;
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
virtual string get_preferred_name() const;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,97 @@ is_abstract() const {
|
|||
return !funcs.empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPStructType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPStructType::
|
||||
is_trivial() const {
|
||||
// Make sure all base classes are trivial.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && !base->is_trivial()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
assert(_scope != NULL);
|
||||
|
||||
// Make sure all members are trivial.
|
||||
CPPScope::Variables::const_iterator vi;
|
||||
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
|
||||
CPPInstance *instance = (*vi).second;
|
||||
assert(instance != NULL);
|
||||
|
||||
if (instance->_storage_class & CPPInstance::SC_static) {
|
||||
// Static members don't count.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (instance->_initializer != NULL) {
|
||||
// A member with an initializer means the default constructor would
|
||||
// assign a value. This means the type can't be trivial.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finally, check if the data member itself is non-trivial.
|
||||
assert(instance->_type != NULL);
|
||||
if (!instance->_type->is_trivial()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now look for functions that are virtual or con/destructors.
|
||||
bool is_default_constructible = true;
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) {
|
||||
CPPFunctionGroup *fgroup = (*fi).second;
|
||||
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin(); ii != fgroup->_instances.end(); ++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
|
||||
if (inst->_storage_class & CPPInstance::SC_virtual) {
|
||||
// Virtual functions are banned right off the bat.
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(inst->_type != (CPPType *)NULL);
|
||||
CPPFunctionType *ftype = inst->_type->as_function_type();
|
||||
assert(ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
if (ftype->_flags & (CPPFunctionType::F_destructor |
|
||||
CPPFunctionType::F_move_constructor |
|
||||
CPPFunctionType::F_copy_constructor)) {
|
||||
// User-provided destructors and copy/move constructors are not trivial.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ftype->_flags & CPPFunctionType::F_constructor) != 0) {
|
||||
if (ftype->_parameters->_parameters.size() == 0 &&
|
||||
!ftype->_parameters->_includes_ellipsis) {
|
||||
// Same for the default constructor.
|
||||
return false;
|
||||
}
|
||||
// The presence of a non-default constructor makes the class not
|
||||
// default-constructible.
|
||||
is_default_constructible = false;
|
||||
}
|
||||
|
||||
if (fgroup->_name == "operator =") {
|
||||
// Or assignment operators.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, the class must be default-constructible.
|
||||
return is_default_constructible;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPStructType::check_virtual
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
bool check_virtual();
|
||||
virtual bool is_fully_specified() const;
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_trivial() const;
|
||||
|
||||
CPPInstance *get_destructor() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,17 @@ is_tbd() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPType::
|
||||
is_trivial() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPType::is_parameter_expr
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
bool has_typedef_name() const;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,17 @@ is_tbd() const {
|
|||
return _type->is_tbd();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_trivial
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns true if the type is considered a Plain Old
|
||||
// Data (POD) type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CPPTypedefType::
|
||||
is_trivial() const {
|
||||
return _type->is_trivial();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CPPTypedefType::is_fully_specified
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_trivial() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,28 +13,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::Constructor
|
||||
// Access: Published
|
||||
// Description: The default constructor must do nothing, because we
|
||||
// can't guarantee ordering of static initializers. If
|
||||
// the constructor tried to initialize its value, it
|
||||
// might happen after the value had already been set
|
||||
// previously by another static initializer!
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TypeHandle::
|
||||
TypeHandle() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TypeHandle::
|
||||
TypeHandle(const TypeHandle ©) : _index(copy._index) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeHandle::Equality Operator
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -94,8 +94,10 @@ PUBLISHED:
|
|||
// enum value.
|
||||
};
|
||||
|
||||
INLINE TypeHandle();
|
||||
INLINE TypeHandle(const TypeHandle ©);
|
||||
// The default constructor must do nothing, because we can't
|
||||
// guarantee ordering of static initializers. If the constructor
|
||||
// tried to initialize its value, it might happen after the value
|
||||
// had already been set previously by another static initializer!
|
||||
|
||||
EXTENSION(static TypeHandle make(PyTypeObject *classobj));
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
#include "interrogateType.h"
|
||||
#include "pnotify.h"
|
||||
|
||||
extern bool inside_python_native;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: FunctionRemap::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -120,11 +118,7 @@ call_function(ostream &out, int indent_level, bool convert_result,
|
|||
InterfaceMaker::indent(out, indent_level)
|
||||
<< "unref_delete(" << container << ");\n";
|
||||
} else {
|
||||
if (inside_python_native) {
|
||||
InterfaceMaker::indent(out, indent_level) << "Dtool_Py_Delete(self);\n";
|
||||
} else {
|
||||
InterfaceMaker::indent(out, indent_level) << "delete " << container << ";\n";
|
||||
}
|
||||
InterfaceMaker::indent(out, indent_level) << "delete " << container << ";\n";
|
||||
}
|
||||
|
||||
} else if (_type == T_typecast_method) {
|
||||
|
|
@ -866,13 +860,12 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
break;
|
||||
|
||||
case T_constructor:
|
||||
if (!_has_this && _parameters.size() == 1 &&
|
||||
TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
|
||||
TypeManager::unwrap(_return_type->get_orig_type())) {
|
||||
// If this is the only parameter, and it's the same as the
|
||||
// "this" type, this is a copy constructor.
|
||||
if (_ftype->_flags & CPPFunctionType::F_copy_constructor) {
|
||||
// It's a copy constructor.
|
||||
_flags |= F_copy_constructor;
|
||||
|
||||
} else if (_ftype->_flags & CPPFunctionType::F_move_constructor) {
|
||||
|
||||
} else if (!_has_this && _parameters.size() > 0 &&
|
||||
(_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0) {
|
||||
// A non-explicit non-copy constructor might be eligible for coercion.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include <set>
|
||||
#include <map>
|
||||
|
||||
extern bool inside_python_native;
|
||||
extern InterrogateType dummy_type;
|
||||
extern std::string EXPORT_IMPORT_PREFIX;
|
||||
|
||||
|
|
@ -724,7 +723,7 @@ write_python_instance(ostream &out, int indent_level, const string &return_expr,
|
|||
out << boolalpha;
|
||||
|
||||
if (!isExportThisRun(itype._cpptype)) {
|
||||
_external_imports.insert(itype._cpptype);
|
||||
_external_imports.insert(TypeManager::resolve_type(itype._cpptype));
|
||||
}
|
||||
|
||||
string class_name = itype.get_scoped_name();
|
||||
|
|
@ -743,7 +742,7 @@ write_python_instance(ostream &out, int indent_level, const string &return_expr,
|
|||
<< "} else {\n";
|
||||
indent(out, indent_level)
|
||||
<< " return DTool_CreatePyInstanceTyped((void *)" << return_expr
|
||||
<< ", " << CLASS_PREFIX << make_safe_name(class_name) << ", "
|
||||
<< ", *Dtool_Ptr_" << make_safe_name(class_name) << ", "
|
||||
<< owns_memory << ", " << is_const << ", "
|
||||
<< return_expr << "->as_typed_object()->get_type_index());\n";
|
||||
indent(out, indent_level)
|
||||
|
|
@ -753,7 +752,7 @@ write_python_instance(ostream &out, int indent_level, const string &return_expr,
|
|||
indent(out, indent_level)
|
||||
<< "return "
|
||||
<< "DTool_CreatePyInstance((void *)" << return_expr << ", "
|
||||
<< CLASS_PREFIX << make_safe_name(class_name) << ", "
|
||||
<< "*Dtool_Ptr_" << make_safe_name(class_name) << ", "
|
||||
<< owns_memory << ", " << is_const << ");\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -787,8 +786,6 @@ InterfaceMakerPythonNative::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonNative::
|
||||
write_prototypes(ostream &out_code, ostream *out_h) {
|
||||
inside_python_native = true;
|
||||
|
||||
Functions::iterator fi;
|
||||
|
||||
if (out_h != NULL) {
|
||||
|
|
@ -817,7 +814,7 @@ write_prototypes(ostream &out_code, ostream *out_h) {
|
|||
write_prototypes_class(out_code, out_h, object);
|
||||
} else {
|
||||
//write_prototypes_class_external(out_code, object);
|
||||
_external_imports.insert(object->_itype._cpptype);
|
||||
//_external_imports.insert(object->_itype._cpptype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -832,28 +829,62 @@ write_prototypes(ostream &out_code, ostream *out_h) {
|
|||
string class_name = type->get_local_name(&parser);
|
||||
string safe_name = make_safe_name(class_name);
|
||||
|
||||
out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << safe_name << ";\n";
|
||||
out_code << "IMPORT_THIS void Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n";
|
||||
out_code << "// " << class_name << "\n";
|
||||
|
||||
//out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << safe_name << ";\n";
|
||||
out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
|
||||
//out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" << safe_name << "\n";
|
||||
//out_code << "IMPORT_THIS void Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n";
|
||||
|
||||
// This is some really ugly code, because we have to store a pointer with a
|
||||
// function of a signature that differs from class to class. If someone can
|
||||
// think of an elegant way to do this without sacrificing perf, let me know.
|
||||
int has_coerce = has_coerce_constructor(type->as_struct_type());
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
if (has_coerce > 0) {
|
||||
out_code << "IMPORT_THIS bool Dtool_Coerce_" << safe_name << "(PyObject *args, CPT(" << class_name << ") &coerced);\n";
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
out_code
|
||||
<< "inline static bool Dtool_ConstCoerce_" << safe_name << "(PyObject *args, CPT(" << class_name << ") &coerced) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, CPT(" << class_name << ") &))Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce)(args, coerced);\n"
|
||||
<< "}\n";
|
||||
|
||||
if (has_coerce > 1) {
|
||||
out_code << "IMPORT_THIS bool Dtool_Coerce_" << safe_name << "(PyObject *args, PT(" << class_name << ") &coerced);\n";
|
||||
out_code
|
||||
<< "inline static bool Dtool_Coerce_" << safe_name << "(PyObject *args, PT(" << class_name << ") &coerced) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_Coerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, PT(" << class_name << ") &))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced);\n"
|
||||
<< "}\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (has_coerce > 0) {
|
||||
out_code << "IMPORT_THIS bool Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " const *&coerced, bool &manage);\n";
|
||||
|
||||
} else if (TypeManager::is_trivial(type)) {
|
||||
out_code
|
||||
<< "inline static " << class_name << " *Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " &coerced) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, NULL);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_Coerce != NULL, NULL);\n"
|
||||
<< " return ((" << class_name << " *(*)(PyObject *, " << class_name << " &))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced);\n"
|
||||
<< "}\n";
|
||||
|
||||
} else {
|
||||
out_code
|
||||
<< "inline static bool Dtool_ConstCoerce_" << safe_name << "(PyObject *args, " << class_name << " const *&coerced, bool &manage) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, " << class_name << " const *&, bool&))Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce)(args, coerced, manage);\n"
|
||||
<< "}\n";
|
||||
|
||||
if (has_coerce > 1) {
|
||||
out_code << "IMPORT_THIS bool Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " *&coerced, bool &manage);\n";
|
||||
out_code
|
||||
<< "inline static bool Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " *&coerced, bool &manage) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_Coerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, " << class_name << " *&, bool&))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced, manage);\n"
|
||||
<< "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inside_python_native = false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -919,8 +950,6 @@ write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonNative::
|
||||
write_functions(ostream &out) {
|
||||
inside_python_native = true;
|
||||
|
||||
out << "//********************************************************************\n";
|
||||
out << "//*** Functions for .. Global\n" ;
|
||||
out << "//********************************************************************\n";
|
||||
|
|
@ -957,8 +986,6 @@ write_functions(ostream &out) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
inside_python_native = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1015,7 +1042,7 @@ write_class_details(ostream &out, Object *obj) {
|
|||
// Write the constructors.
|
||||
if (obj->_constructors.size() == 0) {
|
||||
// There is no constructor - write one that simply outputs an error.
|
||||
out << "int Dtool_Init_" + ClassName + "(PyObject *, PyObject *, PyObject *) {\n"
|
||||
out << "static int Dtool_Init_" + ClassName + "(PyObject *, PyObject *, PyObject *) {\n"
|
||||
<< "#ifdef NDEBUG\n"
|
||||
<< " Dtool_Raise_TypeError(\"cannot init constant class\");\n"
|
||||
<< "#else\n"
|
||||
|
|
@ -1027,7 +1054,7 @@ write_class_details(ostream &out, Object *obj) {
|
|||
} else {
|
||||
for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) {
|
||||
Function *func = (*fi);
|
||||
std::string fname = "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)";
|
||||
std::string fname = "static int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)";
|
||||
|
||||
string expected_params;
|
||||
write_function_for_name(out, obj, func->_remaps, fname, expected_params, true, AT_keyword_args, RF_int);
|
||||
|
|
@ -1040,7 +1067,7 @@ write_class_details(ostream &out, Object *obj) {
|
|||
int has_coerce = has_coerce_constructor(cpptype->as_struct_type());
|
||||
if (has_coerce > 0) {
|
||||
write_coerce_constructor(out, obj, true);
|
||||
if (has_coerce > 1) {
|
||||
if (has_coerce > 1 && !TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
write_coerce_constructor(out, obj, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1059,28 +1086,28 @@ write_class_details(ostream &out, Object *obj) {
|
|||
for (di = details.begin(); di != details.end(); di++) {
|
||||
//InterrogateType ptype =idb->get_type(di->first);
|
||||
if (di->second._is_legal_py_class && !isExportThisRun(di->second._structType)) {
|
||||
_external_imports.insert(di->second._structType);
|
||||
_external_imports.insert(TypeManager::resolve_type(di->second._structType));
|
||||
}
|
||||
//out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(di->second._to_class_name) << ";\n";
|
||||
}
|
||||
|
||||
// Write support methods to cast from and to pointers of this type.
|
||||
{
|
||||
out << "inline void *Dtool_UpcastInterface_" << ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type) {\n";
|
||||
out << "static void *Dtool_UpcastInterface_" << ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type) {\n";
|
||||
out << " Dtool_PyTypedObject *SelfType = ((Dtool_PyInstDef *)self)->_My_Type;\n";
|
||||
out << " if (SelfType != &Dtool_" << ClassName << ") {\n";
|
||||
out << " if (SelfType != Dtool_Ptr_" << ClassName << ") {\n";
|
||||
out << " printf(\"" << ClassName << " ** Bad Source Type-- Requesting Conversion from %s to %s\\n\", Py_TYPE(self)->tp_name, requested_type->_PyType.tp_name); fflush(NULL);\n";;
|
||||
out << " return NULL;\n";
|
||||
out << " }\n";
|
||||
out << "\n";
|
||||
out << " " << cClassName << " *local_this = (" << cClassName << " *)((Dtool_PyInstDef *)self)->_ptr_to_object;\n";
|
||||
out << " if (requested_type == &Dtool_" << ClassName << ") {\n";
|
||||
out << " if (requested_type == Dtool_Ptr_" << ClassName << ") {\n";
|
||||
out << " return local_this;\n";
|
||||
out << " }\n";
|
||||
|
||||
for (di = details.begin(); di != details.end(); di++) {
|
||||
if (di->second._is_legal_py_class) {
|
||||
out << " if (requested_type == &Dtool_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " if (requested_type == Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " return " << di->second._up_cast_string << " local_this;\n";
|
||||
out << " }\n";
|
||||
}
|
||||
|
|
@ -1089,16 +1116,16 @@ write_class_details(ostream &out, Object *obj) {
|
|||
out << " return NULL;\n";
|
||||
out << "}\n\n";
|
||||
|
||||
out << "inline void *Dtool_DowncastInterface_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n";
|
||||
out << "static void *Dtool_DowncastInterface_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n";
|
||||
out << " if (from_this == NULL || from_type == NULL) {\n";
|
||||
out << " return NULL;\n";
|
||||
out << " }\n";
|
||||
out << " if (from_type == &Dtool_" << ClassName << ") {\n";
|
||||
out << " if (from_type == Dtool_Ptr_" << ClassName << ") {\n";
|
||||
out << " return from_this;\n";
|
||||
out << " }\n";
|
||||
for (di = details.begin(); di != details.end(); di++) {
|
||||
if (di->second._can_downcast && di->second._is_legal_py_class) {
|
||||
out << " if (from_type == &Dtool_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " if (from_type == Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " " << di->second._to_class_name << "* other_this = (" << di->second._to_class_name << "*)from_this;\n" ;
|
||||
out << " return (" << cClassName << "*)other_this;\n";
|
||||
out << " }\n";
|
||||
|
|
@ -1144,21 +1171,25 @@ write_class_declarations(ostream &out, ostream *out_h, Object *obj) {
|
|||
}
|
||||
out << "(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
|
||||
|
||||
out << "EXPORT_THIS void Dtool_PyModuleClassInit_" << class_name << "(PyObject *module);\n";
|
||||
out << "static struct Dtool_PyTypedObject *const Dtool_Ptr_" << class_name << " = &Dtool_" << class_name << ";\n";
|
||||
out << "static void Dtool_PyModuleClassInit_" << class_name << "(PyObject *module);\n";
|
||||
|
||||
int has_coerce = has_coerce_constructor(type->as_struct_type());
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
if (has_coerce > 0) {
|
||||
out << "EXPORT_THIS bool Dtool_Coerce_" << class_name << "(PyObject *args, CPT(" << c_class_name << ") &coerced);\n";
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
assert(!type->is_trivial());
|
||||
out << "bool Dtool_ConstCoerce_" << class_name << "(PyObject *args, CPT(" << c_class_name << ") &coerced);\n";
|
||||
if (has_coerce > 1) {
|
||||
out << "EXPORT_THIS bool Dtool_Coerce_" << class_name << "(PyObject *args, PT(" << c_class_name << ") &coerced);\n";
|
||||
out << "bool Dtool_Coerce_" << class_name << "(PyObject *args, PT(" << c_class_name << ") &coerced);\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (has_coerce > 0) {
|
||||
out << "EXPORT_THIS bool Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " const *&coerced, bool &manage);\n";
|
||||
|
||||
} else if (TypeManager::is_trivial(type)) {
|
||||
out << "" << c_class_name << " *Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " &coerced);\n";
|
||||
|
||||
} else {
|
||||
out << "bool Dtool_ConstCoerce_" << class_name << "(PyObject *args, " << c_class_name << " const *&coerced, bool &manage);\n";
|
||||
if (has_coerce > 1) {
|
||||
out << "EXPORT_THIS bool Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " *&coerced, bool &manage);\n";
|
||||
out << "bool Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " *&coerced, bool &manage);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1202,7 +1233,7 @@ write_sub_module(ostream &out, Object *obj) {
|
|||
<< " " << *(obj->_itype._cpptype) << "\n";
|
||||
|
||||
if (!isExportThisRun(wrapped_itype._cpptype)) {
|
||||
_external_imports.insert(wrapped_itype._cpptype);
|
||||
_external_imports.insert(TypeManager::resolve_type(wrapped_itype._cpptype));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1210,9 +1241,9 @@ write_sub_module(ostream &out, Object *obj) {
|
|||
std::string export_class_name2 = classNameFromCppName(obj->_itype.get_name(), true);
|
||||
|
||||
// out << " Py_INCREF(&Dtool_" << class_name << ".As_PyTypeObject());\n";
|
||||
out << " PyModule_AddObject(module, \"" << export_class_name << "\", (PyObject *)&Dtool_" << class_name << ".As_PyTypeObject());\n";
|
||||
out << " PyModule_AddObject(module, \"" << export_class_name << "\", (PyObject *)&Dtool_" << class_name << ");\n";
|
||||
if (export_class_name != export_class_name2) {
|
||||
out << " PyModule_AddObject(module, \"" << export_class_name2 << "\", (PyObject *)&Dtool_" << class_name << ".As_PyTypeObject());\n";
|
||||
out << " PyModule_AddObject(module, \"" << export_class_name2 << "\", (PyObject *)&Dtool_" << class_name << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1225,19 +1256,62 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||
out << "//*** Module Object Linker ..\n";
|
||||
out << "//********************************************************************\n";
|
||||
|
||||
out << "static void BuildInstants(PyObject *module) {\n";
|
||||
out << " (void) module; // Unused\n";
|
||||
|
||||
Objects::iterator oi;
|
||||
|
||||
out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n";
|
||||
|
||||
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
|
||||
Object *object = (*oi).second;
|
||||
if (object->_itype.is_enum() && !object->_itype.is_nested()) {
|
||||
int enum_count = object->_itype.number_of_enum_values();
|
||||
if (enum_count > 0) {
|
||||
out << "//********************************************************************\n";
|
||||
out << "//*** Module Enums .." << object->_itype.get_scoped_name() << "\n";
|
||||
out << "//********************************************************************\n";
|
||||
if (object->_itype.is_class() ||
|
||||
object->_itype.is_struct()) {
|
||||
if (is_cpp_type_legal(object->_itype._cpptype) &&
|
||||
isExportThisRun(object->_itype._cpptype)) {
|
||||
string class_name = make_safe_name(object->_itype.get_scoped_name());
|
||||
bool is_typed = HasAGetClassTypeFunction(object->_itype._cpptype);
|
||||
|
||||
if (is_typed) {
|
||||
out << " Dtool_" << class_name << "._type = "
|
||||
<< object->_itype._cpptype->get_local_name(&parser)
|
||||
<< "::get_class_type();\n"
|
||||
<< " RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n";
|
||||
|
||||
} else {
|
||||
out << " RegisterNamedClass(\"" << object->_itype.get_scoped_name()
|
||||
<< "\", Dtool_" << class_name << ");\n";
|
||||
|
||||
if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) {
|
||||
nout << object->_itype.get_scoped_name() << " derives from TypedObject, "
|
||||
<< "but does not define a get_class_type() function.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out << "}\n\n";
|
||||
|
||||
out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n";
|
||||
out << " // Resolve externally imported types.\n";
|
||||
|
||||
for (std::set<CPPType *>::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ++ii) {
|
||||
string class_name = (*ii)->get_local_name(&parser);
|
||||
string safe_name = make_safe_name(class_name);
|
||||
|
||||
if (HasAGetClassTypeFunction(*ii)) {
|
||||
out << " Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
|
||||
} else {
|
||||
out << " Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
|
||||
}
|
||||
}
|
||||
out << "}\n\n";
|
||||
|
||||
out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n";
|
||||
out << " (void) module;\n";
|
||||
|
||||
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
|
||||
Object *object = (*oi).second;
|
||||
if (object->_itype.is_enum() && !object->_itype.is_nested() &&
|
||||
isExportThisRun(object->_itype._cpptype)) {
|
||||
int enum_count = object->_itype.number_of_enum_values();
|
||||
for (int xx = 0; xx < enum_count; xx++) {
|
||||
string name1 = classNameFromCppName(object->_itype.get_enum_value_name(xx), false);
|
||||
string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true);
|
||||
|
|
@ -1334,10 +1408,10 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||
// Note: we shouldn't add METH_STATIC here, since both METH_STATIC
|
||||
// and METH_CLASS are illegal for module-level functions.
|
||||
|
||||
out << " { \"" << name1 << "\", (PyCFunction) &"
|
||||
out << " {\"" << name1 << "\", (PyCFunction) &"
|
||||
<< func->_name << ", " << flags << ", (const char *)" << func->_name << "_comment},\n";
|
||||
if (name1 != name2) {
|
||||
out << " { \"" << name2 << "\", (PyCFunction) &"
|
||||
out << " {\"" << name2 << "\", (PyCFunction) &"
|
||||
<< func->_name << ", " << flags << ", (const char *)" << func->_name << "_comment},\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -1351,7 +1425,7 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||
|
||||
out << " {NULL, NULL, 0, NULL}\n" << "};\n\n";
|
||||
|
||||
out << "EXPORT_THIS struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, BuildInstants};\n";
|
||||
out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n";
|
||||
if (out_h != NULL) {
|
||||
*out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n";
|
||||
}
|
||||
|
|
@ -1440,6 +1514,11 @@ write_module_class(ostream &out, Object *obj) {
|
|||
std::string cClassName = obj->_itype.get_true_name();
|
||||
std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
|
||||
|
||||
bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
|
||||
if (!is_runtime_typed && HasAGetClassTypeFunction(obj->_itype._cpptype)) {
|
||||
is_runtime_typed = true;
|
||||
}
|
||||
|
||||
Functions::iterator fi;
|
||||
out << "//********************************************************************\n";
|
||||
out << "//*** Py Init Code For .. " << ClassName << " | " << export_class_name << "\n" ;
|
||||
|
|
@ -1555,10 +1634,10 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
|
||||
// This method has non-slotted remaps, so write it out into the function table.
|
||||
out << " { \"" << name1 << "\", (PyCFunction) &"
|
||||
out << " {\"" << name1 << "\", (PyCFunction) &"
|
||||
<< func->_name << ", " << flags << ", (char *) " << func->_name << "_comment},\n";
|
||||
if (name1 != name2) {
|
||||
out << " { \"" << name2 << "\", (PyCFunction) &"
|
||||
out << " {\"" << name2 << "\", (PyCFunction) &"
|
||||
<< func->_name << ", " << flags << ", (char *) " << func->_name << "_comment},\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -1566,37 +1645,43 @@ write_module_class(ostream &out, Object *obj) {
|
|||
|
||||
if (obj->_protocol_types & Object::PT_make_copy) {
|
||||
if (!got_copy) {
|
||||
out << " { \"__copy__\", (PyCFunction) ©_from_make_copy, METH_NOARGS, NULL},\n";
|
||||
out << " {\"__copy__\", (PyCFunction) ©_from_make_copy, METH_NOARGS, NULL},\n";
|
||||
got_copy = true;
|
||||
}
|
||||
} else if (obj->_protocol_types & Object::PT_copy_constructor) {
|
||||
if (!got_copy) {
|
||||
out << " { \"__copy__\", (PyCFunction) ©_from_copy_constructor, METH_NOARGS, NULL},\n";
|
||||
out << " {\"__copy__\", (PyCFunction) ©_from_copy_constructor, METH_NOARGS, NULL},\n";
|
||||
got_copy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_copy && !got_deepcopy) {
|
||||
out << " { \"__deepcopy__\", (PyCFunction) &map_deepcopy_to_copy, METH_VARARGS, NULL},\n";
|
||||
out << " {\"__deepcopy__\", (PyCFunction) &map_deepcopy_to_copy, METH_VARARGS, NULL},\n";
|
||||
}
|
||||
|
||||
MakeSeqs::iterator msi;
|
||||
for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) {
|
||||
string flags = "METH_NOARGS";
|
||||
if (obj->is_static_method((*msi)->_element_name)) {
|
||||
flags += " | METH_CLASS";
|
||||
}
|
||||
string name1 = methodNameFromCppName((*msi)->_seq_name, export_class_name, false);
|
||||
string name2 = methodNameFromCppName((*msi)->_seq_name, export_class_name, true);
|
||||
out << " { \"" << name1
|
||||
<< "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n";
|
||||
if (name1 != name2) {
|
||||
out << " { \"" << name2
|
||||
const string &seq_name = (*msi)->_seq_name;
|
||||
|
||||
if ((seq_name.size() > 4 && seq_name.substr(0, 4) == "get_") ||
|
||||
(seq_name.size() > 7 && seq_name.substr(0, 7) == "modify_")) {
|
||||
|
||||
string flags = "METH_NOARGS";
|
||||
if (obj->is_static_method((*msi)->_element_name)) {
|
||||
flags += " | METH_CLASS";
|
||||
}
|
||||
string name1 = methodNameFromCppName((*msi)->_seq_name, export_class_name, false);
|
||||
string name2 = methodNameFromCppName((*msi)->_seq_name, export_class_name, true);
|
||||
out << " {\"" << name1
|
||||
<< "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n";
|
||||
if (name1 != name2) {
|
||||
out << " { \"" << name2
|
||||
<< "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out << " { NULL, NULL, 0, NULL }\n"
|
||||
out << " {NULL, NULL, 0, NULL}\n"
|
||||
<< "};\n\n";
|
||||
|
||||
int num_derivations = obj->_itype.number_of_derivations();
|
||||
|
|
@ -1607,7 +1692,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
const InterrogateType &d_itype = idb->get_type(d_type_Index);
|
||||
if (is_cpp_type_legal(d_itype._cpptype)) {
|
||||
if (!isExportThisRun(d_itype._cpptype)) {
|
||||
_external_imports.insert(d_itype._cpptype);
|
||||
_external_imports.insert(TypeManager::resolve_type(d_itype._cpptype));
|
||||
|
||||
//out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(d_itype.get_scoped_name().c_str()) << ";\n";
|
||||
}
|
||||
|
|
@ -2649,7 +2734,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
|
||||
// Output the actual PyTypeObject definition.
|
||||
out << "EXPORT_THIS Dtool_PyTypedObject Dtool_" << ClassName << " = {\n";
|
||||
out << "struct Dtool_PyTypedObject Dtool_" << ClassName << " = {\n";
|
||||
out << " {\n";
|
||||
out << " PyVarObject_HEAD_INIT(NULL, 0)\n";
|
||||
// const char *tp_name;
|
||||
|
|
@ -2848,12 +2933,36 @@ write_module_class(ostream &out, Object *obj) {
|
|||
out << " 0, // tp_version_tag\n";
|
||||
out << "#endif\n";
|
||||
out << " },\n";
|
||||
|
||||
// It's tempting to initialize the type handle here, but this causes static
|
||||
// init ordering issues; this may run before init_type is called.
|
||||
out << " TypeHandle::none(),\n";
|
||||
out << " Dtool_PyModuleClassInit_" << ClassName << ",\n";
|
||||
out << " Dtool_UpcastInterface_" << ClassName << ",\n";
|
||||
out << " Dtool_DowncastInterface_" << ClassName << ",\n";
|
||||
out << " TypeHandle::none(),\n";
|
||||
|
||||
int has_coerce = has_coerce_constructor(obj->_itype._cpptype->as_struct_type());
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(obj->_itype._cpptype) ||
|
||||
!TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
out << " (CoerceFunction)Dtool_ConstCoerce_" << ClassName << ",\n";
|
||||
if (has_coerce > 1) {
|
||||
out << " (CoerceFunction)Dtool_Coerce_" << ClassName << ",\n";
|
||||
} else {
|
||||
out << " (CoerceFunction)0,\n";
|
||||
}
|
||||
} else {
|
||||
out << " (CoerceFunction)0,\n";
|
||||
out << " (CoerceFunction)Dtool_Coerce_" << ClassName << ",\n";
|
||||
}
|
||||
} else {
|
||||
out << " (CoerceFunction)0,\n";
|
||||
out << " (CoerceFunction)0,\n";
|
||||
}
|
||||
|
||||
out << "};\n\n";
|
||||
|
||||
out << "void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module) {\n";
|
||||
out << "static void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module) {\n";
|
||||
out << " (void) module; // Unused\n";
|
||||
out << " static bool initdone = false;\n";
|
||||
out << " if (!initdone) {\n";
|
||||
|
|
@ -2864,11 +2973,14 @@ write_module_class(ostream &out, Object *obj) {
|
|||
out << " // Dependent objects\n";
|
||||
string baseargs;
|
||||
for (vector<string>::iterator bi = bases.begin(); bi != bases.end(); ++bi) {
|
||||
baseargs += ", &Dtool_" + *bi + ".As_PyTypeObject()";
|
||||
out << " Dtool_PyModuleClassInit_" << make_safe_name(*bi) << "(NULL);\n";
|
||||
baseargs += ", (PyTypeObject *)Dtool_Ptr_" + *bi;
|
||||
string safe_name = make_safe_name(*bi);
|
||||
|
||||
out << " assert(Dtool_Ptr_" << safe_name << " != NULL);\n"
|
||||
<< " Dtool_Ptr_" << safe_name << "->_Dtool_ModuleClassInit(NULL);\n";
|
||||
}
|
||||
|
||||
out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
|
||||
out << " Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
|
||||
}
|
||||
|
||||
int num_nested = obj->_itype.number_of_nested_types();
|
||||
|
|
@ -2901,7 +3013,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
} else {
|
||||
out << " PyObject *dict = PyDict_New();\n";
|
||||
}
|
||||
out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_dict = dict;\n";
|
||||
out << " Dtool_" << ClassName << "._PyType.tp_dict = dict;\n";
|
||||
out << " PyDict_SetItemString(dict, \"DtoolClassDict\", dict);\n";
|
||||
|
||||
// Now go through the nested types again to actually add the dict items.
|
||||
|
|
@ -2922,9 +3034,9 @@ write_module_class(ostream &out, Object *obj) {
|
|||
out << " Dtool_PyModuleClassInit_" << ClassName1 << "(NULL);\n";
|
||||
string name1 = classNameFromCppName(ClassName2, false);
|
||||
string name2 = classNameFromCppName(ClassName2, true);
|
||||
out << " PyDict_SetItemString(dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n";
|
||||
out << " PyDict_SetItemString(dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ");\n";
|
||||
if (name1 != name2) {
|
||||
out << " PyDict_SetItemString(dict, \"" << name2 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n";
|
||||
out << " PyDict_SetItemString(dict, \"" << name2 << "\", (PyObject *)&Dtool_" << ClassName1 << ");\n";
|
||||
}
|
||||
|
||||
} else if (nested_obj->_itype.is_typedef()) {
|
||||
|
|
@ -2943,7 +3055,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
string ClassName2 = make_safe_name(interrogate_type_name(wrapped));
|
||||
|
||||
string name1 = classNameFromCppName(ClassName2, false);
|
||||
out << " PyDict_SetItemString(dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n";
|
||||
out << " PyDict_SetItemString(dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ");\n";
|
||||
// No need to support mangled names for nested typedefs; we only added support recently.
|
||||
|
||||
} else if (nested_obj->_itype.is_enum()) {
|
||||
|
|
@ -2969,28 +3081,12 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
out << " if (PyType_Ready(&Dtool_" << ClassName << ".As_PyTypeObject()) < 0) {\n";
|
||||
out << " Dtool_Raise_TypeError(\"PyType_Ready(" << ClassName << ")\");\n";
|
||||
out << " return;\n";
|
||||
out << " }\n";
|
||||
|
||||
out << " Py_INCREF(&Dtool_" << ClassName << ".As_PyTypeObject());\n";
|
||||
|
||||
// Why make the class a member of itself?
|
||||
//out << " PyDict_SetItemString(Dtool_" <<ClassName << ".As_PyTypeObject().tp_dict,\"" <<export_class_name<< "\",&Dtool_" <<ClassName << ".As_PyObject());\n";
|
||||
|
||||
bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
|
||||
if (HasAGetClassTypeFunction(obj->_itype)) {
|
||||
is_runtime_typed = true;
|
||||
}
|
||||
|
||||
if (is_runtime_typed) {
|
||||
out << " RegisterRuntimeClass(&Dtool_" << ClassName << ", " << cClassName << "::get_class_type().get_index());\n";
|
||||
} else {
|
||||
out << " RegisterRuntimeClass(&Dtool_" << ClassName << ", -1);\n";
|
||||
}
|
||||
|
||||
out << " }\n";
|
||||
out << " if (PyType_Ready((PyTypeObject *)&Dtool_" << ClassName << ") < 0) {\n"
|
||||
" Dtool_Raise_TypeError(\"PyType_Ready(" << ClassName << ")\");\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" Py_INCREF((PyTypeObject *)&Dtool_" << ClassName << ");\n"
|
||||
" }\n";
|
||||
|
||||
// Also write out the explicit alternate names.
|
||||
//int num_alt_names = obj->_itype.get_num_alt_names();
|
||||
|
|
@ -3625,12 +3721,14 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
|
||||
std::string cClassName = obj->_itype.get_true_name();
|
||||
|
||||
int return_flags = RF_coerced;
|
||||
|
||||
if (TypeManager::is_reference_count(obj->_itype._cpptype)) {
|
||||
// The coercion works slightly different for reference counted types, since
|
||||
// we can handle those a bit more nicely by taking advantage of the refcount
|
||||
// instead of having to use a boolean to indicate that it should be managed.
|
||||
if (is_const) {
|
||||
out << "bool Dtool_Coerce_" << ClassName << "(PyObject *args, CPT(" << cClassName << ") &coerced) {\n";
|
||||
out << "bool Dtool_ConstCoerce_" << ClassName << "(PyObject *args, CPT(" << cClassName << ") &coerced) {\n";
|
||||
} else {
|
||||
out << "bool Dtool_Coerce_" << ClassName << "(PyObject *args, PT(" << cClassName << ") &coerced) {\n";
|
||||
}
|
||||
|
|
@ -3650,9 +3748,26 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
out << " coerced->ref();\n";
|
||||
out << " return true;\n";
|
||||
}
|
||||
return_flags |= RF_err_false;
|
||||
|
||||
} else if (TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
out << cClassName << " *Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " &coerced) {\n";
|
||||
|
||||
out << " " << cClassName << " *local_this;\n";
|
||||
out << " DTOOL_Call_ExtractThisPointerForType(args, &Dtool_" << ClassName << ", (void**)&local_this);\n";
|
||||
out << " if (local_this != NULL) {\n";
|
||||
out << " if (((Dtool_PyInstDef *)args)->_is_const) {\n";
|
||||
out << " // This is a const object. Make a copy.\n";
|
||||
out << " coerced = *(const " << cClassName << " *)local_this;\n";
|
||||
out << " return &coerced;\n";
|
||||
out << " }\n";
|
||||
out << " return local_this;\n";
|
||||
|
||||
return_flags |= RF_err_null;
|
||||
|
||||
} else {
|
||||
if (is_const) {
|
||||
out << "bool Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " const *&coerced, bool &manage) {\n";
|
||||
out << "bool Dtool_ConstCoerce_" << ClassName << "(PyObject *args, " << cClassName << " const *&coerced, bool &manage) {\n";
|
||||
} else {
|
||||
out << "bool Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " *&coerced, bool &manage) {\n";
|
||||
}
|
||||
|
|
@ -3667,12 +3782,14 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
} else {
|
||||
out << " return true;\n";
|
||||
}
|
||||
|
||||
return_flags |= RF_err_false;
|
||||
}
|
||||
|
||||
out << " }\n\n";
|
||||
|
||||
if (map_sets.empty()) {
|
||||
error_return(out, 2, RF_coerced | RF_err_false);
|
||||
error_return(out, 2, return_flags);
|
||||
out << "}\n\n";
|
||||
return;
|
||||
}
|
||||
|
|
@ -3687,12 +3804,12 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
out << " PyObject *arg = args;\n";
|
||||
|
||||
write_function_forset(out, mii->second, mii->first, mii->first, expected_params, 4, false, false,
|
||||
AT_single_arg, RF_coerced | RF_err_false, true, false);
|
||||
AT_single_arg, return_flags, true, false);
|
||||
|
||||
if (map_sets.size() == 1) {
|
||||
out << " }\n";
|
||||
//out << " PyErr_Clear();\n";
|
||||
error_return(out, 2, RF_coerced | RF_err_false);
|
||||
error_return(out, 2, return_flags);
|
||||
out << "}\n\n";
|
||||
return;
|
||||
}
|
||||
|
|
@ -3730,7 +3847,7 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
indent(out, 6) << "case " << max_args << ": {\n";
|
||||
|
||||
write_function_forset(out, mii->second, min_args, max_args, expected_params, 8, false, false,
|
||||
AT_varargs, RF_coerced | RF_err_false, true, false);
|
||||
AT_varargs, return_flags, true, false);
|
||||
|
||||
indent(out, 8) << "break;\n";
|
||||
indent(out, 6) << "}\n";
|
||||
|
|
@ -3760,13 +3877,13 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
|||
}
|
||||
|
||||
write_function_forset(out, mii->second, min_args, max_args, expected_params, 6, false, false,
|
||||
AT_varargs, RF_coerced | RF_err_false, true, false);
|
||||
AT_varargs, return_flags, true, false);
|
||||
indent(out, 4) << "}\n";
|
||||
}
|
||||
|
||||
out << " }\n\n";
|
||||
//out << " PyErr_Clear();\n";
|
||||
error_return(out, 2, RF_coerced | RF_err_false);
|
||||
error_return(out, 2, return_flags);
|
||||
out << "}\n\n";
|
||||
}
|
||||
|
||||
|
|
@ -5163,7 +5280,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
|
||||
// need to a forward scope for this class..
|
||||
if (!isExportThisRun(obj_type)) {
|
||||
_external_imports.insert(obj_type);
|
||||
_external_imports.insert(TypeManager::resolve_type(obj_type));
|
||||
}
|
||||
|
||||
string this_class_name;
|
||||
|
|
@ -5183,19 +5300,50 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
// We use a PointerTo to handle the management here. It's cleaner
|
||||
// that way.
|
||||
if (TypeManager::is_const_pointer_to_anything(type)) {
|
||||
extra_convert << 'C';
|
||||
}
|
||||
extra_convert
|
||||
<< "PT(" << class_name << ") " << param_name << "_this"
|
||||
<< default_expr << ";\n";
|
||||
extra_convert
|
||||
<< "CPT(" << class_name << ") " << param_name << "_this"
|
||||
<< default_expr << ";\n";
|
||||
|
||||
coerce_call = "Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this)";
|
||||
coerce_call = "Dtool_ConstCoerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this)";
|
||||
} else {
|
||||
extra_convert
|
||||
<< "PT(" << class_name << ") " << param_name << "_this"
|
||||
<< default_expr << ";\n";
|
||||
|
||||
coerce_call = "Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this)";
|
||||
}
|
||||
|
||||
// Use move constructor when available for functions that take
|
||||
// an actual PointerTo. This eliminates an unref()/ref() pair.
|
||||
pexpr_string = "MOVE(" + param_name + "_this)";
|
||||
|
||||
} else if (TypeManager::is_trivial(obj_type)) {
|
||||
// This is a trivial type, such as TypeHandle or LVecBase4.
|
||||
obj_type->output_instance(extra_convert, param_name + "_local", &parser);
|
||||
extra_convert << ";\n";
|
||||
|
||||
type->output_instance(extra_convert, param_name + "_this", &parser);
|
||||
|
||||
if (is_optional) {
|
||||
extra_convert
|
||||
<< default_expr << ";\n"
|
||||
<< "if (" << param_name << " != NULL) {\n"
|
||||
<< " " << param_name << "_this";
|
||||
}
|
||||
|
||||
extra_convert << " = Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_local);\n";
|
||||
|
||||
if (is_optional) {
|
||||
extra_convert << "}\n";
|
||||
}
|
||||
|
||||
coerce_call = "(" + param_name + "_this != NULL)";
|
||||
|
||||
pexpr_string = param_name + "_this";
|
||||
|
||||
} else {
|
||||
// This is a bit less elegant: we use a bool to store whether
|
||||
// we're supposed to clean up the reference afterward.
|
||||
|
|
@ -5204,8 +5352,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
<< default_expr << ";\n"
|
||||
<< "bool " << param_name << "_manage = false;\n";
|
||||
|
||||
coerce_call = "Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this, " + param_name + "_manage)";
|
||||
if (TypeManager::is_const_pointer_or_ref(orig_type)) {
|
||||
coerce_call = "Dtool_ConstCoerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this, " + param_name + "_manage)";
|
||||
} else {
|
||||
coerce_call = "Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this, " + param_name + "_manage)";
|
||||
}
|
||||
|
||||
extra_cleanup
|
||||
<< "if (" << param_name << "_manage) {\n"
|
||||
|
|
@ -5266,13 +5419,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
}
|
||||
extra_convert
|
||||
<< "DTOOL_Call_ExtractThisPointerForType(" << param_name
|
||||
<< ", &Dtool_" << make_safe_name(class_name)
|
||||
<< ", Dtool_Ptr_" << make_safe_name(class_name)
|
||||
<< ", (void **)&" << param_name << "_this);\n";
|
||||
} else {
|
||||
extra_convert << boolalpha
|
||||
<< " = (" << class_name << " *)"
|
||||
<< "DTOOL_Call_GetPointerThisClass(" << param_name
|
||||
<< ", &Dtool_" << make_safe_name(class_name)
|
||||
<< ", Dtool_Ptr_" << make_safe_name(class_name)
|
||||
<< ", " << pn << ", \""
|
||||
<< method_prefix << methodNameFromCppName(remap, this_class_name, false)
|
||||
<< "\", " << const_ok << ", " << report_errors << ");\n";
|
||||
|
|
@ -5462,6 +5615,20 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
manage_return = remap->_return_value_needs_management;
|
||||
return_expr = "return_value";
|
||||
|
||||
} else if ((return_flags & RF_coerced) != 0 && TypeManager::is_trivial(remap->_cpptype)) {
|
||||
// Another special case is the coerce constructor for a trivial type.
|
||||
// We don't want to invoke "operator new" unnecessarily.
|
||||
if (is_constructor && remap->_extension) {
|
||||
// Extension constructors are a special case, as usual.
|
||||
indent(out, indent_level)
|
||||
<< remap->get_call_str("&coerced", pexprs) << ";\n";
|
||||
|
||||
} else {
|
||||
indent(out, indent_level)
|
||||
<< "coerced = " << remap->get_call_str(container, pexprs) << ";\n";
|
||||
}
|
||||
return_expr = "&coerced";
|
||||
|
||||
} else {
|
||||
// The general case; an ordinary constructor or function.
|
||||
return_expr = remap->call_function(out, indent_level, true, container, pexprs);
|
||||
|
|
@ -5626,7 +5793,10 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
// the C++ code was executing, and report this failure back to Python.
|
||||
// Don't do this for coercion constructors since they are called by
|
||||
// other wrapper functions which already check this on their own.
|
||||
if (watch_asserts && (return_flags & RF_coerced) == 0) {
|
||||
// Generated getters obviously can't raise asserts.
|
||||
if (watch_asserts && (return_flags & RF_coerced) == 0 &&
|
||||
remap->_type != FunctionRemap::T_getter &&
|
||||
remap->_type != FunctionRemap::T_setter) {
|
||||
out << "#ifndef NDEBUG\n";
|
||||
indent(out, indent_level)
|
||||
<< "Notify *notify = Notify::ptr();\n";
|
||||
|
|
@ -5663,7 +5833,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false);
|
||||
const InterrogateType &itype = idb->get_type(type_index);
|
||||
indent(out, indent_level)
|
||||
<< "return DTool_PyInit_Finalize(self, " << return_expr << ", &" << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", true, false);\n";
|
||||
<< "return DTool_PyInit_Finalize(self, (void *)" << return_expr << ", &" << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", true, false);\n";
|
||||
|
||||
} else if (TypeManager::is_integer(orig_type)) {
|
||||
if (return_flags & RF_compare) {
|
||||
|
|
@ -5678,7 +5848,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
indent(out, indent_level) << "return 0;\n";
|
||||
|
||||
} else {
|
||||
cerr << "Warning: function has return type " << *orig_type
|
||||
nout << "Warning: function has return type " << *orig_type
|
||||
<< ", expected int or void:\n" << expected_params << "\n";
|
||||
indent(out, indent_level) << "// Don't know what to do with return type "
|
||||
<< *orig_type << ".\n";
|
||||
|
|
@ -5728,16 +5898,20 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
|
||||
if (return_expr == "coerced") {
|
||||
// We already did this earlier...
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
|
||||
} else if (TypeManager::is_reference_count(remap->_cpptype)) {
|
||||
indent(out, indent_level) << "coerced = MOVE(" << return_expr << ");\n";
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
|
||||
} else if (TypeManager::is_trivial(remap->_cpptype)) {
|
||||
indent(out, indent_level) << "return &coerced;\n";
|
||||
|
||||
} else {
|
||||
indent(out, indent_level) << "coerced = " << return_expr << ";\n";
|
||||
indent(out, indent_level) << "manage = true;\n";
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
}
|
||||
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
}
|
||||
|
||||
// Close the extra braces opened earlier.
|
||||
|
|
@ -5827,7 +6001,8 @@ error_raise_return(ostream &out, int indent_level, int return_flags,
|
|||
out << ");\n";
|
||||
}
|
||||
|
||||
} else if ((return_flags & RF_err_null) != 0) {
|
||||
} else if ((return_flags & RF_err_null) != 0 &&
|
||||
(return_flags & RF_pyobject) != 0) {
|
||||
// PyErr_Format always returns NULL. Passing it on directly allows
|
||||
// the compiler to make a tiny optimization, so why not.
|
||||
indent(out, indent_level) << "return PyErr_Format(PyExc_" << exc_type << ",\n";
|
||||
|
|
@ -6265,7 +6440,6 @@ record_object(TypeIndex type_index) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonNative::
|
||||
generate_wrappers() {
|
||||
inside_python_native = true;
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
||||
// We use a while loop rather than a simple for loop, because we
|
||||
|
|
@ -6314,7 +6488,6 @@ generate_wrappers() {
|
|||
record_function(dummy_type, func_index);
|
||||
}
|
||||
}
|
||||
inside_python_native = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
|
@ -6490,9 +6663,9 @@ has_coerce_constructor(CPPStructType *type) {
|
|||
}
|
||||
|
||||
if (ftype->_flags & CPPFunctionType::F_constructor) {
|
||||
if (params.size() == 1 &&
|
||||
TypeManager::unwrap(params[0]->_type) == type) {
|
||||
// Skip a copy constructor.
|
||||
if (ftype->_flags & (CPPFunctionType::F_copy_constructor |
|
||||
CPPFunctionType::F_move_constructor)) {
|
||||
// Skip a copy and move constructor.
|
||||
continue;
|
||||
} else {
|
||||
return 2;
|
||||
|
|
@ -6626,37 +6799,19 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
|
|||
// does the class have a supportable GetClassType which returns a TypeHandle.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool InterfaceMakerPythonNative::
|
||||
HasAGetClassTypeFunction(const InterrogateType &itype_class) {
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
||||
int num_methods = itype_class.number_of_methods();
|
||||
int mi;
|
||||
|
||||
for (mi = 0; mi < num_methods; mi++) {
|
||||
FunctionIndex func_index = itype_class.get_method(mi);
|
||||
const InterrogateFunction &ifunc = idb->get_function(func_index);
|
||||
if (ifunc.get_name() == "get_class_type") {
|
||||
if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
|
||||
InterrogateFunction::Instances::const_iterator ii;
|
||||
for (ii = ifunc._instances->begin();ii != ifunc._instances->end();++ii) {
|
||||
CPPInstance *cppinst = (*ii).second;
|
||||
CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
|
||||
|
||||
if (cppfunc != NULL && cppfunc->_return_type != NULL &&
|
||||
cppfunc->_parameters != NULL) {
|
||||
CPPType *ret_type = TypeManager::unwrap(cppfunc->_return_type);
|
||||
if (TypeManager::is_struct(ret_type) &&
|
||||
ret_type->get_simple_name() == "TypeHandle") {
|
||||
if (cppfunc->_parameters->_parameters.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HasAGetClassTypeFunction(CPPType *type) {
|
||||
while (type->get_subtype() == CPPDeclaration::ST_typedef) {
|
||||
type = type->as_typedef_type()->_type;
|
||||
}
|
||||
return false;
|
||||
|
||||
CPPStructType *struct_type = type->as_struct_type();
|
||||
if (struct_type == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CPPScope *scope = struct_type->get_scope();
|
||||
|
||||
return scope->_functions.find("get_class_type") != scope->_functions.end();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ public:
|
|||
bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
|
||||
bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
|
||||
void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const InterrogateType &itype, bool is_const);
|
||||
bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
|
||||
bool HasAGetClassTypeFunction(CPPType *type);
|
||||
int NeedsAStrFunction(const InterrogateType &itype_class);
|
||||
int NeedsAReprFunction(const InterrogateType &itype_class);
|
||||
bool NeedsARichCompareFunction(const InterrogateType &itype_class);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
|
||||
InterrogateBuilder builder;
|
||||
std::string EXPORT_IMPORT_PREFIX;
|
||||
bool inside_python_native = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InterrogateBuilder::add_source_file
|
||||
|
|
@ -1912,27 +1911,29 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
|
|||
CPPType *return_type = NULL;
|
||||
|
||||
CPPFunctionGroup *fgroup = make_property->_getter;
|
||||
CPPFunctionGroup::Instances::const_iterator fi;
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
CPPFunctionType *ftype =
|
||||
function->_type->as_function_type();
|
||||
if (ftype != NULL && ftype->_parameters->_parameters.size() == 0) {
|
||||
getter = function;
|
||||
return_type = ftype->_return_type;
|
||||
if (fgroup != NULL) {
|
||||
CPPFunctionGroup::Instances::const_iterator fi;
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
CPPFunctionType *ftype =
|
||||
function->_type->as_function_type();
|
||||
if (ftype != NULL && ftype->_parameters->_parameters.size() == 0) {
|
||||
getter = function;
|
||||
return_type = ftype->_return_type;
|
||||
|
||||
// The return type of the non-const method probably better represents
|
||||
// the type of the property we are creating.
|
||||
if ((ftype->_flags & CPPFunctionType::F_const_method) == 0) {
|
||||
break;
|
||||
// The return type of the non-const method probably better represents
|
||||
// the type of the property we are creating.
|
||||
if ((ftype->_flags & CPPFunctionType::F_const_method) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getter == NULL || return_type == NULL) {
|
||||
cerr << "No instance of getter '"
|
||||
<< make_property->_getter->_name << "' is suitable!\n";
|
||||
return 0;
|
||||
if (getter == NULL || return_type == NULL) {
|
||||
cerr << "No instance of getter '"
|
||||
<< fgroup->_name << "' is suitable!\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
|
@ -1944,11 +1945,17 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
|
|||
iproperty._name = make_property->get_simple_name();
|
||||
iproperty._scoped_name = descope(make_property->get_local_name(&parser));
|
||||
|
||||
iproperty._type = get_type(return_type, false);
|
||||
if (return_type != NULL) {
|
||||
iproperty._type = get_type(return_type, false);
|
||||
} else {
|
||||
iproperty._type = 0;
|
||||
}
|
||||
|
||||
iproperty._flags |= InterrogateElement::F_has_getter;
|
||||
iproperty._getter = get_function(getter, "", struct_type,
|
||||
struct_type->get_scope(), 0);
|
||||
if (getter != NULL) {
|
||||
iproperty._flags |= InterrogateElement::F_has_getter;
|
||||
iproperty._getter = get_function(getter, "", struct_type,
|
||||
struct_type->get_scope(), 0);
|
||||
}
|
||||
|
||||
// See if there happens to be a comment before the MAKE_PROPERTY macro.
|
||||
if (make_property->_leading_comment != (CPPCommentBlock *)NULL) {
|
||||
|
|
@ -1958,6 +1965,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
|
|||
// Now look for setters.
|
||||
fgroup = make_property->_setter;
|
||||
if (fgroup != NULL) {
|
||||
CPPFunctionGroup::Instances::const_iterator fi;
|
||||
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
|
||||
CPPInstance *function = (*fi);
|
||||
iproperty._flags |= InterrogateElement::F_has_setter;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "panda_getopt_long.h"
|
||||
#include "preprocess_argv.h"
|
||||
#include "pset.h"
|
||||
#include "vector_string.h"
|
||||
|
||||
Filename output_code_filename;
|
||||
string module_name;
|
||||
|
|
@ -33,6 +34,7 @@ bool build_c_wrappers = false;
|
|||
bool build_python_wrappers = false;
|
||||
bool build_python_native_wrappers = false;
|
||||
bool track_interpreter = false;
|
||||
vector_string imports;
|
||||
|
||||
// Short command-line options.
|
||||
static const char *short_options = "";
|
||||
|
|
@ -46,6 +48,7 @@ enum CommandOptions {
|
|||
CO_python,
|
||||
CO_python_native,
|
||||
CO_track_interpreter,
|
||||
CO_import,
|
||||
};
|
||||
|
||||
static struct option long_options[] = {
|
||||
|
|
@ -56,6 +59,7 @@ static struct option long_options[] = {
|
|||
{ "python", no_argument, NULL, CO_python },
|
||||
{ "python-native", no_argument, NULL, CO_python_native },
|
||||
{ "track-interpreter", no_argument, NULL, CO_track_interpreter },
|
||||
{ "import", required_argument, NULL, CO_import },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
@ -113,6 +117,9 @@ int write_python_table_native(ostream &out) {
|
|||
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
printf("Referencing Library %s\n", (*ii).c_str());
|
||||
out << "extern LibraryDef " << *ii << "_moddef;\n";
|
||||
out << "extern void Dtool_" << *ii << "_RegisterTypes();\n";
|
||||
out << "extern void Dtool_" << *ii << "_ResolveExternals();\n";
|
||||
out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n";
|
||||
}
|
||||
|
||||
out << "\n"
|
||||
|
|
@ -138,6 +145,19 @@ int write_python_table_native(ostream &out) {
|
|||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
vector_string::const_iterator si;
|
||||
for (si = imports.begin(); si != imports.end(); ++si) {
|
||||
out << " PyImport_Import(PyUnicode_FromString(\"" << *si << "\"));\n";
|
||||
}
|
||||
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_RegisterTypes();\n";
|
||||
}
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_ResolveExternals();\n";
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
out << " LibraryDef *defs[] = {";
|
||||
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << "&" << *ii << "_moddef, ";
|
||||
|
|
@ -145,7 +165,15 @@ int write_python_table_native(ostream &out) {
|
|||
|
||||
out << "NULL};\n"
|
||||
<< "\n"
|
||||
<< " return Dtool_PyModuleInitHelper(defs, &py_" << library_name << "_module);\n"
|
||||
<< " PyObject *module = Dtool_PyModuleInitHelper(defs, &py_" << library_name << "_module);\n"
|
||||
<< " if (module != NULL) {\n";
|
||||
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_BuildInstants(module);\n";
|
||||
}
|
||||
|
||||
out << " }\n"
|
||||
<< " return module;\n"
|
||||
<< "}\n"
|
||||
<< "\n"
|
||||
<< "#else // Python 2 case\n"
|
||||
|
|
@ -162,6 +190,18 @@ int write_python_table_native(ostream &out) {
|
|||
out << " in_interpreter = 1;\n";
|
||||
}
|
||||
|
||||
for (si = imports.begin(); si != imports.end(); ++si) {
|
||||
out << " PyImport_Import(PyUnicode_FromString(\"" << *si << "\"));\n";
|
||||
}
|
||||
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_RegisterTypes();\n";
|
||||
}
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_ResolveExternals();\n";
|
||||
}
|
||||
out << "\n";
|
||||
|
||||
out << " LibraryDef *defs[] = {";
|
||||
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << "&" << *ii << "_moddef, ";
|
||||
|
|
@ -169,7 +209,14 @@ int write_python_table_native(ostream &out) {
|
|||
|
||||
out << "NULL};\n"
|
||||
<< "\n"
|
||||
<< " Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n"
|
||||
<< " PyObject *module = Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n"
|
||||
<< " if (module != NULL) {\n";
|
||||
|
||||
for (ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
out << " Dtool_" << *ii << "_BuildInstants(module);\n";
|
||||
}
|
||||
|
||||
out << " }\n"
|
||||
<< "}\n"
|
||||
<< "#endif\n"
|
||||
<< "\n";
|
||||
|
|
@ -335,6 +382,10 @@ int main(int argc, char *argv[]) {
|
|||
track_interpreter = true;
|
||||
break;
|
||||
|
||||
case CO_import:
|
||||
imports.push_back(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2570,4 +2570,59 @@ is_local(CPPType *source_type) {
|
|||
|
||||
return false;
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_trivial
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the type is trivial (or trivial
|
||||
// enough for our purposes).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_trivial(CPPType *source_type) {
|
||||
switch (source_type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_trivial(source_type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_reference:
|
||||
return false;
|
||||
|
||||
case CPPDeclaration::ST_pointer:
|
||||
return true;
|
||||
|
||||
case CPPDeclaration::ST_simple:
|
||||
return true;
|
||||
|
||||
case CPPDeclaration::ST_typedef:
|
||||
return is_trivial(source_type->as_typedef_type()->_type);
|
||||
|
||||
default:
|
||||
if (source_type->is_trivial()) {
|
||||
return true;
|
||||
} else {
|
||||
// This is a bit of a hack. is_trivial() returns false for types that
|
||||
// have an empty constructor (since we can't use =default yet).
|
||||
// For the other classes, it's just convenient to consider them trivial
|
||||
// even if they aren't, since they are simple enough.
|
||||
string name = source_type->get_simple_name();
|
||||
return (name == "ButtonHandle" || name == "DatagramIterator" ||
|
||||
name == "BitMask" || name == "Filename" || name == "pixel" ||
|
||||
name == "NodePath" || name == "LoaderOptions" ||
|
||||
name == "PointerToArray" || name == "ConstPointerToArray" ||
|
||||
name == "PStatThread" ||
|
||||
(name.size() >= 6 && name.substr(0, 6) == "LPlane") ||
|
||||
(name.size() > 6 && name.substr(0, 6) == "LPoint") ||
|
||||
(name.size() > 7 && name.substr(0, 7) == "LVector") ||
|
||||
(name.size() > 7 && name.substr(0, 7) == "LMatrix") ||
|
||||
(name.size() > 8 && name.substr(0, 8) == "LVecBase") ||
|
||||
(name.size() >= 9 && name.substr(0, 9) == "LParabola") ||
|
||||
(name.size() >= 9 && name.substr(0, 9) == "LRotation") ||
|
||||
(name.size() >= 11 && name.substr(0, 11) == "LQuaternion") ||
|
||||
(name.size() >= 12 && name.substr(0, 12) == "LOrientation") ||
|
||||
(name.size() > 16 && name.substr(0, 16) == "UnalignedLMatrix") ||
|
||||
(name.size() > 17 && name.substr(0, 17) == "UnalignedLVecBase"));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ public:
|
|||
|
||||
static bool is_exported(CPPType *type);
|
||||
static bool is_local(CPPType *type);
|
||||
|
||||
static bool is_trivial(CPPType *type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class EmptyClass {
|
|||
Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
|
||||
|
||||
static PyObject *GetSuperBase(PyObject *self) {
|
||||
Py_INCREF(&(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject())); // order is important .. this is used for static functions
|
||||
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
|
||||
return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
|
||||
};
|
||||
|
||||
|
|
@ -35,21 +35,21 @@ EXPCL_DTOOLCONFIG void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module
|
|||
if (!initdone) {
|
||||
|
||||
initdone = true;
|
||||
Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict = PyDict_New();
|
||||
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict);
|
||||
Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New();
|
||||
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict);
|
||||
|
||||
if (PyType_Ready(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()) < 0) {
|
||||
if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
|
||||
return;
|
||||
}
|
||||
Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
|
||||
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
|
||||
|
||||
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], &Dtool_DTOOL_SUPER_BASE.As_PyObject()));
|
||||
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
|
||||
}
|
||||
|
||||
if (module != NULL) {
|
||||
Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
|
||||
PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject());
|
||||
Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
|
||||
PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,9 +123,12 @@ EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
|
|||
0,
|
||||
0,
|
||||
},
|
||||
TypeHandle::none(),
|
||||
Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
|
||||
Dtool_UpcastInterface_DTOOL_SUPER_BASE,
|
||||
Dtool_DowncastInterface_DTOOL_SUPER_BASE,
|
||||
TypeHandle::none(),
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
|
|||
|
|
@ -269,23 +269,3 @@ remap_indices(const IndexRemapper &remap) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GetRunTimeDictionary
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary()
|
||||
{
|
||||
static RunTimeTypeDictionary dict;
|
||||
return dict;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GetRunTimeTypeList
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList()
|
||||
{
|
||||
static RunTimeTypeList list;
|
||||
return list;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -231,14 +231,4 @@ INLINE istream &operator >> (istream &in, InterrogateType::EnumValue &d);
|
|||
|
||||
#include "interrogateType.I"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
struct Dtool_PyTypedObject;
|
||||
typedef std::map< int , Dtool_PyTypedObject *> RunTimeTypeDictionary;
|
||||
typedef std::set<int > RunTimeTypeList;
|
||||
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary();
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ PyMemberDef standard_type_members[] = {
|
|||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static RuntimeTypeMap runtime_type_map;
|
||||
static RuntimeTypeSet runtime_type_set;
|
||||
static NamedTypeMap named_type_map;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DtoolCanThisBeAPandaInstance
|
||||
// Description: Given a valid (non-NULL) PyObject, does a simple
|
||||
|
|
@ -360,7 +364,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
/////////////////////////////////////////////
|
||||
// ask class to allocate an instance..
|
||||
/////////////////////////////////////////////
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL, NULL);
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) target_class->_PyType.tp_new(&target_class->_PyType, NULL, NULL);
|
||||
if (self != NULL) {
|
||||
self->_ptr_to_object = new_local_this;
|
||||
self->_memory_rules = memory_rules;
|
||||
|
|
@ -377,7 +381,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
// if we get this far .. just wrap the thing in the known type ??
|
||||
// better than aborting...I guess....
|
||||
/////////////////////////////////////////////////////
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL);
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) known_class_type._PyType.tp_new(&known_class_type._PyType, NULL, NULL);
|
||||
if (self != NULL) {
|
||||
self->_ptr_to_object = local_this_in;
|
||||
self->_memory_rules = memory_rules;
|
||||
|
|
@ -401,7 +405,7 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
|
|||
}
|
||||
|
||||
Dtool_PyTypedObject *classdef = &in_classdef;
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL, NULL);
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) classdef->_PyType.tp_new(&classdef->_PyType, NULL, NULL);
|
||||
if (self != NULL) {
|
||||
self->_ptr_to_object = local_this;
|
||||
self->_memory_rules = memory_rules;
|
||||
|
|
@ -446,42 +450,97 @@ void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id) {
|
||||
if (class_id == 0) {
|
||||
RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) {
|
||||
pair<NamedTypeMap::iterator, bool> result =
|
||||
named_type_map.insert(NamedTypeMap::value_type(name, &otype));
|
||||
|
||||
if (!result.second) {
|
||||
// There was already a class with this name in the dictionary.
|
||||
interrogatedb_cat.warning()
|
||||
<< "Class " << otype->_PyType.tp_name
|
||||
<< "Double definition for class " << name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) {
|
||||
int type_index = otype._type.get_index();
|
||||
|
||||
if (type_index == 0) {
|
||||
interrogatedb_cat.warning()
|
||||
<< "Class " << otype._PyType.tp_name
|
||||
<< " has a zero TypeHandle value; check that init_type() is called.\n";
|
||||
|
||||
} else if (class_id > 0) {
|
||||
RunTimeTypeDictionary &dict = GetRunTimeDictionary();
|
||||
pair<RunTimeTypeDictionary::iterator, bool> result =
|
||||
dict.insert(RunTimeTypeDictionary::value_type(class_id, otype));
|
||||
} else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) {
|
||||
interrogatedb_cat.warning()
|
||||
<< "Class " << otype._PyType.tp_name
|
||||
<< " has an illegal TypeHandle value; check that init_type() is called.\n";
|
||||
|
||||
} else {
|
||||
pair<RuntimeTypeMap::iterator, bool> result =
|
||||
runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype));
|
||||
if (!result.second) {
|
||||
// There was already an entry in the dictionary for class_id.
|
||||
// There was already an entry in the dictionary for type_index.
|
||||
Dtool_PyTypedObject *other_type = (*result.first).second;
|
||||
interrogatedb_cat.warning()
|
||||
<< "Classes " << otype->_PyType.tp_name
|
||||
<< "Classes " << otype._PyType.tp_name
|
||||
<< " and " << other_type->_PyType.tp_name
|
||||
<< " share the same TypeHandle value (" << class_id
|
||||
<< " share the same TypeHandle value (" << type_index
|
||||
<< "); check class definitions.\n";
|
||||
|
||||
} else {
|
||||
GetRunTimeTypeList().insert(class_id);
|
||||
otype->_type = TypeRegistry::ptr()->find_type_by_id(class_id);
|
||||
runtime_type_set.insert(type_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dtool_PyTypedObject *
|
||||
LookupNamedClass(const string &name) {
|
||||
NamedTypeMap::const_iterator it;
|
||||
it = named_type_map.find(name);
|
||||
|
||||
if (it == named_type_map.end()) {
|
||||
// Find a type named like this in the type registry.
|
||||
TypeHandle handle = TypeRegistry::ptr()->find_type(name);
|
||||
if (handle.get_index() > 0) {
|
||||
RuntimeTypeMap::const_iterator it2;
|
||||
it2 = runtime_type_map.find(handle.get_index());
|
||||
if (it2 != runtime_type_map.end()) {
|
||||
return it2->second;
|
||||
}
|
||||
}
|
||||
|
||||
interrogatedb_cat.error()
|
||||
<< "Attempt to use type " << name << " which has not yet been defined!\n";
|
||||
return NULL;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
Dtool_PyTypedObject *
|
||||
LookupRuntimeTypedClass(TypeHandle handle) {
|
||||
RuntimeTypeMap::const_iterator it;
|
||||
it = runtime_type_map.find(handle.get_index());
|
||||
|
||||
if (it == runtime_type_map.end()) {
|
||||
interrogatedb_cat.error()
|
||||
<< "Attempt to use type " << handle << " which has not yet been defined!\n";
|
||||
return NULL;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
|
||||
RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type);
|
||||
if (di != GetRunTimeDictionary().end()) {
|
||||
RuntimeTypeMap::iterator di = runtime_type_map.find(type);
|
||||
if (di != runtime_type_map.end()) {
|
||||
return di->second;
|
||||
} else {
|
||||
int type2 = get_best_parent_from_Set(type, GetRunTimeTypeList());
|
||||
di = GetRunTimeDictionary().find(type2);
|
||||
if (di != GetRunTimeDictionary().end()) {
|
||||
int type2 = get_best_parent_from_Set(type, runtime_type_set);
|
||||
di = runtime_type_map.find(type2);
|
||||
if (di != runtime_type_map.end()) {
|
||||
return di->second;
|
||||
}
|
||||
}
|
||||
|
|
@ -526,11 +585,6 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// the constant inits... enums, classes ...
|
||||
for (int y = 0; defs[y] != NULL; y++) {
|
||||
defs[y]->_constants(module);
|
||||
}
|
||||
|
||||
PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);
|
||||
return module;
|
||||
}
|
||||
|
|
@ -710,33 +764,6 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
|
|||
return PyBool_FromLong(result);
|
||||
}
|
||||
|
||||
PyObject *make_list_for_item(PyObject *self, const char *num_name,
|
||||
const char *element_name) {
|
||||
PyObject *num_result = PyObject_CallMethod(self, (char *)num_name, (char *)"()");
|
||||
if (num_result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_ssize_t num_elements;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
num_elements = PyLong_AsSsize_t(num_result);
|
||||
#else
|
||||
num_elements = PyInt_AsSsize_t(num_result);
|
||||
#endif
|
||||
Py_DECREF(num_result);
|
||||
|
||||
PyObject *list = PyList_New(num_elements);
|
||||
for (int i = 0; i < num_elements; ++i) {
|
||||
PyObject *element = PyObject_CallMethod(self, (char *)element_name, (char *)"(i)", i);
|
||||
if (element == NULL) {
|
||||
Py_DECREF(list);
|
||||
return NULL;
|
||||
}
|
||||
PyList_SET_ITEM(list, i, element);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: copy_from_make_copy
|
||||
// Description: This is a support function for a synthesized
|
||||
|
|
|
|||
|
|
@ -143,17 +143,17 @@ using namespace std;
|
|||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Dtool_PyTypedObject;
|
||||
typedef std::map<int, Dtool_PyTypedObject *> RunTimeTypeDictionary;
|
||||
typedef std::set<int> RunTimeTypeList;
|
||||
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary();
|
||||
EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList();
|
||||
typedef std::map<int, Dtool_PyTypedObject *> RuntimeTypeMap;
|
||||
typedef std::set<int> RuntimeTypeSet;
|
||||
typedef std::map<std::string, Dtool_PyTypedObject *> NamedTypeMap;
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// used to stamp dtool instance..
|
||||
#define PY_PANDA_SIGNATURE 0xbeaf
|
||||
typedef void *(*UpcastFunction)(PyObject *,Dtool_PyTypedObject *);
|
||||
typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
|
||||
typedef void *(*CoerceFunction)(PyObject *, void *);
|
||||
typedef void (*ModuleClassInitFunction)(PyObject *module);
|
||||
|
||||
//inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type);
|
||||
//inline void Dtool_Deallocate_General(PyObject * self);
|
||||
|
|
@ -196,16 +196,16 @@ struct Dtool_PyTypedObject {
|
|||
// Standard Python Features..
|
||||
PyTypeObject _PyType;
|
||||
|
||||
// My Class Level Features..
|
||||
UpcastFunction _Dtool_UpcastInterface; // The Upcast Function By Slot
|
||||
DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
|
||||
|
||||
// May be TypeHandle::none() to indicate a non-TypedObject class.
|
||||
TypeHandle _type;
|
||||
|
||||
// some convenience functions..
|
||||
inline PyTypeObject &As_PyTypeObject() { return _PyType; };
|
||||
inline PyObject &As_PyObject() { return (PyObject &)_PyType; };
|
||||
ModuleClassInitFunction _Dtool_ModuleClassInit;
|
||||
|
||||
UpcastFunction _Dtool_UpcastInterface; // The Upcast Function By Slot
|
||||
DowncastFunction _Dtool_DowncastInterface; // The Downcast Function By Slot
|
||||
|
||||
CoerceFunction _Dtool_ConstCoerce;
|
||||
CoerceFunction _Dtool_Coerce;
|
||||
};
|
||||
|
||||
// This is now simply a forward declaration. The actual definition is created
|
||||
|
|
@ -217,7 +217,7 @@ struct Dtool_PyTypedObject {
|
|||
// More Macro(s) to Implement class functions.. Usually used if C++ needs type information
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#define Define_Dtool_new(CLASS_NAME,CNAME)\
|
||||
PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
|
||||
static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\
|
||||
(void) args; (void) kwds;\
|
||||
PyObject *self = type->tp_alloc(type, 0);\
|
||||
((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\
|
||||
|
|
@ -291,7 +291,11 @@ EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self);
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject *otype, int class_id);
|
||||
EXPCL_DTOOLCONFIG void RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype);
|
||||
EXPCL_DTOOLCONFIG void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype);
|
||||
|
||||
EXPCL_DTOOLCONFIG Dtool_PyTypedObject *LookupNamedClass(const string &name);
|
||||
EXPCL_DTOOLCONFIG Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -305,7 +309,7 @@ EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
|
|||
// with these as the generated code depends on how this is set
|
||||
// up..
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer);
|
||||
EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
|
||||
|
||||
EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, bool report_errors);
|
||||
|
||||
|
|
@ -407,11 +411,9 @@ template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memo
|
|||
//struct Dtool_PyTypedObject Dtool_##CLASS_NAME;
|
||||
|
||||
#define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
|
||||
extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
|
||||
int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
|
||||
PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
|
||||
void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
|
||||
void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);
|
||||
extern struct Dtool_PyTypedObject Dtool_##CLASS_NAME;\
|
||||
static int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
|
||||
static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\
|
||||
|
|
@ -460,10 +462,7 @@ EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &them
|
|||
/// fallowing structors and code.. along with the support of interigate_module
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct LibraryDef {
|
||||
typedef void (*ConstantFunction)(PyObject *);
|
||||
|
||||
PyMethodDef *_methods;
|
||||
ConstantFunction _constants;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -505,10 +504,6 @@ EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2);
|
|||
|
||||
EXPCL_DTOOLCONFIG PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op);
|
||||
|
||||
EXPCL_DTOOLCONFIG PyObject *
|
||||
make_list_for_item(PyObject *self, const char *num_name,
|
||||
const char *element_name);
|
||||
|
||||
EXPCL_DTOOLCONFIG PyObject *
|
||||
copy_from_make_copy(PyObject *self);
|
||||
|
||||
|
|
@ -527,6 +522,8 @@ PyLongOrInt_FromUnsignedLong(unsigned long value);
|
|||
EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
|
||||
EXPCL_DTOOLCONFIG extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
|
||||
|
||||
#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
|
||||
|
||||
#endif // HAVE_PYTHON && !CPPPARSER
|
||||
|
||||
#endif // PY_PANDA_H_
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ __published:
|
|||
static const openmode in;
|
||||
static const openmode out;
|
||||
static const openmode trunc;
|
||||
protected:
|
||||
// Force this to be a non-trivial type.
|
||||
ios_base() {};
|
||||
};
|
||||
class ios : public ios_base {
|
||||
__published:
|
||||
|
|
|
|||
|
|
@ -1411,7 +1411,10 @@ def CompileImod(wobj, wsrc, opts):
|
|||
# Assume that interrogate_module is on the PATH somewhere.
|
||||
cmd = 'interrogate_module'
|
||||
|
||||
cmd += ' -oc ' + woutc + ' -module ' + module + ' -library ' + library + ' -python-native '
|
||||
cmd += ' -oc ' + woutc + ' -module ' + module + ' -library ' + library + ' -python-native'
|
||||
importmod = GetValueOption(opts, "IMPORT:")
|
||||
if importmod:
|
||||
cmd += ' -import ' + importmod
|
||||
for x in wsrc: cmd += ' ' + BracketNameWithQuotes(x)
|
||||
oscmd(cmd)
|
||||
CompileCxx(wobj,woutc,opts)
|
||||
|
|
@ -1592,20 +1595,13 @@ def CompileLink(dll, obj, opts):
|
|||
cmd = cxx + ' -undefined dynamic_lookup'
|
||||
if ("BUNDLE" in opts): cmd += ' -bundle '
|
||||
else:
|
||||
if GetOrigExt(dll) == ".pyd":
|
||||
install_name = '@loader_path/../panda3d/' + os.path.basename(dll)
|
||||
else:
|
||||
install_name = os.path.basename(dll)
|
||||
install_name = os.path.basename(dll)
|
||||
cmd += ' -dynamiclib -install_name ' + install_name
|
||||
cmd += ' -compatibility_version ' + MAJOR_VERSION + ' -current_version ' + VERSION
|
||||
cmd += ' -o ' + dll + ' -L' + GetOutputDir() + '/lib -L' + GetOutputDir() + '/tmp'
|
||||
else:
|
||||
cmd = cxx + ' -shared'
|
||||
if ("MODULE" not in opts): cmd += " -Wl,-soname=" + os.path.basename(dll)
|
||||
if GetOrigExt(dll) == ".pyd" and not os.path.basename(dll).startswith('core'):
|
||||
# Tell the other libraries where to find core.so.
|
||||
# Not sure if this is the best way to do that, but it works.
|
||||
cmd += " -Wl,-rpath '-Wl,$ORIGIN'"
|
||||
cmd += ' -o ' + dll + ' -L' + GetOutputDir() + '/lib -L' + GetOutputDir() + '/tmp'
|
||||
|
||||
for x in obj:
|
||||
|
|
@ -3856,12 +3852,11 @@ if (PkgSkip("VISION") == 0) and (not RUNTIME):
|
|||
|
||||
TargetAdd('vision_module.obj', input='libp3vision.in')
|
||||
TargetAdd('vision_module.obj', opts=OPTS)
|
||||
TargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision'])
|
||||
TargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('vision.pyd', input='vision_module.obj')
|
||||
TargetAdd('vision.pyd', input='libp3vision_igate.obj')
|
||||
TargetAdd('vision.pyd', input='libp3vision.dll')
|
||||
TargetAdd('vision.pyd', input='core.pyd')
|
||||
TargetAdd('vision.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('vision.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -3887,13 +3882,12 @@ if (PkgSkip("ROCKET") == 0) and (not RUNTIME):
|
|||
|
||||
TargetAdd('rocket_module.obj', input='libp3rocket.in')
|
||||
TargetAdd('rocket_module.obj', opts=OPTS)
|
||||
TargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket'])
|
||||
TargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('rocket.pyd', input='rocket_module.obj')
|
||||
TargetAdd('rocket.pyd', input='libp3rocket_igate.obj')
|
||||
TargetAdd('rocket.pyd', input='p3rocket_rocketRegion_ext.obj')
|
||||
TargetAdd('rocket.pyd', input='libp3rocket.dll')
|
||||
TargetAdd('rocket.pyd', input='core.pyd')
|
||||
TargetAdd('rocket.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('rocket.pyd', opts=['PYTHON', 'ROCKET'])
|
||||
|
||||
|
|
@ -3915,12 +3909,11 @@ if PkgSkip("AWESOMIUM") == 0 and not RUNTIME:
|
|||
|
||||
TargetAdd('awesomium_module.obj', input='libp3awesomium.in')
|
||||
TargetAdd('awesomium_module.obj', opts=OPTS)
|
||||
TargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium'])
|
||||
TargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('awesomium.pyd', input='awesomium_module.obj')
|
||||
TargetAdd('awesomium.pyd', input='libp3awesomium_igate.obj')
|
||||
TargetAdd('awesomium.pyd', input='libp3awesomium.dll')
|
||||
TargetAdd('awesomium.pyd', input='core.pyd')
|
||||
TargetAdd('awesomium.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('awesomium.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -3949,12 +3942,11 @@ if (PkgSkip('SKEL')==0) and (not RUNTIME):
|
|||
TargetAdd('libpandaskel.dll', opts=OPTS)
|
||||
|
||||
TargetAdd('skel_module.obj', input='libp3skel.in')
|
||||
TargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel'])
|
||||
TargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('skel.pyd', input='skel_module.obj')
|
||||
TargetAdd('skel.pyd', input='libp3skel_igate.obj')
|
||||
TargetAdd('skel.pyd', input='libpandaskel.dll')
|
||||
TargetAdd('skel.pyd', input='core.pyd')
|
||||
TargetAdd('skel.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('skel.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -3988,12 +3980,11 @@ if (PkgSkip('PANDAFX')==0) and (not RUNTIME):
|
|||
OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG']
|
||||
TargetAdd('fx_module.obj', input='libp3distort.in')
|
||||
TargetAdd('fx_module.obj', opts=OPTS)
|
||||
TargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx'])
|
||||
TargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('fx.pyd', input='fx_module.obj')
|
||||
TargetAdd('fx.pyd', input='libp3distort_igate.obj')
|
||||
TargetAdd('fx.pyd', input='libpandafx.dll')
|
||||
TargetAdd('fx.pyd', input='core.pyd')
|
||||
TargetAdd('fx.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('fx.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -4016,12 +4007,11 @@ if (PkgSkip("VRPN")==0 and not RUNTIME):
|
|||
|
||||
TargetAdd('vrpn_module.obj', input='libp3vrpn.in')
|
||||
TargetAdd('vrpn_module.obj', opts=OPTS)
|
||||
TargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn'])
|
||||
TargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('vrpn.pyd', input='vrpn_module.obj')
|
||||
TargetAdd('vrpn.pyd', input='libp3vrpn_igate.obj')
|
||||
TargetAdd('vrpn.pyd', input='libp3vrpn.dll')
|
||||
TargetAdd('vrpn.pyd', input='core.pyd')
|
||||
TargetAdd('vrpn.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('vrpn.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -4249,14 +4239,13 @@ if (not RUNTIME):
|
|||
TargetAdd('egg_module.obj', input='libp3egg2pg.in')
|
||||
TargetAdd('egg_module.obj', input='libp3egg.in')
|
||||
TargetAdd('egg_module.obj', opts=OPTS)
|
||||
TargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg'])
|
||||
TargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('egg.pyd', input='egg_module.obj')
|
||||
TargetAdd('egg.pyd', input='p3egg_eggGroupNode_ext.obj')
|
||||
TargetAdd('egg.pyd', input='libp3egg_igate.obj')
|
||||
TargetAdd('egg.pyd', input='libp3egg2pg_igate.obj')
|
||||
TargetAdd('egg.pyd', input='libpandaegg.dll')
|
||||
TargetAdd('egg.pyd', input='core.pyd')
|
||||
TargetAdd('egg.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('egg.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -4416,13 +4405,12 @@ if (PkgSkip("ODE")==0 and not RUNTIME):
|
|||
OPTS=['DIR:panda/metalibs/pandaode', 'ODE']
|
||||
TargetAdd('ode_module.obj', input='libpandaode.in')
|
||||
TargetAdd('ode_module.obj', opts=OPTS)
|
||||
TargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode'])
|
||||
TargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('ode.pyd', input='ode_module.obj')
|
||||
TargetAdd('ode.pyd', input='libpandaode_igate.obj')
|
||||
TargetAdd('ode.pyd', input='p3ode_ext_composite.obj')
|
||||
TargetAdd('ode.pyd', input='libpandaode.dll')
|
||||
TargetAdd('ode.pyd', input='core.pyd')
|
||||
TargetAdd('ode.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('ode.pyd', opts=['PYTHON', 'WINUSER', 'ODE'])
|
||||
|
||||
|
|
@ -4454,12 +4442,11 @@ if (PkgSkip("BULLET")==0 and not RUNTIME):
|
|||
OPTS=['DIR:panda/metalibs/pandabullet', 'BULLET']
|
||||
TargetAdd('bullet_module.obj', input='libpandabullet.in')
|
||||
TargetAdd('bullet_module.obj', opts=OPTS)
|
||||
TargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet'])
|
||||
TargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('bullet.pyd', input='bullet_module.obj')
|
||||
TargetAdd('bullet.pyd', input='libpandabullet_igate.obj')
|
||||
TargetAdd('bullet.pyd', input='libpandabullet.dll')
|
||||
TargetAdd('bullet.pyd', input='core.pyd')
|
||||
TargetAdd('bullet.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('bullet.pyd', opts=['PYTHON', 'WINUSER', 'BULLET'])
|
||||
|
||||
|
|
@ -4493,12 +4480,11 @@ if (PkgSkip("PHYSX")==0):
|
|||
OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC']
|
||||
TargetAdd('physx_module.obj', input='libpandaphysx.in')
|
||||
TargetAdd('physx_module.obj', opts=OPTS)
|
||||
TargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx'])
|
||||
TargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('physx.pyd', input='physx_module.obj')
|
||||
TargetAdd('physx.pyd', input='libpandaphysx_igate.obj')
|
||||
TargetAdd('physx.pyd', input='libpandaphysx.dll')
|
||||
TargetAdd('physx.pyd', input='core.pyd')
|
||||
TargetAdd('physx.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('physx.pyd', opts=['PYTHON', 'WINUSER', 'PHYSX', 'NOARCH:PPC'])
|
||||
|
||||
|
|
@ -4559,14 +4545,13 @@ if (PkgSkip("PANDAPHYSICS")==0) and (not RUNTIME):
|
|||
if (PkgSkip("PANDAPARTICLESYSTEM")==0):
|
||||
TargetAdd('physics_module.obj', input='libp3particlesystem.in')
|
||||
TargetAdd('physics_module.obj', opts=OPTS)
|
||||
TargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics'])
|
||||
TargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('physics.pyd', input='physics_module.obj')
|
||||
TargetAdd('physics.pyd', input='libp3physics_igate.obj')
|
||||
if (PkgSkip("PANDAPARTICLESYSTEM")==0):
|
||||
TargetAdd('physics.pyd', input='libp3particlesystem_igate.obj')
|
||||
TargetAdd('physics.pyd', input='libpandaphysics.dll')
|
||||
TargetAdd('physics.pyd', input='core.pyd')
|
||||
TargetAdd('physics.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('physics.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
@ -4816,7 +4801,7 @@ if (PkgSkip("DIRECT")==0):
|
|||
TargetAdd('direct_module.obj', input='libp3interval.in')
|
||||
TargetAdd('direct_module.obj', input='libp3distributed.in')
|
||||
TargetAdd('direct_module.obj', opts=OPTS)
|
||||
TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct'])
|
||||
TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('direct.pyd', input='libp3dcparser_igate.obj')
|
||||
TargetAdd('direct.pyd', input='libp3showbase_igate.obj')
|
||||
|
|
@ -4826,7 +4811,6 @@ if (PkgSkip("DIRECT")==0):
|
|||
|
||||
TargetAdd('direct.pyd', input='direct_module.obj')
|
||||
TargetAdd('direct.pyd', input='libp3direct.dll')
|
||||
TargetAdd('direct.pyd', input='core.pyd')
|
||||
TargetAdd('direct.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('direct.pyd', opts=['PYTHON', 'OPENSSL', 'WINUSER', 'WINGDI'])
|
||||
|
||||
|
|
@ -6026,12 +6010,11 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME):
|
|||
|
||||
TargetAdd('ai_module.obj', input='libpandaai.in')
|
||||
TargetAdd('ai_module.obj', opts=OPTS)
|
||||
TargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai'])
|
||||
TargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai', 'IMPORT:panda3d.core'])
|
||||
|
||||
TargetAdd('ai.pyd', input='ai_module.obj')
|
||||
TargetAdd('ai.pyd', input='libpandaai_igate.obj')
|
||||
TargetAdd('ai.pyd', input='libpandaai.dll')
|
||||
TargetAdd('ai.pyd', input='core.pyd')
|
||||
TargetAdd('ai.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('ai.pyd', opts=['PYTHON'])
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class BulletShape;
|
|||
class EXPCL_PANDABULLET BulletRigidBodyNode : public BulletBodyNode {
|
||||
|
||||
PUBLISHED:
|
||||
BulletRigidBodyNode(const char *name="rigid");
|
||||
explicit BulletRigidBodyNode(const char *name="rigid");
|
||||
INLINE ~BulletRigidBodyNode();
|
||||
|
||||
// Mass & inertia
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "luse.h"
|
||||
#include "globPattern.h"
|
||||
#include "plist.h"
|
||||
#include "bamCacheRecord.h"
|
||||
|
||||
class EggTextureCollection;
|
||||
class EggMaterialCollection;
|
||||
|
|
@ -33,7 +34,6 @@ class EggPolygon;
|
|||
class EggVertex;
|
||||
class EggVertexPool;
|
||||
class DSearchPath;
|
||||
class BamCacheRecord;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggGroupNode
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
#if defined(HAVE_PYTHON) && defined(DO_MEMORY_USAGE)
|
||||
|
||||
#ifndef CPPPARSER
|
||||
extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedObject;
|
||||
extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_TypedReferenceCount;
|
||||
extern EXPCL_PANDAEXPRESS Dtool_PyTypedObject Dtool_ReferenceCount;
|
||||
extern Dtool_PyTypedObject Dtool_TypedObject;
|
||||
extern Dtool_PyTypedObject Dtool_TypedReferenceCount;
|
||||
extern Dtool_PyTypedObject Dtool_ReferenceCount;
|
||||
#endif // CPPPARSER
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -45,6 +45,19 @@ operator = (const Namable &other) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Namable::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Namable &Namable::
|
||||
operator = (Namable &&other) NOEXCEPT {
|
||||
_name = MOVE(other._name);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Namable::set_name
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -28,10 +28,14 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS Namable : public MemoryBase {
|
||||
PUBLISHED:
|
||||
INLINE Namable(const string &initial_name = "");
|
||||
INLINE explicit Namable(const string &initial_name = "");
|
||||
INLINE Namable(const Namable ©);
|
||||
INLINE Namable &operator = (const Namable &other);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Namable &operator = (Namable &&other) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE void set_name(const string &name);
|
||||
INLINE void clear_name();
|
||||
INLINE bool has_name() const;
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ protected:
|
|||
virtual PT(CopyOnWriteObject) make_cow_copy();
|
||||
|
||||
PUBLISHED:
|
||||
Geom(const GeomVertexData *data);
|
||||
explicit Geom(const GeomVertexData *data);
|
||||
|
||||
protected:
|
||||
Geom(const Geom ©);
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ protected:
|
|||
virtual PT(CopyOnWriteObject) make_cow_copy();
|
||||
|
||||
PUBLISHED:
|
||||
GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
|
||||
UsageHint usage_hint);
|
||||
explicit GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
|
||||
UsageHint usage_hint);
|
||||
GeomVertexArrayData(const GeomVertexArrayData ©);
|
||||
void operator = (const GeomVertexArrayData ©);
|
||||
virtual ~GeomVertexArrayData();
|
||||
|
|
|
|||
|
|
@ -80,12 +80,12 @@ protected:
|
|||
virtual PT(CopyOnWriteObject) make_cow_copy();
|
||||
|
||||
PUBLISHED:
|
||||
GeomVertexData(const string &name,
|
||||
const GeomVertexFormat *format,
|
||||
UsageHint usage_hint);
|
||||
explicit GeomVertexData(const string &name,
|
||||
const GeomVertexFormat *format,
|
||||
UsageHint usage_hint);
|
||||
GeomVertexData(const GeomVertexData ©);
|
||||
GeomVertexData(const GeomVertexData ©,
|
||||
const GeomVertexFormat *format);
|
||||
explicit GeomVertexData(const GeomVertexData ©,
|
||||
const GeomVertexFormat *format);
|
||||
void operator = (const GeomVertexData ©);
|
||||
virtual ~GeomVertexData();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexData);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "pnmImage.h"
|
||||
#include "colorSpace.h"
|
||||
#include "geomEnums.h"
|
||||
#include "bamCacheRecord.h"
|
||||
|
||||
class PNMImage;
|
||||
class PfmFile;
|
||||
|
|
@ -51,7 +52,6 @@ class FactoryParams;
|
|||
class PreparedGraphicsObjects;
|
||||
class CullTraverser;
|
||||
class CullTraverserData;
|
||||
class BamCacheRecord;
|
||||
class TexturePeeker;
|
||||
struct DDSHeader;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class FactoryParams;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ TextureStage : public TypedWritableReferenceCount {
|
||||
PUBLISHED:
|
||||
TextureStage(const string &name);
|
||||
explicit TextureStage(const string &name);
|
||||
INLINE TextureStage(TextureStage ©);
|
||||
void operator = (const TextureStage ©);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@
|
|||
#include "odeSpace_ext.h"
|
||||
#include "lpoint3.h"
|
||||
|
||||
#ifndef CPPPARSER
|
||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_LPoint3f;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OdeGeom::get_AA_bounds
|
||||
// Access: Published
|
||||
|
|
@ -30,8 +26,8 @@ get_AA_bounds() const {
|
|||
LPoint3f *max_point = new LPoint3f;
|
||||
_this->get_AABB(*min_point, *max_point);
|
||||
|
||||
PyObject *min_inst = DTool_CreatePyInstance((void*) min_point, Dtool_LPoint3f, true, false);
|
||||
PyObject *max_inst = DTool_CreatePyInstance((void*) max_point, Dtool_LPoint3f, true, false);
|
||||
PyObject *min_inst = DTool_CreatePyInstance(min_point, true);
|
||||
PyObject *max_inst = DTool_CreatePyInstance(max_point, true);
|
||||
return Py_BuildValue("NN", min_inst, max_inst);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@
|
|||
/* okcircular */
|
||||
#include "odeGeom_ext.h"
|
||||
|
||||
#ifndef CPPPARSER
|
||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_LPoint3f;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: OdeSpace::get_AA_bounds
|
||||
// Access: Published
|
||||
|
|
@ -30,8 +26,8 @@ get_AA_bounds() const {
|
|||
LPoint3f *max_point = new LPoint3f;
|
||||
_this->get_AABB(*min_point, *max_point);
|
||||
|
||||
PyObject *min_inst = DTool_CreatePyInstance((void*) min_point, Dtool_LPoint3f, true, false);
|
||||
PyObject *max_inst = DTool_CreatePyInstance((void*) max_point, Dtool_LPoint3f, true, false);
|
||||
PyObject *min_inst = DTool_CreatePyInstance(min_point, true);
|
||||
PyObject *max_inst = DTool_CreatePyInstance(max_point, true);
|
||||
return Py_BuildValue("NN", min_inst, max_inst);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PGRAPH Camera : public LensNode {
|
||||
PUBLISHED:
|
||||
Camera(const string &name, Lens *lens = new PerspectiveLens());
|
||||
explicit Camera(const string &name, Lens *lens = new PerspectiveLens());
|
||||
Camera(const Camera ©);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ PUBLISHED:
|
|||
INLINE explicit NodePath(const string &top_node_name, Thread *current_thread = Thread::get_current_thread());
|
||||
INLINE explicit NodePath(PandaNode *node, Thread *current_thread = Thread::get_current_thread());
|
||||
INLINE static NodePath any_path(PandaNode *node, Thread *current_thread = Thread::get_current_thread());
|
||||
NodePath(const NodePath &parent, PandaNode *child_node,
|
||||
Thread *current_thread = Thread::get_current_thread());
|
||||
explicit NodePath(const NodePath &parent, PandaNode *child_node,
|
||||
Thread *current_thread = Thread::get_current_thread());
|
||||
|
||||
INLINE NodePath(const NodePath ©);
|
||||
INLINE void operator = (const NodePath ©);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class GraphicsStateGuardianBase;
|
|||
class EXPCL_PANDA_PGRAPH PandaNode : public TypedWritableReferenceCount,
|
||||
public Namable, public LinkedListNode {
|
||||
PUBLISHED:
|
||||
PandaNode(const string &name);
|
||||
explicit PandaNode(const string &name);
|
||||
virtual ~PandaNode();
|
||||
//published so that characters can be combined.
|
||||
virtual PandaNode *combine_with(PandaNode *other);
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ class PNMFileType;
|
|||
class EXPCL_PANDA_PNMIMAGE PNMImage : public PNMImageHeader {
|
||||
PUBLISHED:
|
||||
INLINE PNMImage();
|
||||
PNMImage(const Filename &filename, PNMFileType *type = NULL);
|
||||
INLINE PNMImage(int x_size, int y_size, int num_channels = 3,
|
||||
xelval maxval = 255, PNMFileType *type = NULL,
|
||||
ColorSpace color_space = CS_linear);
|
||||
explicit PNMImage(const Filename &filename, PNMFileType *type = NULL);
|
||||
INLINE explicit PNMImage(int x_size, int y_size, int num_channels = 3,
|
||||
xelval maxval = 255, PNMFileType *type = NULL,
|
||||
ColorSpace color_space = CS_linear);
|
||||
INLINE PNMImage(const PNMImage ©);
|
||||
INLINE void operator = (const PNMImage ©);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@ typedef unsigned char gray;
|
|||
struct pixel {
|
||||
PUBLISHED:
|
||||
pixel() { }
|
||||
pixel(gray fill) : r(fill), g(fill), b(fill) { }
|
||||
pixel(gray r, gray g, gray b) : r(r), g(g), b(b) { }
|
||||
static int size() { return 3; }
|
||||
|
||||
gray operator [](int i) const { nassertr(i >= 0 && i < 3, 0); return *(&r + i); }
|
||||
gray &operator [](int i) { nassertr(i >= 0 && i < 3, r); return *(&r + i); }
|
||||
pixel operator + (const pixel &other) const
|
||||
|
|
@ -60,6 +61,7 @@ PUBLISHED:
|
|||
{ r *= mult; g *= mult; b *= mult; }
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
static int size() { return 3; }
|
||||
void output(ostream &out) {
|
||||
out << "pixel(r=" << r << ", g=" << g << ", b=" << b << ")";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Thread;
|
|||
// with Panda's Thread instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PSTATCLIENT PStatThread {
|
||||
private:
|
||||
public:
|
||||
INLINE PStatThread();
|
||||
|
||||
PUBLISHED:
|
||||
|
|
|
|||
Loading…
Reference in New Issue