interrogate changes: respect const, use Python names in diagnostic messages

This commit is contained in:
David Rose 2007-02-08 20:15:54 +00:00
parent c1091e7b4a
commit 0be53cccf6
10 changed files with 255 additions and 113 deletions

View File

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

View File

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

View File

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

View File

@ -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<<","<<typestr<<");\n";
indent(out, indent_level)<<"return DTool_CreatePyInstanceTyped((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<< ows_memory_flag << ", " << const_flag << ", " << typestr << ");\n";
}
else
{
// indent(out, indent_level)<< "if(" << return_expr <<"!= NULL)\n";
indent(out, indent_level)
<<"return DTool_CreatePyInstance((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<<ows_memory_flag<<");\n";
<<"return DTool_CreatePyInstance((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<<ows_memory_flag << ", " << const_flag <<");\n";
}
}
}
@ -892,8 +891,8 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_
if(force_base_functions)
{
out << " //Support Function For Dtool_types ... for know in each module ??\n";
out << " {\"Dtool_BarrowThisRefrence\", &Dtool_BarrowThisRefrence,METH_VARARGS,\"Used to barrow 'this' poiner ( to, from)\\n Assumes no ownership\"}, \n";
out << " //Support Function For Dtool_types ... for now in each module ??\n";
out << " {\"Dtool_BorrowThisReference\", &Dtool_BorrowThisReference,METH_VARARGS,\"Used to borrow 'this' poiner ( to, from)\\n Assumes no ownership\"}, \n";
out << " {\"Dtool_AddToDictionary\", &Dtool_AddToDictionary,METH_VARARGS,\"Used to Items Into a types (tp_dict)\"}, \n";
}
@ -1730,7 +1729,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Function *func,
indent(out,8)<< "{\n";
indent(out,12)
<< "PyErr_Format(PyExc_TypeError, \""
<< func->_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()) << ","<<ows_memory_flag<<");\n";
WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag);
}
else
@ -2380,7 +2437,7 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
const InterrogateType &itype = idb->get_type(type_index);
indent(out, indent_level)
<<"return DTool_PyInit_Finalize(self, " << return_expr <<",&"<<CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) << ",true);\n";
<<"return DTool_PyInit_Finalize(self, " << return_expr <<",&"<<CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) << ",true,false);\n";
}
else
{
@ -2404,9 +2461,7 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve
}
// ForwardDeclrs << "extern \"C\" 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()) << ","<<ows_memory_flag<<");\n";
WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag);
}
else
{
@ -2421,9 +2476,7 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve
}
// ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n";
//indent(out, indent_level)
// <<"return DTool_CreatePyInstance((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) << ","<<ows_memory_flag<<");\n";
WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace);
WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag);
}
}
@ -2448,10 +2501,8 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve
}
// ForwardDeclrs << "extern \"C\" 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);
WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag);
//indent(out, indent_level)
// << "return DTool_CreatePyInstance((void *)" << return_expr <<","<<CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) <<","<< ows_memory_flag<< ");\n";
}
else
{

View File

@ -106,7 +106,7 @@ public:
void GetValideChildClasses( std::map< std::string ,CastDetails > &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);

View File

@ -38,6 +38,7 @@ ParameterRemapThis(CPPType *type, bool is_const) :
} else {
_new_type = TypeManager::wrap_pointer(type);
}
_orig_type = _new_type;
}
////////////////////////////////////////////////////////////////////

View File

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

View File

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

View File

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

View File

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