mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
interrogate: support scoped enum args and return values
This commit is contained in:
parent
94cbdc563b
commit
b2c04a8c7a
@ -815,6 +815,11 @@ write_prototypes(ostream &out_code, ostream *out_h) {
|
|||||||
// _external_imports.insert(object->_itype._cpptype);
|
// _external_imports.insert(object->_itype._cpptype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (object->_itype.is_scoped_enum() && isExportThisRun(object->_itype._cpptype)) {
|
||||||
|
// Forward declare where we will put the scoped enum type.
|
||||||
|
string class_name = object->_itype._cpptype->get_local_name(&parser);
|
||||||
|
string safe_name = make_safe_name(class_name);
|
||||||
|
out_code << "static PyTypeObject *Dtool_Ptr_" << safe_name << " = nullptr;\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,7 +1306,10 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||||||
int enum_count = object->_itype.number_of_enum_values();
|
int enum_count = object->_itype.number_of_enum_values();
|
||||||
|
|
||||||
if (object->_itype.is_scoped_enum()) {
|
if (object->_itype.is_scoped_enum()) {
|
||||||
// Convert as Python 3.4 enum.
|
// Convert as Python 3.4-style enum.
|
||||||
|
string class_name = object->_itype._cpptype->get_local_name(&parser);
|
||||||
|
string safe_name = make_safe_name(class_name);
|
||||||
|
|
||||||
CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type());
|
CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type());
|
||||||
string cast_to = underlying_type->get_local_name(&parser);
|
string cast_to = underlying_type->get_local_name(&parser);
|
||||||
out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
|
out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
|
||||||
@ -1318,9 +1326,11 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||||||
<< object->_itype.get_enum_value_name(xx) << "));\n"
|
<< object->_itype.get_enum_value_name(xx) << "));\n"
|
||||||
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
||||||
}
|
}
|
||||||
|
out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\""
|
||||||
|
<< object->_itype.get_name() << "\", members, \""
|
||||||
|
<< _def->module_name << "\");\n";
|
||||||
out << " PyModule_AddObject(module, \"" << object->_itype.get_name()
|
out << " PyModule_AddObject(module, \"" << object->_itype.get_name()
|
||||||
<< "\", Dtool_EnumType_Create(\"" << object->_itype.get_name()
|
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
||||||
<< "\", members, \"" << _def->module_name << "\"));\n";
|
|
||||||
out << " }\n";
|
out << " }\n";
|
||||||
out << "#endif\n";
|
out << "#endif\n";
|
||||||
} else {
|
} else {
|
||||||
@ -3112,7 +3122,10 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
// support recently.
|
// support recently.
|
||||||
|
|
||||||
} else if (nested_obj->_itype.is_scoped_enum()) {
|
} else if (nested_obj->_itype.is_scoped_enum()) {
|
||||||
// Convert enum class as Python 3.4 enum.
|
// Convert enum class as Python 3.4-style enum.
|
||||||
|
string class_name = nested_obj->_itype._cpptype->get_local_name(&parser);
|
||||||
|
string safe_name = make_safe_name(class_name);
|
||||||
|
|
||||||
int enum_count = nested_obj->_itype.number_of_enum_values();
|
int enum_count = nested_obj->_itype.number_of_enum_values();
|
||||||
CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type());
|
CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type());
|
||||||
string cast_to = underlying_type->get_local_name(&parser);
|
string cast_to = underlying_type->get_local_name(&parser);
|
||||||
@ -3130,9 +3143,11 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
<< nested_obj->_itype.get_enum_value_name(xx) << "));\n"
|
<< nested_obj->_itype.get_enum_value_name(xx) << "));\n"
|
||||||
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
||||||
}
|
}
|
||||||
|
out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\""
|
||||||
|
<< nested_obj->_itype.get_name() << "\", members, \""
|
||||||
|
<< _def->module_name << "\");\n";
|
||||||
out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name()
|
out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name()
|
||||||
<< "\", Dtool_EnumType_Create(\"" << nested_obj->_itype.get_name()
|
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
||||||
<< "\", members, \"" << _def->module_name << "\"));\n";
|
|
||||||
out << " }\n";
|
out << " }\n";
|
||||||
out << "#endif\n";
|
out << "#endif\n";
|
||||||
|
|
||||||
@ -4821,6 +4836,46 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||||||
clear_error = true;
|
clear_error = true;
|
||||||
only_pyobjects = false;
|
only_pyobjects = false;
|
||||||
|
|
||||||
|
} else if (TypeManager::is_scoped_enum(type)) {
|
||||||
|
if (args_type == AT_single_arg) {
|
||||||
|
param_name = "arg";
|
||||||
|
} else {
|
||||||
|
indent(out, indent_level) << "PyObject *" << param_name;
|
||||||
|
if (default_value != nullptr) {
|
||||||
|
out << " = nullptr";
|
||||||
|
}
|
||||||
|
out << ";\n";
|
||||||
|
format_specifiers += "O";
|
||||||
|
parameter_list += ", &" + param_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPEnumType *enum_type = (CPPEnumType *)TypeManager::unwrap(type);
|
||||||
|
CPPType *underlying_type = enum_type->get_underlying_type();
|
||||||
|
underlying_type = TypeManager::unwrap_const(underlying_type);
|
||||||
|
|
||||||
|
//indent(out, indent_level);
|
||||||
|
//underlying_type->output_instance(out, param_name + "_val", &parser);
|
||||||
|
//out << default_expr << ";\n";
|
||||||
|
extra_convert << "long " << param_name << "_val";
|
||||||
|
|
||||||
|
if (default_value != nullptr) {
|
||||||
|
extra_convert << " = (long)";
|
||||||
|
default_value->output(extra_convert, 0, &parser, false);
|
||||||
|
extra_convert <<
|
||||||
|
";\nif (" << param_name << " != nullptr) {\n"
|
||||||
|
" " << param_name << "_val = Dtool_EnumValue_AsLong(" + param_name + ");\n"
|
||||||
|
"}";
|
||||||
|
} else {
|
||||||
|
extra_convert
|
||||||
|
<< ";\n"
|
||||||
|
<< param_name << "_val = Dtool_EnumValue_AsLong(" + param_name + ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
pexpr_string = "(" + enum_type->get_local_name(&parser) + ")" + param_name + "_val";
|
||||||
|
expected_params += classNameFromCppName(enum_type->get_simple_name(), false);
|
||||||
|
extra_param_check << " && " << param_name << "_val != -1";
|
||||||
|
clear_error = true;
|
||||||
|
|
||||||
} else if (TypeManager::is_bool(type)) {
|
} else if (TypeManager::is_bool(type)) {
|
||||||
if (args_type == AT_single_arg) {
|
if (args_type == AT_single_arg) {
|
||||||
param_name = "arg";
|
param_name = "arg";
|
||||||
@ -6220,7 +6275,24 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
|
|||||||
CPPType *orig_type = return_type->get_orig_type();
|
CPPType *orig_type = return_type->get_orig_type();
|
||||||
CPPType *type = return_type->get_new_type();
|
CPPType *type = return_type->get_new_type();
|
||||||
|
|
||||||
if (return_type->new_type_is_atomic_string() ||
|
if (TypeManager::is_scoped_enum(type)) {
|
||||||
|
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||||
|
TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false);
|
||||||
|
const InterrogateType &itype = idb->get_type(type_index);
|
||||||
|
string safe_name = make_safe_name(itype.get_scoped_name());
|
||||||
|
|
||||||
|
indent(out, indent_level)
|
||||||
|
<< "return PyObject_CallFunction((PyObject *)Dtool_Ptr_" << safe_name;
|
||||||
|
|
||||||
|
CPPType *underlying_type = ((CPPEnumType *)itype._cpptype)->get_underlying_type();
|
||||||
|
if (TypeManager::is_unsigned_integer(underlying_type)) {
|
||||||
|
out << ", \"k\", (unsigned long)";
|
||||||
|
} else {
|
||||||
|
out << ", \"l\", (long)";
|
||||||
|
}
|
||||||
|
out << "(" << return_expr << "));\n";
|
||||||
|
|
||||||
|
} else if (return_type->new_type_is_atomic_string() ||
|
||||||
TypeManager::is_simple(type) ||
|
TypeManager::is_simple(type) ||
|
||||||
TypeManager::is_char_pointer(type) ||
|
TypeManager::is_char_pointer(type) ||
|
||||||
TypeManager::is_wchar_pointer(type) ||
|
TypeManager::is_wchar_pointer(type) ||
|
||||||
|
@ -310,6 +310,26 @@ is_struct(CPPType *type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the indicated type is an enum class, const or otherwise.
|
||||||
|
*/
|
||||||
|
bool TypeManager::
|
||||||
|
is_scoped_enum(CPPType *type) {
|
||||||
|
switch (type->get_subtype()) {
|
||||||
|
case CPPDeclaration::ST_enum:
|
||||||
|
return ((CPPEnumType *)type)->is_scoped();
|
||||||
|
|
||||||
|
case CPPDeclaration::ST_const:
|
||||||
|
return is_scoped_enum(type->as_const_type()->_wrapped_around);
|
||||||
|
|
||||||
|
case CPPDeclaration::ST_typedef:
|
||||||
|
return is_scoped_enum(type->as_typedef_type()->_type);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the indicated type is some kind of enumerated type, const
|
* Returns true if the indicated type is some kind of enumerated type, const
|
||||||
* or otherwise.
|
* or otherwise.
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
static bool is_pointer(CPPType *type);
|
static bool is_pointer(CPPType *type);
|
||||||
static bool is_const(CPPType *type);
|
static bool is_const(CPPType *type);
|
||||||
static bool is_struct(CPPType *type);
|
static bool is_struct(CPPType *type);
|
||||||
|
static bool is_scoped_enum(CPPType *type);
|
||||||
static bool is_enum(CPPType *type);
|
static bool is_enum(CPPType *type);
|
||||||
static bool is_const_enum(CPPType *type);
|
static bool is_const_enum(CPPType *type);
|
||||||
static bool is_const_ref_to_enum(CPPType *type);
|
static bool is_const_ref_to_enum(CPPType *type);
|
||||||
|
@ -97,6 +97,20 @@ INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, i
|
|||||||
Py_RETURN_RICHCOMPARE(cmpval, 0, op);
|
Py_RETURN_RICHCOMPARE(cmpval, 0, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the enum value to a C long.
|
||||||
|
*/
|
||||||
|
INLINE long Dtool_EnumValue_AsLong(PyObject *value) {
|
||||||
|
PyObject *val = PyObject_GetAttrString(value, "value");
|
||||||
|
if (val != nullptr) {
|
||||||
|
long as_long = PyLongOrInt_AS_LONG(val);
|
||||||
|
Py_DECREF(val);
|
||||||
|
return as_long;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These functions wrap a pointer for a class that defines get_type_handle().
|
* These functions wrap a pointer for a class that defines get_type_handle().
|
||||||
*/
|
*/
|
||||||
|
@ -309,7 +309,7 @@ PyObject *_Dtool_Return(PyObject *value) {
|
|||||||
/**
|
/**
|
||||||
* Creates a Python 3.4-style enum type. Steals reference to 'names'.
|
* Creates a Python 3.4-style enum type. Steals reference to 'names'.
|
||||||
*/
|
*/
|
||||||
PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
|
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
|
||||||
static PyObject *enum_class = nullptr;
|
static PyObject *enum_class = nullptr;
|
||||||
static PyObject *enum_meta = nullptr;
|
static PyObject *enum_meta = nullptr;
|
||||||
static PyObject *enum_create = nullptr;
|
static PyObject *enum_create = nullptr;
|
||||||
@ -330,7 +330,8 @@ PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *m
|
|||||||
PyObject_SetAttrString(result, "__module__", modstr);
|
PyObject_SetAttrString(result, "__module__", modstr);
|
||||||
Py_DECREF(modstr);
|
Py_DECREF(modstr);
|
||||||
}
|
}
|
||||||
return result;
|
nassertr(PyType_Check(result), nullptr);
|
||||||
|
return (PyTypeObject *)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -258,8 +258,10 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
|
|||||||
/**
|
/**
|
||||||
* Wrapper around Python 3.4's enum library, which does not have a C API.
|
* Wrapper around Python 3.4's enum library, which does not have a C API.
|
||||||
*/
|
*/
|
||||||
EXPCL_INTERROGATEDB PyObject *Dtool_EnumType_Create(const char *name, PyObject *names,
|
EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
|
||||||
const char *module = nullptr);
|
const char *module = nullptr);
|
||||||
|
EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user