diff --git a/direct/src/interval/IntervalManager.py b/direct/src/interval/IntervalManager.py index 3ceded278c..3bc3236568 100644 --- a/direct/src/interval/IntervalManager.py +++ b/direct/src/interval/IntervalManager.py @@ -27,7 +27,7 @@ class IntervalManager(CIntervalManager): ##self.dd = self if globalPtr: self.cObj = CIntervalManager.getGlobalPtr() - Dtool_BarrowThisRefrence(self, self.cObj) + Dtool_BorrowThisReference(self, self.cObj) self.dd = self else: CIntervalManager.__init__(self) diff --git a/dtool/src/interrogate/functionRemap.cxx b/dtool/src/interrogate/functionRemap.cxx index 6f25eef7cf..9265c85b52 100644 --- a/dtool/src/interrogate/functionRemap.cxx +++ b/dtool/src/interrogate/functionRemap.cxx @@ -47,6 +47,7 @@ FunctionRemap(const InterrogateType &itype, const InterrogateFunction &ifunc, _void_return = true; _ForcedVoidReturn = false; _has_this = false; + _const_method = false; _first_true_parameter = 0; _num_default_parameters = num_default_parameters; _type = T_normal; @@ -444,6 +445,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak // If this is a method, but not a static method, and not a // constructor, then we need a "this" parameter. _has_this = true; + _const_method = (_ftype->_flags & CPPFunctionType::F_const_method) != 0; if (interface_maker->synthesize_this_parameter()) { // If the interface_maker demands it, the "this" parameter is treated @@ -452,8 +454,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak Parameter param; param._name = "this"; param._has_name = true; - bool is_const = (_ftype->_flags & CPPFunctionType::F_const_method) != 0; - param._remap = new ParameterRemapThis(_cpptype, is_const); + param._remap = new ParameterRemapThis(_cpptype, _const_method); _parameters.push_back(param); _first_true_parameter = 1; } diff --git a/dtool/src/interrogate/functionRemap.h b/dtool/src/interrogate/functionRemap.h index 1a523517e0..c57f5318ad 100644 --- a/dtool/src/interrogate/functionRemap.h +++ b/dtool/src/interrogate/functionRemap.h @@ -89,6 +89,7 @@ public: bool _void_return; bool _ForcedVoidReturn; bool _has_this; + bool _const_method; int _first_true_parameter; int _num_default_parameters; Type _type; diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 21f79a601e..647ae63832 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -411,7 +411,7 @@ void InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string // Function : WriteReturnInstance // /////////////////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace) +void InterfaceMakerPythonNative::WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag) { if(inplace == true) { @@ -430,15 +430,14 @@ void InterfaceMakerPythonNative::WriteReturnInstance(ostream &out, int indent_le if(IsPandaTypedObject(ctype->as_struct_type())) { std::string typestr = "(" + return_expr + ")->as_typed_object()->get_type_index()"; - - indent(out, indent_level)<<"return DTool_CreatePyInstanceTyped((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<< ows_memory_flag<<","<_remaps[0]->_cppfunc->get_local_name(&parser) + << methodNameFromCppName(func, "") << "() takes "; // We add one to the parameter count for "self", following the @@ -1920,7 +1919,7 @@ std::vector< FunctionRemap * > SortFunctionSet(std::set< FunctionRemap *> &rema /////////////////////////////////////////////////////////// // Function : write_function_forset // -// A set is defined as all rempas that have the same number of paramaters.. +// A set is defined as all remaps that have the same number of paramaters.. /////////////////////////////////////////////////////////// void InterfaceMakerPythonNative::write_function_forset(ostream &out, InterfaceMaker::Function *func, std::set< FunctionRemap *> &remapsin, string &expected_params, int indent_level,ostream &forward_decl, const std::string &functionname, bool is_inplace) @@ -1937,8 +1936,17 @@ void InterfaceMakerPythonNative::write_function_forset(ostream &out, InterfaceMa FunctionRemap *remap = (*sii); if(isRemapLegal(*remap)) { + if (remap->_has_this && !remap->_const_method) { + // If it's a non-const method, we only allow a + // non-const this. + indent(out,indent_level) + << "if (!((Dtool_PyInstDef *)self)->_is_const) {\n"; + } else { + indent(out, indent_level) + << "{\n"; + } - indent(out,indent_level)<< "{ // -2 " ; + indent(out,indent_level) << " // -2 " ; remap->write_orig_prototype(out, 0); out << "\n" ; write_function_instance(out, func, remap,expected_params,indent_level+4,false,forward_decl, func->_name, is_inplace); @@ -1954,13 +1962,40 @@ void InterfaceMakerPythonNative::write_function_forset(ostream &out, InterfaceMa for(sii = remapsin.begin(); sii != remapsin.end(); sii ++) { FunctionRemap *remap = (*sii); - if(isRemapLegal(*remap)) - { + if(isRemapLegal(*remap)) { + if (remap->_has_this && !remap->_const_method) { + // If it's a non-const method, we only allow a + // non-const this. + indent(out, indent_level) + << "if (!((Dtool_PyInstDef *)self)->_is_const) {\n"; + } else { + indent(out, indent_level) + << "{\n"; + } - indent(out,indent_level)<< "// 1-" ;remap->write_orig_prototype(out, 0); out << "\n" ; -// indent(out,indent_level)<< "do{\n"; - write_function_instance(out, func, remap,expected_params,indent_level+4,true,forward_decl, func->_name, is_inplace); - // indent(out,indent_level)<< "}while(false);\n"; + indent(out,indent_level + 2) + << "// 1-" ;remap->write_orig_prototype(out, 0); out << "\n" ; + write_function_instance(out, func, remap,expected_params,indent_level+4,true,forward_decl, func->_name, is_inplace); + + if (remap->_has_this && !remap->_const_method) { + indent(out, indent_level) + << "} else {\n"; + indent(out, indent_level + 2) + << "PyErr_SetString(PyExc_TypeError,\n"; + string class_name = remap->_cpptype->get_simple_name(); + indent(out, indent_level + 2) + << " \"Cannot call " + << classNameFromCppName(class_name) + << "." << methodNameFromCppName(func, class_name) + << "() on a const object.\");\n"; + indent(out, indent_level + 2) + << "return (PyObject *) NULL;\n"; + indent(out,indent_level) + << "}\n\n"; + } else { + indent(out,indent_level) + << "}\n\n"; + } } } } @@ -1997,7 +2032,7 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface // simultaneously building the ParseTuple() function call and also // the parameter expression list for call_function(). - expected_params += remap->_cppfunc->get_simple_name(); + expected_params += methodNameFromCppName(func1, ""); expected_params += "("; int pn; @@ -2098,7 +2133,7 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface indent(out,indent_level) << "double " << param_name; format_specifiers += "d"; parameter_list += ", &" + param_name; - expected_params += "float "; + expected_params += "float"; } else if (TypeManager::is_char_pointer(type)) { indent(out,indent_level) << "char *" << param_name; @@ -2112,10 +2147,19 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface parameter_list += ", &" + param_name; pexpr_string = param_name; pname_for_pyobject += param_name; - expected_params += "PyObject"; + expected_params += "any"; } else if (TypeManager::is_pointer(type)) { - expected_params += type->get_preferred_name(); + CPPType *obj_type = TypeManager::unwrap(TypeManager::resolve_type(type)); + bool const_ok = !TypeManager::is_non_const_pointer_or_ref(orig_type); + + if (const_ok) { + expected_params += "const "; + } else { + expected_params += "non-const "; + } + expected_params += classNameFromCppName(obj_type->get_simple_name()); + if (!remap->_has_this || pn != 0) { indent(out, indent_level) << "PyObject *" << param_name; @@ -2123,7 +2167,7 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface parameter_list += ", &" + param_name; pname_for_pyobject += param_name; - TypeIndex p_type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false); + TypeIndex p_type_index = builder.get_type(obj_type,false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &p_itype = idb->get_type(p_type_index); @@ -2135,12 +2179,19 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(p_itype.get_scoped_name()) << ";\n"; } + string class_name; + string method_prefix; + if (remap->_cpptype) { + class_name = remap->_cpptype->get_simple_name(); + method_prefix = classNameFromCppName(class_name) + string("."); + } + ostringstream str; str << "DTOOL_Call_GetPointerThisClass(" << param_name << ", &Dtool_" << make_safe_name(p_itype.get_scoped_name()) << ", " << pn << ", \"" - << remap->_cppfunc->get_local_name(&parser) - << "\");\n"; + << method_prefix << methodNameFromCppName(func1, class_name) + << "\", " << const_ok << ");\n"; extra_convert += str.str(); extra_param_check += "|| (" + param_name + "_this == NULL)"; @@ -2173,7 +2224,8 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface // If we got what claimed to be a unary operator, don't check for // parameters, since we won't be getting any anyway. if (!func1->_ifunc.is_unary_op()) { - std::string format_specifiers1 = format_specifiers + ":" + remap->_cppfunc->get_local_name(&parser); + std::string format_specifiers1 = format_specifiers + ":" + + methodNameFromCppName(func1, ""); indent(out,indent_level) << "static char * key_word_list[] = {" << keyword_list << "NULL};\n"; @@ -2343,6 +2395,13 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve } else if (TypeManager::is_pointer(type)) { + string const_flag; + if (TypeManager::is_const_pointer_to_anything(type)) { + const_flag = "true"; + } else { + const_flag = "false"; + } + if (TypeManager::is_struct(orig_type) || TypeManager::is_ref_to_anything(orig_type)) { if( TypeManager::is_ref_to_anything(orig_type)) @@ -2352,10 +2411,10 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve const InterrogateType &itype = idb->get_type(type_index); std::string ows_memory_flag("true"); - if(remap->_return_value_needs_management) - ows_memory_flag = "true"; + if(remap->_return_value_needs_management) + ows_memory_flag = "true"; else - ows_memory_flag = "false"; + ows_memory_flag = "false"; if(!isExportThisRun(itype._cpptype)) { @@ -2363,9 +2422,7 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; } - WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace); - // indent(out, indent_level) - // <<"return DTool_CreatePyInstance((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) << ","<get_type(type_index); indent(out, indent_level) - <<"return DTool_PyInit_Finalize(self, " << return_expr <<",&"< &answer, CPPStructType * inclass, const std::string &up_cast_seed = "", bool downcastposible = true); bool DoesInheritFromIsClass( const CPPStructType * inclass, const std::string &name); bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); }; - void WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag,const std::string &class_name, CPPType *ctype, bool inplace); + void WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag,const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag); bool HasAGetKeyFunction(const InterrogateType &itype_class); int NeedsAStrFunction(const InterrogateType &itype_class); int NeedsAReprFunction(const InterrogateType &itype_class); diff --git a/dtool/src/interrogate/parameterRemapThis.cxx b/dtool/src/interrogate/parameterRemapThis.cxx index c2e1bcb30f..7b91cd1709 100644 --- a/dtool/src/interrogate/parameterRemapThis.cxx +++ b/dtool/src/interrogate/parameterRemapThis.cxx @@ -38,6 +38,7 @@ ParameterRemapThis(CPPType *type, bool is_const) : } else { _new_type = TypeManager::wrap_pointer(type); } + _orig_type = _new_type; } //////////////////////////////////////////////////////////////////// diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index ac343ab4dd..2967bdd7c8 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -166,6 +166,49 @@ is_const_ref_to_anything(CPPType *type) { } } +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_const_pointer_to_anything +// Access: Public, Static +// Description: Returns true if the indicated type is a const +// pointer to something, false otherwise. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_const_pointer_to_anything(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_const_pointer_to_anything(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_pointer: + return is_const(type->as_pointer_type()->_pointing_at); + + default: + return false; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_non_const_pointer_or_ref +// Access: Public, Static +// Description: Returns true if the indicated type is a non-const +// pointer or reference to something, false otherwise. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_non_const_pointer_or_ref(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_non_const_pointer_or_ref(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_pointer: + return !is_const(type->as_pointer_type()->_pointing_at); + + case CPPDeclaration::ST_reference: + return !is_const(type->as_reference_type()->_pointing_at); + + default: + return false; + } +} + //////////////////////////////////////////////////////////////////// // Function: TypeManager::is_pointer // Access: Public, Static @@ -1586,13 +1629,13 @@ bool TypeManager::IsExported(CPPType *in_type) if (type->get_subtype() == CPPDeclaration::ST_struct) { CPPStructType *struct_type =type->as_type()->resolve_type(&parser, &parser)->as_struct_type(); - CPPScope *scope = struct_type->_scope; + //CPPScope *scope = struct_type->_scope; return IsExported(struct_type); } else if (type->get_subtype() == CPPDeclaration::ST_enum) { - CPPEnumType *enum_type = type->as_type()->resolve_type(&parser, &parser)->as_enum_type(); + //CPPEnumType *enum_type = type->as_type()->resolve_type(&parser, &parser)->as_enum_type(); if (type->_vis <= min_vis) return true; } diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index ecc112e9c7..0f99edca61 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -53,6 +53,8 @@ public: static bool is_reference(CPPType *type); static bool is_ref_to_anything(CPPType *type); static bool is_const_ref_to_anything(CPPType *type); + static bool is_const_pointer_to_anything(CPPType *type); + static bool is_non_const_pointer_or_ref(CPPType *type); static bool is_pointer(CPPType *type); static bool is_const(CPPType *type); static bool is_struct(CPPType *type); diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index e5e6ac8f72..3b662cbfbe 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -22,11 +22,12 @@ #ifdef HAVE_PYTHON PyMemberDef standard_type_members[] = { - {"this", T_INT, offsetof(Dtool_PyInstDef,_ptr_to_object),READONLY,"C++ This if any"}, - {"this_ownership", T_INT, offsetof(Dtool_PyInstDef, _memory_rules), READONLY,"C++ 'this' ownership rules"}, - {"this_signiture", T_INT, offsetof(Dtool_PyInstDef, _signiture), READONLY,"A type check signiture"}, - {"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY,"The dtool meta object"}, - {NULL} /* Sentinel */ + {"this", T_INT, offsetof(Dtool_PyInstDef,_ptr_to_object),READONLY,"C++ This if any"}, + {"this_ownership", T_INT, offsetof(Dtool_PyInstDef, _memory_rules), READONLY,"C++ 'this' ownership rules"}, + {"this_const", T_INT, offsetof(Dtool_PyInstDef, _is_const), READONLY,"C++ 'this' const flag"}, + {"this_signature", T_INT, offsetof(Dtool_PyInstDef, _signature), READONLY,"A type check signature"}, + {"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY,"The dtool meta object"}, + {NULL} /* Sentinel */ }; @@ -39,7 +40,7 @@ bool DtoolCanThisBeAPandaInstance(PyObject *self) if(self->ob_type->tp_basicsize >= (int)sizeof(Dtool_PyInstDef)) { Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self; - if(pyself->_signiture == PY_PANDA_SIGNITURE) + if(pyself->_signature == PY_PANDA_SIGNATURE) return true; } return false; @@ -47,8 +48,8 @@ bool DtoolCanThisBeAPandaInstance(PyObject *self) //////////////////////////////////////////////////////////////////////// // Function : DTOOL_Call_ExtractThisPointerForType // -// These are the rapers that allow for down and upcast from type .. -// needed by the Dtool py interface.. Be very carefull if you muck with these +// These are the wrappers that allow for down and upcast from type .. +// needed by the Dtool py interface.. Be very careful if you muck with these // as the generated code depends on how this is set up.. //////////////////////////////////////////////////////////////////////// void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer) @@ -61,25 +62,58 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, - int param, const string &function_name) { + int param, const string &function_name, bool const_ok) { if (self != NULL) { if (DtoolCanThisBeAPandaInstance(self)) { Dtool_PyTypedObject *my_type = ((Dtool_PyInstDef *)self)->_My_Type; void *result = my_type->_Dtool_UpcastInterface(self, classdef); if (result != NULL) { - return result; - } + if (const_ok || !((Dtool_PyInstDef *)self)->_is_const) { + return result; + } - ostringstream str; - str << function_name << "() argument " << param << " must be " - << classdef->_name << ", not " << my_type->_name; - string msg = str.str(); - PyErr_SetString(PyExc_TypeError, msg.c_str()); + ostringstream str; + str << function_name << "() argument " << param << " may not be const"; + string msg = str.str(); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + + } else { + ostringstream str; + str << function_name << "() argument " << param << " must be "; + + + PyObject *fname = PyObject_GetAttrString((PyObject *)classdef->_PyType.ob_type, "__name__"); + if (fname != (PyObject *)NULL) { + str << PyString_AsString(fname); + Py_DECREF(fname); + } else { + str << classdef->_name; + } + + PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__"); + if (tname != (PyObject *)NULL) { + str << ", not " << PyString_AsString(tname); + Py_DECREF(tname); + } else { + str << ", not " << my_type->_name; + } + + string msg = str.str(); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + } } else { ostringstream str; - str << function_name << "() argument " << param << " must be " - << classdef->_name; + str << function_name << "() argument " << param << " must be "; + + PyObject *fname = PyObject_GetAttrString((PyObject *)classdef->_PyType.ob_type, "__name__"); + if (fname != (PyObject *)NULL) { + str << PyString_AsString(fname); + Py_DECREF(fname); + } else { + str << classdef->_name; + } + PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__"); if (tname != (PyObject *)NULL) { str << ", not " << PyString_AsString(tname); @@ -116,7 +150,7 @@ void * DTOOL_Call_GetPointerThis(PyObject *self) // this function relies on the behavior of typed objects in the panda system. // //////////////////////////////////////////////////////////////////////// -PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, int RunTimeType) +PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) { if(local_this_in == NULL ) { @@ -149,7 +183,8 @@ PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject { self->_ptr_to_object = new_local_this; self->_memory_rules = memory_rules; - self->_signiture = PY_PANDA_SIGNITURE; + self->_is_const = is_const; + self->_signature = PY_PANDA_SIGNATURE; self->_My_Type = target_class; return (PyObject *)self; } @@ -166,7 +201,8 @@ PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject { self->_ptr_to_object = local_this_in; self->_memory_rules = memory_rules; - self->_signiture = PY_PANDA_SIGNITURE; + self->_is_const = is_const; + self->_signature = PY_PANDA_SIGNATURE; self->_My_Type = &known_class_type; } return (PyObject *)self; @@ -176,7 +212,7 @@ PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject // DTool_CreatePyInstance .. wrapper function to finalize the existance of a general // dtool py instance.. //////////////////////////////////////////////////////////////////////// -PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_classdef, bool memory_rules) +PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_classdef, bool memory_rules, bool is_const) { if(local_this == NULL) { @@ -190,6 +226,7 @@ PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_cl { self->_ptr_to_object = local_this; self->_memory_rules = memory_rules; + self->_is_const = is_const; self->_My_Type = classdef; } return (PyObject *)self; @@ -198,7 +235,7 @@ PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_cl /////////////////////////////////////////////////////////////////////////////// /// Th Finalizer for simple instances.. /////////////////////////////////////////////////////////////////////////////// -int DTool_PyInit_Finalize(PyObject * self, void * This, Dtool_PyTypedObject *type, bool memory_rules) +int DTool_PyInit_Finalize(PyObject * self, void * This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) { // lets put some code in here that checks to see the memory is properly configured.. // prior to my call .. @@ -206,6 +243,7 @@ int DTool_PyInit_Finalize(PyObject * self, void * This, Dtool_PyTypedObject *ty ((Dtool_PyInstDef *)self)->_My_Type = type; ((Dtool_PyInstDef *)self)->_ptr_to_object = This; ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; + ((Dtool_PyInstDef *)self)->_is_const = is_const; return 0; } @@ -313,12 +351,12 @@ void Dtool_PyModuleInitHelper( LibrayDef *defs[], char * modulename) /////////////////////////////////////////////////////////////////////////////// /// HACK.... Be carefull // -// Dtool_BarrowThisRefrence +// Dtool_BorrowThisReference // This function can be used to grab the "THIS" pointer from an object and use it -// Required to support fom historical inharatence in the for of "is this instance of".. +// Required to support historical inheritance in the form of "is this instance of".. // /////////////////////////////////////////////////////////////////////////////// -PyObject * Dtool_BarrowThisRefrence(PyObject * self, PyObject * args ) +PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args ) { PyObject *from_in = NULL; PyObject *to_in = NULL; @@ -332,13 +370,14 @@ PyObject * Dtool_BarrowThisRefrence(PyObject * self, PyObject * args ) if(from->_My_Type == to->_My_Type) { to->_memory_rules = false; + to->_is_const = from->_is_const; to->_ptr_to_object = from->_ptr_to_object; return Py_BuildValue(""); } PyErr_SetString(PyExc_TypeError, "Must Be Same Type??"); } else - PyErr_SetString(PyExc_TypeError, "One of thesee does not appear to be DTOOL Instance ??"); + PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??"); } return (PyObject *) NULL; } @@ -446,7 +485,7 @@ int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2) }; // CompareTo Failed some how :( - // do a this compare .. if Posible... + // do a this compare .. if Possible... if(v1_this < v2_this) return -1; diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index ee9e5b3795..04f462cced 100755 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -84,7 +84,7 @@ EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList(); ////////////////////////////////////////////////////////// // used to stamp dtool instance.. -#define PY_PANDA_SIGNITURE 0xdeadbeaf +#define PY_PANDA_SIGNATURE 0xdeadbeaf typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * ); typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *); typedef void ( *FreeFunction )(PyObject *); @@ -96,37 +96,38 @@ inline void Dtool_Deallocate_General(PyObject * self); //////////////////////////////////////////////////////////////////////// // THIS IS THE INSTANCE CONTAINER FOR ALL panda py objects.... //////////////////////////////////////////////////////////////////////// -struct Dtool_PyInstDef -{ - PyObject_HEAD - void * _ptr_to_object; - bool _memory_rules; - unsigned long _signiture; - struct Dtool_PyTypedObject * _My_Type; +struct Dtool_PyInstDef { + PyObject_HEAD + void *_ptr_to_object; + int _memory_rules; // true if we own the pointer and should delete it or unref it + int _is_const; // true if this is a "const" pointer. + unsigned long _signature; + struct Dtool_PyTypedObject *_My_Type; }; //////////////////////////////////////////////////////////////////////// -// A Offset Dictionary Definign How to read the Above Object.. +// A Offset Dictionary Defining How to read the Above Object.. //////////////////////////////////////////////////////////////////////// extern EXPCL_DTOOLCONFIG PyMemberDef standard_type_members[]; //////////////////////////////////////////////////////////////////////// // The Class Definition Structor For a Dtool python type. //////////////////////////////////////////////////////////////////////// -struct Dtool_PyTypedObject -{ - // Standard Python Fearures.. - PyTypeObject _PyType; - // My Class Level Features.. - char * _name; // cpp name for the object - bool _Dtool_IsRunTimeCapable; // derived from TypedObject - ConvertFunctionType _Dtool_UpcastInterface; // The Upcast Function By Slot - ConvertFunctionType1 _Dtool_DowncastInterface; // The Downcast Function By Slot - FreeFunction _Dtool_FreeInstance; - PyModuleClassInit _Dtool_ClassInit; // The init function pointer - // some convience functions.. - inline PyTypeObject & As_PyTypeObject(void) { return _PyType; }; - inline PyObject & As_PyObject(void) { return (PyObject &)_PyType; }; +struct Dtool_PyTypedObject { + // Standard Python Features.. + PyTypeObject _PyType; + + // My Class Level Features.. + const char *_name; // cpp name for the object + bool _Dtool_IsRunTimeCapable; // derived from TypedObject + ConvertFunctionType _Dtool_UpcastInterface; // The Upcast Function By Slot + ConvertFunctionType1 _Dtool_DowncastInterface; // The Downcast Function By Slot + FreeFunction _Dtool_FreeInstance; + PyModuleClassInit _Dtool_ClassInit; // The init function pointer + + // some convenience functions.. + inline PyTypeObject &As_PyTypeObject() { return _PyType; }; + inline PyObject &As_PyObject() { return (PyObject &)_PyType; }; }; @@ -234,24 +235,26 @@ EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME = {\ //////////////////////////////////////////////////////////////////////// // The Fast Deallocator.. for Our instances.. //////////////////////////////////////////////////////////////////////// -inline void Dtool_Deallocate_General(PyObject * self) -{ - ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_FreeInstance(self); - self->ob_type->tp_free(self); +inline void Dtool_Deallocate_General(PyObject * self) { + ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_FreeInstance(self); + self->ob_type->tp_free(self); } + //////////////////////////////////////////////////////////////////////// -// More Macro(s) to Implement class functions.. Usally used if C++ needs type information +// 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)\ {\ - PyObject * self = type->tp_alloc(type, 0);\ - ((Dtool_PyInstDef *)self)->_signiture = PY_PANDA_SIGNITURE;\ + PyObject *self = type->tp_alloc(type, 0);\ + ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\ ((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;\ ((Dtool_PyInstDef *)self)->_memory_rules = false;\ + ((Dtool_PyInstDef *)self)->_is_const = false;\ ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\ return self;\ -}\ +} + //////////////////////////////////////////////////////////////////////// /// Delete functions.. //////////////////////////////////////////////////////////////////////// @@ -301,14 +304,15 @@ EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self); //////////////////////////////////////////////////////////////////////// // Function : DTOOL_Call_ExtractThisPointerForType // -// These are the rapers that allow for down and upcast from type .. -// needed by the Dtool py interface.. Be very carefull if you muck with these -// as the generated code depends on how this is set up.. +// These are the wrappers that allow for down and upcast from type .. +// needed by the Dtool py interface.. Be very careful if you muck +// 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_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name); +EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok); EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThis(PyObject *self); @@ -318,13 +322,13 @@ EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThis(PyObject *self); // this function relies on the behavior of typed objects in the panda system. // //////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, int RunTimeType); +EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); //////////////////////////////////////////////////////////////////////// // DTool_CreatePyInstance .. wrapper function to finalize the existance of a general // dtool py instance.. //////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_classdef, bool memory_rules); +EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); /////////////////////////////////////////////////////////////////////////////// // Macro(s) class definition .. Used to allocate storage and @@ -374,7 +378,7 @@ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) /////////////////////////////////////////////////////////////////////////////// /// Th Finalizer for simple instances.. /////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject * self, void * This, Dtool_PyTypedObject *type, bool memory_rules); +EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); /////////////////////////////////////////////////////////////////////////////// /// A heler function to glu methed definition together .. that can not be done at @@ -417,12 +421,12 @@ EXPCL_DTOOLCONFIG void Dtool_PyModuleInitHelper( LibrayDef *defs[], char * mo /////////////////////////////////////////////////////////////////////////////// /// HACK.... Be carefull // -// Dtool_BarrowThisRefrence +// Dtool_BorrowThisReference // This function can be used to grab the "THIS" pointer from an object and use it // Required to support fom historical inharatence in the for of "is this instance of".. // /////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG PyObject * Dtool_BarrowThisRefrence(PyObject * self, PyObject * args ); +EXPCL_DTOOLCONFIG PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args ); ////////////////////////////////////////////////////////////////////////////////////////////// // We do expose a dictionay for dtool classes .. this should be removed at some point..