mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
Add functionality allowing extension functions to interrogate
This commit is contained in:
parent
9067399079
commit
beb90c565f
@ -250,6 +250,7 @@ pop_struct() {
|
||||
%token KW_ELSE
|
||||
%token KW_END_PUBLISH
|
||||
%token KW_ENUM
|
||||
%token KW_EXTENSION
|
||||
%token KW_EXTERN
|
||||
%token KW_EXPLICIT
|
||||
%token KW_PUBLISHED
|
||||
@ -547,6 +548,10 @@ storage_class:
|
||||
| storage_class KW_BLOCKING
|
||||
{
|
||||
$$ = $1 | (int)CPPInstance::SC_blocking;
|
||||
}
|
||||
| storage_class KW_EXTENSION
|
||||
{
|
||||
$$ = $1 | (int)CPPInstance::SC_extension;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -37,25 +37,29 @@ public:
|
||||
// Some of these flags clearly only make sense in certain contexts,
|
||||
// e.g. for a function or method.
|
||||
enum StorageClass {
|
||||
SC_static = 0x001,
|
||||
SC_extern = 0x002,
|
||||
SC_c_binding = 0x004,
|
||||
SC_virtual = 0x008,
|
||||
SC_inline = 0x010,
|
||||
SC_explicit = 0x020,
|
||||
SC_register = 0x040,
|
||||
SC_pure_virtual = 0x080,
|
||||
SC_volatile = 0x100,
|
||||
SC_mutable = 0x200,
|
||||
SC_static = 0x0001,
|
||||
SC_extern = 0x0002,
|
||||
SC_c_binding = 0x0004,
|
||||
SC_virtual = 0x0008,
|
||||
SC_inline = 0x0010,
|
||||
SC_explicit = 0x0020,
|
||||
SC_register = 0x0040,
|
||||
SC_pure_virtual = 0x0080,
|
||||
SC_volatile = 0x0100,
|
||||
SC_mutable = 0x0200,
|
||||
|
||||
// This bit is only set by CPPStructType::check_virtual().
|
||||
SC_inherited_virtual = 0x400,
|
||||
SC_inherited_virtual = 0x0400,
|
||||
|
||||
// This is a special "storage class" for methods tagged with the
|
||||
// BLOCKING macro (i.e. the special __blocking keyword). These
|
||||
// are methods that might block and therefore need to release
|
||||
// Python threads for their duration.
|
||||
SC_blocking = 0x800,
|
||||
SC_blocking = 0x0800,
|
||||
|
||||
// And this is for methods tagged with __extension, which declares
|
||||
// extension methods defined separately from the source code.
|
||||
SC_extension = 0x1000,
|
||||
};
|
||||
|
||||
CPPInstance(CPPType *type, const string &name, int storage_class = 0);
|
||||
|
@ -1966,6 +1966,7 @@ check_keyword(const string &name) {
|
||||
if (name == "__end_publish") return KW_END_PUBLISH;
|
||||
if (name == "enum") return KW_ENUM;
|
||||
if (name == "extern") return KW_EXTERN;
|
||||
if (name == "__extension") return KW_EXTENSION;
|
||||
if (name == "explicit") return KW_EXPLICIT;
|
||||
if (name == "__published") return KW_PUBLISHED;
|
||||
if (name == "false") return KW_FALSE;
|
||||
|
@ -325,12 +325,29 @@
|
||||
#define END_PUBLISH __end_publish
|
||||
#define BLOCKING __blocking
|
||||
#define MAKE_SEQ(seq_name, num_name, element_name) __make_seq(seq_name, num_name, element_name)
|
||||
#undef USE_STL_ALLOCATOR // Don't try to parse these template classes in interrogate.
|
||||
#undef USE_STL_ALLOCATOR /* Don't try to parse these template classes in interrogate. */
|
||||
#define EXTENSION(x) __extension x;
|
||||
#define EXTEND __extension
|
||||
#define EXT_FUNC(func) ::func()
|
||||
#define EXT_FUNC_ARGS(func, ...) ::func(__VA_ARGS__)
|
||||
#define EXT_METHOD(cl, m) cl::m()
|
||||
#define EXT_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__)
|
||||
#define EXT_CONST_METHOD(cl, m) cl::m() const
|
||||
#define EXT_CONST_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) const
|
||||
#else
|
||||
#define BEGIN_PUBLISH
|
||||
#define END_PUBLISH
|
||||
#define BLOCKING
|
||||
#define MAKE_SEQ(seq_name, num_name, element_name)
|
||||
#define EXTENSION(x)
|
||||
#define EXTEND
|
||||
/* If you change this, don't forget to also change it in interrogate itself. */
|
||||
#define EXT_FUNC(cl, m) _ext__ ## m ()
|
||||
#define EXT_FUNC_ARGS(cl, m, ...) _ext__ ## m (__VA_ARGS__)
|
||||
#define EXT_METHOD(cl, m) _ext_ ## cl ## _ ## m (cl * _ext_this)
|
||||
#define EXT_METHOD_ARGS(cl, m, ...) _ext_ ## cl ## _ ## m (cl * _ext_this, __VA_ARGS__)
|
||||
#define EXT_CONST_METHOD(cl, m) _ext_ ## cl ## _ ## m (const cl * _ext_this)
|
||||
#define EXT_CONST_METHOD_ARGS(cl, m, ...) _ext_ ## cl ## _ ## m (const cl * _ext_this, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -44,6 +44,7 @@ FunctionRemap(const InterrogateType &itype, const InterrogateFunction &ifunc,
|
||||
_ForcedVoidReturn = false;
|
||||
_has_this = false;
|
||||
_blocking = false;
|
||||
_extension = false;
|
||||
_const_method = false;
|
||||
_first_true_parameter = 0;
|
||||
_num_default_parameters = num_default_parameters;
|
||||
@ -115,11 +116,12 @@ string FunctionRemap::call_function(ostream &out, int indent_level, bool convert
|
||||
InterfaceMaker::indent(out, indent_level)
|
||||
<< "unref_delete(" << container << ");\n";
|
||||
} else {
|
||||
if(inside_python_native)
|
||||
if (inside_python_native) {
|
||||
InterfaceMaker::indent(out, indent_level) << "Dtool_Py_Delete(self); \n";
|
||||
else
|
||||
} else {
|
||||
InterfaceMaker::indent(out, indent_level) << " delete " << container << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_type == T_typecast_method) {
|
||||
// A typecast method can be invoked implicitly.
|
||||
@ -376,8 +378,7 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
||||
call << _expression;
|
||||
}
|
||||
|
||||
} else if (_type == T_setter)
|
||||
{
|
||||
} else if (_type == T_setter) {
|
||||
if (!container.empty()) {
|
||||
call << "(" << container << ")->" << _expression;
|
||||
} else {
|
||||
@ -387,6 +388,24 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
||||
call << " = ";
|
||||
_parameters[0]._remap->pass_parameter(call, get_parameter_expr(_first_true_parameter, pexprs));
|
||||
|
||||
} else {
|
||||
const char *separator = "";
|
||||
|
||||
// If this function is marked as having an extension function,
|
||||
// call that instead. The naming convention of the extension
|
||||
// function has to match the EXT_IMPL definition in dtoolbase.h.
|
||||
if (_extension) {
|
||||
if (_cpptype != NULL) {
|
||||
call << "_ext_" << _cpptype->get_local_name()
|
||||
<< _cppfunc->get_local_name() << "(";
|
||||
} else {
|
||||
call << "_ext__" << _cppfunc->get_local_name() << "(";
|
||||
}
|
||||
|
||||
if (_has_this && !container.empty()) {
|
||||
call << container;
|
||||
separator = ", ";
|
||||
}
|
||||
} else {
|
||||
|
||||
if (_type == T_constructor) {
|
||||
@ -402,9 +421,9 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
||||
call << _cppfunc->get_local_name(&parser);
|
||||
}
|
||||
|
||||
const char *separator = "";
|
||||
|
||||
call << "(";
|
||||
}
|
||||
|
||||
if (_flags & F_explicit_self) {
|
||||
// Pass on the PyObject * that we stripped off above.
|
||||
call << separator << "self";
|
||||
@ -472,11 +491,14 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
||||
_type = T_setter;
|
||||
}
|
||||
|
||||
if (_cpptype != (CPPType *)NULL &&
|
||||
((_cppfunc->_storage_class & CPPInstance::SC_blocking) != 0)) {
|
||||
if ((_cppfunc->_storage_class & CPPInstance::SC_blocking) != 0) {
|
||||
// If it's marked as a "blocking" method or function, record that.
|
||||
_blocking = true;
|
||||
}
|
||||
if ((_cppfunc->_storage_class & CPPInstance::SC_extension) != 0) {
|
||||
// Same with functions or methods marked with "extension".
|
||||
_extension = true;
|
||||
}
|
||||
|
||||
string fname = _cppfunc->get_simple_name();
|
||||
|
||||
|
@ -97,6 +97,7 @@ public:
|
||||
bool _ForcedVoidReturn;
|
||||
bool _has_this;
|
||||
bool _blocking;
|
||||
bool _extension;
|
||||
bool _const_method;
|
||||
int _first_true_parameter;
|
||||
int _num_default_parameters;
|
||||
|
@ -376,10 +376,10 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
||||
|
||||
declaration_bodies << "#include <sstream>\n";
|
||||
|
||||
if (build_python_native )
|
||||
{
|
||||
if(library_name.size() > 1)
|
||||
if (build_python_native) {
|
||||
if (library_name.size() > 1) {
|
||||
declaration_bodies << "#define PANDA_LIBRARY_NAME_" << library_name << "\n";
|
||||
}
|
||||
declaration_bodies << "#include \"py_panda.h\" \n";
|
||||
}
|
||||
declaration_bodies << "\n";
|
||||
@ -396,6 +396,12 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
|
||||
} else {
|
||||
declaration_bodies << "#include <" << filename << ">\n";
|
||||
}
|
||||
// Check if it's a special extension file.
|
||||
} else if (filename.length() > 6 && filename.substr(filename.length() - 6) == "_ext.I") {
|
||||
declaration_bodies
|
||||
<< "#define this _ext_this\n"
|
||||
<< "#include \"" << filename << "\"\n"
|
||||
<< "#undef this\n";
|
||||
}
|
||||
}
|
||||
declaration_bodies << "\n";
|
||||
@ -921,7 +927,7 @@ in_noinclude(const string &name) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool InterrogateBuilder::
|
||||
should_include(const string &filename) const {
|
||||
// Don't directly include any .cxx or .I files.
|
||||
// Don't directly include any .cxx or .I files, except for extensions.
|
||||
if (CPPFile::is_c_or_i_file(filename)) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user