interrogatedb 3.0 to restructure make_seq, improve make_seq handling and performance

This commit is contained in:
rdb 2015-11-09 18:01:44 +01:00
parent 4a5d64909a
commit ac1c036cac
19 changed files with 1831 additions and 1628 deletions

View File

@ -83,7 +83,6 @@ static PyObject *_inP07ytf513(PyObject *self, PyObject *args);
static PyObject *_inP07ytsqGH(PyObject *self, PyObject *args); static PyObject *_inP07ytsqGH(PyObject *self, PyObject *args);
static PyObject *_inP07yt7shV(PyObject *self, PyObject *args); static PyObject *_inP07yt7shV(PyObject *self, PyObject *args);
static PyObject *_inP07ytA1eF(PyObject *self, PyObject *args); static PyObject *_inP07ytA1eF(PyObject *self, PyObject *args);
static PyObject *_inP07yt9tTm(PyObject *self, PyObject *args);
static PyObject *_inP07yt776V(PyObject *self, PyObject *args); static PyObject *_inP07yt776V(PyObject *self, PyObject *args);
static PyObject *_inP07ytfaH0(PyObject *self, PyObject *args); static PyObject *_inP07ytfaH0(PyObject *self, PyObject *args);
static PyObject *_inP07ytGB9D(PyObject *self, PyObject *args); static PyObject *_inP07ytGB9D(PyObject *self, PyObject *args);
@ -1219,24 +1218,6 @@ _inP07ytA1eF(PyObject *, PyObject *args) {
return (PyObject *)NULL; return (PyObject *)NULL;
} }
/*
* Python simple wrapper for
* TypeIndex interrogate_make_seq_class(MakeSeqIndex make_seq)
*/
static PyObject *
_inP07yt9tTm(PyObject *, PyObject *args) {
int param0;
if (PyArg_ParseTuple(args, "i", &param0)) {
TypeIndex return_value = interrogate_make_seq_class((MakeSeqIndex)param0);
#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong(return_value);
#else
return PyInt_FromLong(return_value);
#endif
}
return (PyObject *)NULL;
}
/* /*
* Python simple wrapper for * Python simple wrapper for
* char const *interrogate_make_seq_seq_name(MakeSeqIndex make_seq) * char const *interrogate_make_seq_seq_name(MakeSeqIndex make_seq)
@ -2433,7 +2414,6 @@ static PyMethodDef python_simple_funcs[] = {
{ "interrogate_wrapper_pointer", &_inP07ytsqGH, METH_VARARGS }, { "interrogate_wrapper_pointer", &_inP07ytsqGH, METH_VARARGS },
{ "interrogate_wrapper_unique_name", &_inP07yt7shV, METH_VARARGS }, { "interrogate_wrapper_unique_name", &_inP07yt7shV, METH_VARARGS },
{ "interrogate_get_wrapper_by_unique_name", &_inP07ytA1eF, METH_VARARGS }, { "interrogate_get_wrapper_by_unique_name", &_inP07ytA1eF, METH_VARARGS },
{ "interrogate_make_seq_class", &_inP07yt9tTm, METH_VARARGS },
{ "interrogate_make_seq_seq_name", &_inP07yt776V, METH_VARARGS }, { "interrogate_make_seq_seq_name", &_inP07yt776V, METH_VARARGS },
{ "interrogate_make_seq_num_name", &_inP07ytfaH0, METH_VARARGS }, { "interrogate_make_seq_num_name", &_inP07ytfaH0, METH_VARARGS },
{ "interrogate_make_seq_element_name", &_inP07ytGB9D, METH_VARARGS }, { "interrogate_make_seq_element_name", &_inP07ytGB9D, METH_VARARGS },

File diff suppressed because it is too large Load Diff

View File

@ -502,7 +502,7 @@ declaration:
CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer); CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer);
if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) { if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) {
yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @1); yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @5);
} }
CPPMakeProperty *make_property = new CPPMakeProperty($3, getter->as_function_group(), NULL, current_scope, @1.file); CPPMakeProperty *make_property = new CPPMakeProperty($3, getter->as_function_group(), NULL, current_scope, @1.file);
@ -512,14 +512,14 @@ declaration:
{ {
CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer); CPPDeclaration *getter = $5->find_symbol(current_scope, global_scope, current_lexer);
if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) { if (getter == (CPPDeclaration *)NULL || getter->get_subtype() != CPPDeclaration::ST_function_group) {
yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @1); yyerror("Reference to non-existent or invalid getter: " + $5->get_fully_scoped_name(), @5);
} else { } else {
CPPDeclaration *setter = $7->find_symbol(current_scope, global_scope, current_lexer); CPPDeclaration *setter = $7->find_symbol(current_scope, global_scope, current_lexer);
CPPFunctionGroup *setter_func = NULL; CPPFunctionGroup *setter_func = NULL;
if (setter == (CPPDeclaration *)NULL || setter->get_subtype() != CPPDeclaration::ST_function_group) { if (setter == (CPPDeclaration *)NULL || setter->get_subtype() != CPPDeclaration::ST_function_group) {
yyerror("Reference to non-existent or invalid setter: " + $7->get_fully_scoped_name(), @1); yyerror("Reference to non-existent or invalid setter: " + $7->get_fully_scoped_name(), @7);
} else { } else {
setter_func = setter->as_function_group(); setter_func = setter->as_function_group();
} }
@ -529,10 +529,27 @@ declaration:
current_scope->add_declaration(make_property, global_scope, current_lexer, @1); current_scope->add_declaration(make_property, global_scope, current_lexer, @1);
} }
} }
| KW_MAKE_SEQ '(' name ',' name ',' name ')' ';' | KW_MAKE_SEQ '(' IDENTIFIER ',' IDENTIFIER ',' IDENTIFIER ')' ';'
{ {
CPPMakeSeq *make_seq = new CPPMakeSeq($3->get_simple_name(), $5->get_simple_name(), $7->get_simple_name(), @1.file); CPPDeclaration *length_getter = $5->find_symbol(current_scope, global_scope, current_lexer);
current_scope->add_declaration(make_seq, global_scope, current_lexer, @1); if (length_getter == (CPPDeclaration *)NULL || length_getter->get_subtype() != CPPDeclaration::ST_function_group) {
yyerror("reference to non-existent or invalid length method: " + $5->get_fully_scoped_name(), @5);
length_getter = NULL;
}
CPPDeclaration *element_getter = $7->find_symbol(current_scope, global_scope, current_lexer);
if (element_getter == (CPPDeclaration *)NULL || element_getter->get_subtype() != CPPDeclaration::ST_function_group) {
yyerror("reference to non-existent or invalid element method: " + $7->get_fully_scoped_name(), @5);
element_getter = NULL;
}
if (length_getter != (CPPDeclaration *)NULL && element_getter != (CPPDeclaration *)NULL) {
CPPMakeSeq *make_seq = new CPPMakeSeq($3,
length_getter->as_function_group(),
element_getter->as_function_group(),
current_scope, @1.file);
current_scope->add_declaration(make_seq, global_scope, current_lexer, @1);
}
} }
| KW_STATIC_ASSERT '(' const_expr ',' string_literal ')' | KW_STATIC_ASSERT '(' const_expr ',' string_literal ')'
{ {

View File

@ -20,13 +20,46 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CPPMakeSeq:: CPPMakeSeq::
CPPMakeSeq(const string &seq_name, const string &num_name, CPPMakeSeq(CPPIdentifier *ident,
const string &element_name, const CPPFile &file) : CPPFunctionGroup *length_getter,
CPPFunctionGroup *element_getter,
CPPScope *current_scope, const CPPFile &file) :
CPPDeclaration(file), CPPDeclaration(file),
_seq_name(seq_name), _ident(ident),
_num_name(num_name), _length_getter(length_getter),
_element_name(element_name) _element_getter(element_getter)
{ {
_ident->_native_scope = current_scope;
}
////////////////////////////////////////////////////////////////////
// Function: CPPMakeSeq::get_simple_name
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
string CPPMakeSeq::
get_simple_name() const {
return _ident->get_simple_name();
}
////////////////////////////////////////////////////////////////////
// Function: CPPMakeSeq::get_local_name
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
string CPPMakeSeq::
get_local_name(CPPScope *scope) const {
return _ident->get_local_name(scope);
}
////////////////////////////////////////////////////////////////////
// Function: CPPMakeSeq::get_fully_scoped_name
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
string CPPMakeSeq::
get_fully_scoped_name() const {
return _ident->get_fully_scoped_name();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -36,8 +69,10 @@ CPPMakeSeq(const string &seq_name, const string &num_name,
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CPPMakeSeq:: void CPPMakeSeq::
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const { output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
out << "__make_seq(" << _seq_name << ", " << _num_name << ", " out << "__make_seq(" << _ident->get_local_name(scope)
<< _element_name << ");"; << ", " << _length_getter->_name
<< ", " << _element_getter->_name
<< ");";
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -18,6 +18,7 @@
#include "dtoolbase.h" #include "dtoolbase.h"
#include "cppDeclaration.h" #include "cppDeclaration.h"
#include "cppIdentifier.h"
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// Class : CPPMakeSeq // Class : CPPMakeSeq
@ -29,8 +30,14 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class CPPMakeSeq : public CPPDeclaration { class CPPMakeSeq : public CPPDeclaration {
public: public:
CPPMakeSeq(const string &seq_name, const string &num_name, CPPMakeSeq(CPPIdentifier *ident,
const string &element_name, const CPPFile &file); CPPFunctionGroup *length_getter,
CPPFunctionGroup *element_getter,
CPPScope *current_scope, const CPPFile &file);
virtual string get_simple_name() const;
virtual string get_local_name(CPPScope *scope = NULL) const;
virtual string get_fully_scoped_name() const;
virtual void output(ostream &out, int indent_level, CPPScope *scope, virtual void output(ostream &out, int indent_level, CPPScope *scope,
bool complete) const; bool complete) const;
@ -38,11 +45,9 @@ public:
virtual SubType get_subtype() const; virtual SubType get_subtype() const;
virtual CPPMakeSeq *as_make_seq(); virtual CPPMakeSeq *as_make_seq();
string _seq_name; CPPIdentifier *_ident;
string _num_name; CPPFunctionGroup *_length_getter;
string _element_name; CPPFunctionGroup *_element_getter;
}; };
#endif #endif

View File

@ -79,11 +79,11 @@ InterfaceMaker::Function::
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
InterfaceMaker::MakeSeq:: InterfaceMaker::MakeSeq::
MakeSeq(const string &name, CPPMakeSeq *cpp_make_seq) : MakeSeq(const string &name, const InterrogateMakeSeq &imake_seq) :
_name(name), _name(name),
_seq_name(cpp_make_seq->_seq_name), _imake_seq(imake_seq),
_num_name(cpp_make_seq->_num_name), _length_getter(NULL),
_element_name(cpp_make_seq->_element_name) _element_getter(NULL)
{ {
} }
@ -174,30 +174,6 @@ check_protocols() {
if (flags & FunctionRemap::F_iter) { if (flags & FunctionRemap::F_iter) {
_protocol_types |= PT_iter; _protocol_types |= PT_iter;
} }
// Now are there any make_seq requests within this class?
if (_itype._cpptype != NULL) {
CPPStructType *stype = _itype._cpptype->as_struct_type();
if (stype != (CPPStructType *)NULL) {
CPPScope *scope = stype->get_scope();
if (scope != (CPPScope *)NULL) {
CPPScope::Declarations::iterator di;
for (di = scope->_declarations.begin(); di != scope->_declarations.end(); ++di) {
CPPMakeSeq *cpp_make_seq = (*di)->as_make_seq();
if (cpp_make_seq != (CPPMakeSeq *)NULL) {
string class_name = _itype.get_scoped_name();
string clean_name = InterrogateBuilder::clean_identifier(class_name);
string wrapper_name = "MakeSeq_" + clean_name + "_" + cpp_make_seq->_seq_name;
MakeSeq *make_seq = new MakeSeq(wrapper_name, cpp_make_seq);
_make_seqs.push_back(make_seq);
// Also add to the interrogate database.
builder.get_make_seq(cpp_make_seq, stype);
}
}
}
}
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -637,6 +613,8 @@ get_unique_prefix() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
InterfaceMaker::Function *InterfaceMaker:: InterfaceMaker::Function *InterfaceMaker::
record_function(const InterrogateType &itype, FunctionIndex func_index) { record_function(const InterrogateType &itype, FunctionIndex func_index) {
assert(func_index != 0);
if (_functions.count(func_index)) { if (_functions.count(func_index)) {
// Already exists. // Already exists.
return _functions[func_index]; return _functions[func_index];

View File

@ -33,6 +33,7 @@ class CPPInstance;
class InterrogateBuilder; class InterrogateBuilder;
class InterrogateElement; class InterrogateElement;
class InterrogateFunction; class InterrogateFunction;
class InterrogateMakeSeq;
class InterrogateType; class InterrogateType;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -116,12 +117,12 @@ public:
class MakeSeq { class MakeSeq {
public: public:
MakeSeq(const string &name, CPPMakeSeq *cpp_make_seq); MakeSeq(const string &name, const InterrogateMakeSeq &imake_seq);
const InterrogateMakeSeq &_imake_seq;
string _name; string _name;
string _seq_name; Function *_length_getter;
string _num_name; Function *_element_getter;
string _element_name;
}; };
typedef vector<MakeSeq *> MakeSeqs; typedef vector<MakeSeq *> MakeSeqs;

View File

@ -1099,7 +1099,17 @@ write_class_details(ostream &out, Object *obj) {
// Write make seqs: generated methods that return a sequence of items. // Write make seqs: generated methods that return a sequence of items.
MakeSeqs::iterator msi; MakeSeqs::iterator msi;
for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) { for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) {
write_make_seq(out, obj, ClassName, cClassName, *msi); if (is_function_legal((*msi)->_length_getter) &&
is_function_legal((*msi)->_element_getter)) {
write_make_seq(out, obj, ClassName, cClassName, *msi);
} else {
if (!is_function_legal((*msi)->_length_getter)) {
cerr << "illegal length function for MAKE_SEQ: " << (*msi)->_length_getter->_name << "\n";
}
if (!is_function_legal((*msi)->_element_getter)) {
cerr << "illegal element function for MAKE_SEQ: " << (*msi)->_element_getter->_name << "\n";
}
}
} }
// Determine which external imports we will need. // Determine which external imports we will need.
@ -1711,23 +1721,27 @@ write_module_class(ostream &out, Object *obj) {
MakeSeqs::iterator msi; MakeSeqs::iterator msi;
for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) { for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) {
const string &seq_name = (*msi)->_seq_name; MakeSeq *make_seq = (*msi);
if (!is_function_legal(make_seq->_length_getter) ||
!is_function_legal(make_seq->_element_getter)) {
continue;
}
if ((seq_name.size() > 4 && seq_name.substr(0, 4) == "get_") || string seq_name = make_seq->_imake_seq.get_name();
(seq_name.size() > 7 && seq_name.substr(0, 7) == "modify_")) {
string flags = "METH_NOARGS"; string flags = "METH_NOARGS";
if (obj->is_static_method((*msi)->_element_name)) { if (!make_seq->_length_getter->_has_this &&
flags += " | METH_CLASS"; !make_seq->_element_getter->_has_this) {
} flags += " | METH_STATIC";
string name1 = methodNameFromCppName((*msi)->_seq_name, export_class_name, false); }
string name2 = methodNameFromCppName((*msi)->_seq_name, export_class_name, true);
out << " {\"" << name1 string name1 = methodNameFromCppName(seq_name, export_class_name, false);
<< "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n"; string name2 = methodNameFromCppName(seq_name, export_class_name, true);
if (name1 != name2) { out << " {\"" << name1
out << " { \"" << name2 << "\", (PyCFunction) &" << make_seq->_name << ", " << flags << ", NULL},\n";
<< "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n"; if (name1 != name2) {
} out << " { \"" << name2
<< "\", (PyCFunction) &" << make_seq->_name << ", " << flags << ", NULL},\n";
} }
} }
@ -6335,47 +6349,88 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
void InterfaceMakerPythonNative:: void InterfaceMakerPythonNative::
write_make_seq(ostream &out, Object *obj, const std::string &ClassName, write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
const std::string &cClassName, MakeSeq *make_seq) { const std::string &cClassName, MakeSeq *make_seq) {
out << "/******************************************************************\n" << " * Python make_seq wrapper\n"; out << "/******************************************************************\n" << " * Python make_seq wrapper\n";
out << " *******************************************************************/\n"; out << " *******************************************************************/\n";
out << "static PyObject *" << make_seq->_name + "(PyObject *self, PyObject *) {\n"; out << "static PyObject *" << make_seq->_name + "(PyObject *self, PyObject *) {\n";
string element_name = methodNameFromCppName(make_seq->_element_name, ClassName, false);
// This used to be a list. But it should really be a tuple, I think, // This used to return a list. But it should really be a tuple, I
// because it probably makes more sense for it to be immutable (as // think, because it probably makes more sense for it to be immutable
// changes to it won't be visible on the C++ side anyway). // (as changes to it won't be visible on the C++ side anyway).
out << " " << cClassName << " *local_this = NULL;\n" FunctionRemap *remap = make_seq->_length_getter->_remaps.front();
<< " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n" vector_string pexprs;
<< " return NULL;\n"
<< " }\n" if (make_seq->_length_getter->_has_this) {
<< "\n" out <<
<< " PyObject *getter = PyDict_GetItemString(Dtool_" << ClassName << "._PyType.tp_dict, \"" << element_name << "\");\n" " " << cClassName << " *local_this = NULL;\n"
<< " if (getter == (PyObject *)NULL) {\n" " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n"
<< " return Dtool_Raise_AttributeError(self, \"" << element_name << "\");\n" " return NULL;\n"
<< " }\n" " }\n"
<< "\n" " Py_ssize_t count = (Py_ssize_t)" << remap->get_call_str("local_this", pexprs) << ";\n";
<< " Py_ssize_t count = (Py_ssize_t)local_this->" << make_seq->_num_name << "();\n" } else {
<< " PyObject *tuple = PyTuple_New(count);\n" out << " Py_ssize_t count = (Py_ssize_t)" << remap->get_call_str("", pexprs) << ";\n";
<< "\n" }
<< " for (Py_ssize_t i = 0; i < count; ++i) {\n"
<< "#if PY_MAJOR_VERSION >= 3\n" Function *elem_getter = make_seq->_element_getter;
<< " PyObject *index = PyLong_FromSsize_t(i);\n"
<< "#else\n" if ((elem_getter->_args_type & AT_varargs) == AT_varargs) {
<< " PyObject *index = PyInt_FromSsize_t(i);\n" // Fast way to create a temporary tuple to hold only a single item, under
<< "#endif\n" // the assumption that the called method doesn't do anything with this tuple
<< " PyObject *value = PyObject_CallFunctionObjArgs(getter, self, index, NULL);\n" // other than unpack it (which is a fairly safe assumption to make).
<< " PyTuple_SET_ITEM(tuple, i, value);\n" out << " PyTupleObject args;\n";
<< " Py_DECREF(index);\n" out << " PyObject_INIT_VAR(&args, &PyTuple_Type, 1);\n";
<< " }\n" }
<< "\n"
<< " if (Dtool_CheckErrorOccurred()) {\n" out <<
<< " Py_DECREF(tuple);\n" " PyObject *tuple = PyTuple_New(count);\n"
<< " return NULL;\n" "\n"
<< " }\n" " for (Py_ssize_t i = 0; i < count; ++i) {\n"
<< " return tuple;\n" "#if PY_MAJOR_VERSION >= 3\n"
<< "}\n" " PyObject *index = PyLong_FromSsize_t(i);\n"
<< "\n"; "#else\n"
" PyObject *index = PyInt_FromSsize_t(i);\n"
"#endif\n";
switch (elem_getter->_args_type) {
case AT_keyword_args:
out << " PyTuple_SET_ITEM(&args, 0, index);\n"
" PyObject *value = " << elem_getter->_name << "(self, (PyObject *)&args, NULL);\n";
break;
case AT_varargs:
out << " PyTuple_SET_ITEM(&args, 0, index);\n"
" PyObject *value = " << elem_getter->_name << "(self, (PyObject *)&args);\n";
break;
case AT_single_arg:
out << " PyObject *value = " << elem_getter->_name << "(self, index);\n";
break;
default:
out << " PyObject *value = " << elem_getter->_name << "(self, NULL);\n";
break;
}
out <<
" PyTuple_SET_ITEM(tuple, i, value);\n"
" Py_DECREF(index);\n"
" }\n"
"\n";
if ((elem_getter->_args_type & AT_varargs) == AT_varargs) {
out << " _Py_ForgetReference((PyObject *)&args);\n";
}
out <<
" if (Dtool_CheckErrorOccurred()) {\n"
" Py_DECREF(tuple);\n"
" return NULL;\n"
" }\n"
" return tuple;\n"
"}\n"
"\n";
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -6494,6 +6549,21 @@ record_object(TypeIndex type_index) {
} }
} }
int num_make_seqs = itype.number_of_make_seqs();
for (int msi = 0; msi < num_make_seqs; msi++) {
MakeSeqIndex make_seq_index = itype.get_make_seq(msi);
const InterrogateMakeSeq &imake_seq = idb->get_make_seq(make_seq_index);
string class_name = itype.get_scoped_name();
string clean_name = InterrogateBuilder::clean_identifier(class_name);
string wrapper_name = "MakeSeq_" + clean_name + "_" + imake_seq.get_name();
MakeSeq *make_seq = new MakeSeq(wrapper_name, imake_seq);
make_seq->_length_getter = record_function(itype, imake_seq.get_length_getter());
make_seq->_element_getter = record_function(itype, imake_seq.get_element_getter());
object->_make_seqs.push_back(make_seq);
}
object->check_protocols(); object->check_protocols();
int num_nested = itype.number_of_nested_types(); int num_nested = itype.number_of_nested_types();

View File

@ -1998,7 +1998,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
MakeSeqIndex InterrogateBuilder:: MakeSeqIndex InterrogateBuilder::
get_make_seq(CPPMakeSeq *make_seq, CPPStructType *struct_type) { get_make_seq(CPPMakeSeq *make_seq, CPPStructType *struct_type) {
string make_seq_name = struct_type->get_local_name(&parser) + "::MakeSeq_" + make_seq->_seq_name; string make_seq_name = make_seq->get_local_name(&parser);
// First, check to see if it's already there. // First, check to see if it's already there.
MakeSeqsByName::const_iterator tni = MakeSeqsByName::const_iterator tni =
@ -2008,22 +2008,80 @@ get_make_seq(CPPMakeSeq *make_seq, CPPStructType *struct_type) {
return index; return index;
} }
FunctionIndex length_getter = 0;
FunctionIndex element_getter = 0;
CPPFunctionGroup::Instances::const_iterator fi;
CPPFunctionGroup *fgroup = make_seq->_length_getter;
if (fgroup != NULL) {
for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
CPPInstance *function = (*fi);
CPPFunctionType *ftype =
function->_type->as_function_type();
if (ftype != NULL) {
length_getter = get_function(function, "", struct_type,
struct_type->get_scope(), 0);
if (length_getter != 0) {
break;
}
}
}
if (length_getter == 0) {
cerr << "No instance of length method '"
<< fgroup->_name << "' is suitable!\n";
return 0;
}
} else {
cerr << "MAKE_SEQ " << make_seq_name << " requires a length method.\n";
return 0;
}
fgroup = make_seq->_element_getter;
if (fgroup != NULL) {
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() >= 1 &&
TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
// It really doesn't matter whether we grab the const or non-const
// version, since they should all return the same function anyway.
element_getter = get_function(function, "", struct_type,
struct_type->get_scope(), 0);
if (element_getter != 0) {
break;
}
}
}
if (element_getter == 0) {
cerr << "No instance of element method '"
<< fgroup->_name << "' is suitable!\n";
return 0;
}
} else {
cerr << "MAKE_SEQ " << make_seq_name << " requires an element method.\n";
return 0;
}
InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
// It isn't here, so we'll have to define it. // It isn't here, so we'll have to define it.
MakeSeqIndex index = idb->get_next_index(); MakeSeqIndex index = idb->get_next_index();
_make_seqs_by_name[make_seq_name] = index; _make_seqs_by_name[make_seq_name] = index;
InterrogateMakeSeq imake_seq; InterrogateMakeSeq imake_seq;
imake_seq._class = get_type(struct_type, false); imake_seq._name = make_seq->get_simple_name();
imake_seq._seq_name = make_seq->_seq_name; imake_seq._scoped_name = descope(make_seq->get_local_name(&parser));
imake_seq._num_name = make_seq->_num_name;
imake_seq._element_name = make_seq->_element_name; imake_seq._length_getter = length_getter;
imake_seq._element_getter = element_getter;
// See if there happens to be a comment before the MAKE_SEQ macro.
if (make_seq->_leading_comment != (CPPCommentBlock *)NULL) {
imake_seq._comment = trim_blanks(make_seq->_leading_comment->_comment);
}
idb->add_make_seq(index, imake_seq); idb->add_make_seq(index, imake_seq);
InterrogateType &itype = idb->update_type(imake_seq._class);
itype._make_seqs.push_back(index);
return index; return index;
} }
@ -2553,6 +2611,10 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
} else if ((*di)->get_subtype() == CPPDeclaration::ST_make_property) { } else if ((*di)->get_subtype() == CPPDeclaration::ST_make_property) {
ElementIndex element_index = get_make_property((*di)->as_make_property(), cpptype); ElementIndex element_index = get_make_property((*di)->as_make_property(), cpptype);
itype._elements.push_back(element_index); itype._elements.push_back(element_index);
} else if ((*di)->get_subtype() == CPPDeclaration::ST_make_seq) {
MakeSeqIndex make_seq_index = get_make_seq((*di)->as_make_seq(), cpptype);
itype._make_seqs.push_back(make_seq_index);
} }
} }

View File

@ -20,8 +20,8 @@
InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL; InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
int InterrogateDatabase::_file_major_version = 0; int InterrogateDatabase::_file_major_version = 0;
int InterrogateDatabase::_file_minor_version = 0; int InterrogateDatabase::_file_minor_version = 0;
int InterrogateDatabase::_current_major_version = 2; int InterrogateDatabase::_current_major_version = 3;
int InterrogateDatabase::_current_minor_version = 3; int InterrogateDatabase::_current_minor_version = 0;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: InterrogateDatabase::Constructor // Function: InterrogateDatabase::Constructor

View File

@ -45,10 +45,7 @@ input(istream &in) {
InterrogateComponent::input(in); InterrogateComponent::input(in);
in >> _flags >> _type >> _getter >> _setter; in >> _flags >> _type >> _getter >> _setter;
idf_input_string(in, _scoped_name); idf_input_string(in, _scoped_name);
idf_input_string(in, _comment);
if (InterrogateDatabase::get_file_minor_version() >= 3) {
idf_input_string(in, _comment);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -93,10 +93,7 @@ input(istream &in) {
idf_input_vector(in, _c_wrappers); idf_input_vector(in, _c_wrappers);
idf_input_vector(in, _python_wrappers); idf_input_vector(in, _python_wrappers);
idf_input_string(in, _comment); idf_input_string(in, _comment);
idf_input_string(in, _prototype);
if (InterrogateDatabase::get_file_minor_version() >= 2) {
idf_input_string(in, _prototype);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,8 @@ INLINE InterrogateMakeSeq::
InterrogateMakeSeq(InterrogateModuleDef *def) : InterrogateMakeSeq(InterrogateModuleDef *def) :
InterrogateComponent(def) InterrogateComponent(def)
{ {
_class = 0; _length_getter = 0;
_element_getter = 0;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -44,52 +45,71 @@ InterrogateMakeSeq(const InterrogateMakeSeq &copy) {
INLINE void InterrogateMakeSeq:: INLINE void InterrogateMakeSeq::
operator = (const InterrogateMakeSeq &copy) { operator = (const InterrogateMakeSeq &copy) {
InterrogateComponent::operator = (copy); InterrogateComponent::operator = (copy);
_class = copy._class; _scoped_name = copy._scoped_name;
_seq_name = copy._seq_name; _comment = copy._comment;
_num_name = copy._num_name; _length_getter = copy._length_getter;
_element_name = copy._element_name; _element_getter = copy._element_getter;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: InterrogateMakeSeq::get_class // Function: InterrogateMakeSeq::has_scoped_name
// Access: Public // Access: Public
// Description: Return the class that owns the make_seq. // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE TypeIndex InterrogateMakeSeq:: INLINE bool InterrogateMakeSeq::
get_class() const { has_scoped_name() const {
return _class; return !_scoped_name.empty();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: InterrogateMakeSeq::get_seq_name // Function: InterrogateMakeSeq::get_scoped_name
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE const string &InterrogateMakeSeq:: INLINE const string &InterrogateMakeSeq::
get_seq_name() const { get_scoped_name() const {
return _seq_name; return _scoped_name;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: InterrogateMakeSeq::get_num_name // Function: InterrogateMakeSeq::has_comment
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool InterrogateMakeSeq::
has_comment() const {
return !_comment.empty();
}
////////////////////////////////////////////////////////////////////
// Function: InterrogateMakeSeq::get_comment
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE const string &InterrogateMakeSeq:: INLINE const string &InterrogateMakeSeq::
get_num_name() const { get_comment() const {
return _num_name; return _comment;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: InterrogateMakeSeq::get_element_name // Element: InterrogateMakeSeq::get_length_getter
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE const string &InterrogateMakeSeq:: INLINE FunctionIndex InterrogateMakeSeq::
get_element_name() const { get_length_getter() const {
return _element_name; return _length_getter;
} }
////////////////////////////////////////////////////////////////////
// Element: InterrogateMakeSeq::get_element_getter
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE FunctionIndex InterrogateMakeSeq::
get_element_getter() const {
return _element_getter;
}
INLINE ostream & INLINE ostream &
operator << (ostream &out, const InterrogateMakeSeq &make_seq) { operator << (ostream &out, const InterrogateMakeSeq &make_seq) {

View File

@ -25,10 +25,10 @@
void InterrogateMakeSeq:: void InterrogateMakeSeq::
output(ostream &out) const { output(ostream &out) const {
InterrogateComponent::output(out); InterrogateComponent::output(out);
out << _class << " "; out << _length_getter << " "
idf_output_string(out, _seq_name); << _element_getter << " ";
idf_output_string(out, _num_name); idf_output_string(out, _scoped_name);
idf_output_string(out, _element_name); idf_output_string(out, _comment, '\n');
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -40,10 +40,10 @@ output(ostream &out) const {
void InterrogateMakeSeq:: void InterrogateMakeSeq::
input(istream &in) { input(istream &in) {
InterrogateComponent::input(in); InterrogateComponent::input(in);
in >> _class;
idf_input_string(in, _seq_name); in >> _length_getter >> _element_getter;
idf_input_string(in, _num_name); idf_input_string(in, _scoped_name);
idf_input_string(in, _element_name); idf_input_string(in, _comment);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -55,4 +55,6 @@ input(istream &in) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void InterrogateMakeSeq:: void InterrogateMakeSeq::
remap_indices(const IndexRemapper &remap) { remap_indices(const IndexRemapper &remap) {
_length_getter = remap.map_from(_length_getter);
_element_getter = remap.map_from(_element_getter);
} }

View File

@ -32,10 +32,14 @@ public:
INLINE InterrogateMakeSeq(const InterrogateMakeSeq &copy); INLINE InterrogateMakeSeq(const InterrogateMakeSeq &copy);
INLINE void operator = (const InterrogateMakeSeq &copy); INLINE void operator = (const InterrogateMakeSeq &copy);
INLINE TypeIndex get_class() const; INLINE bool has_scoped_name() const;
INLINE const string &get_seq_name() const; INLINE const string &get_scoped_name() const;
INLINE const string &get_num_name() const;
INLINE const string &get_element_name() const; INLINE bool has_comment() const;
INLINE const string &get_comment() const;
INLINE FunctionIndex get_length_getter() const;
INLINE FunctionIndex get_element_getter() const;
void output(ostream &out) const; void output(ostream &out) const;
void input(istream &in); void input(istream &in);
@ -43,10 +47,10 @@ public:
void remap_indices(const IndexRemapper &remap); void remap_indices(const IndexRemapper &remap);
private: private:
TypeIndex _class; string _scoped_name;
string _seq_name; string _comment;
string _num_name; FunctionIndex _length_getter;
string _element_name; FunctionIndex _element_getter;
friend class InterrogateBuilder; friend class InterrogateBuilder;
}; };

View File

@ -91,9 +91,7 @@ void InterrogateType::EnumValue::
input(istream &in) { input(istream &in) {
idf_input_string(in, _name); idf_input_string(in, _name);
idf_input_string(in, _scoped_name); idf_input_string(in, _scoped_name);
if (InterrogateDatabase::get_file_minor_version() >= 3) { idf_input_string(in, _comment);
idf_input_string(in, _comment);
}
in >> _value; in >> _value;
} }

View File

@ -414,34 +414,47 @@ interrogate_get_wrapper_by_unique_name(const char *unique_name) {
return InterrogateDatabase::get_ptr()->get_wrapper_by_unique_name(unique_name); return InterrogateDatabase::get_ptr()->get_wrapper_by_unique_name(unique_name);
} }
TypeIndex
interrogate_make_seq_class(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_class(" << make_seq << ")\n";
return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_class();
}
const char * const char *
interrogate_make_seq_seq_name(MakeSeqIndex make_seq) { interrogate_make_seq_seq_name(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_seq_name(" << make_seq << ")\n"; //cerr << "interrogate_make_seq_seq_name(" << make_seq << ")\n";
static string result; static string result;
result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_seq_name(); result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_name();
return result.c_str(); return result.c_str();
} }
const char *
interrogate_make_seq_scoped_name(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_seq_name(" << make_seq << ")\n";
static string result;
result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_scoped_name();
return result.c_str();
}
bool
interrogate_make_seq_has_comment(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_has_comment(" << make_seq << ")\n";
return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).has_comment();
}
const char *
interrogate_make_seq_comment(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_comment(" << make_seq << ")\n";
return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_comment().c_str();
}
const char * const char *
interrogate_make_seq_num_name(MakeSeqIndex make_seq) { interrogate_make_seq_num_name(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_num_name(" << make_seq << ")\n"; //cerr << "interrogate_make_seq_num_name(" << make_seq << ")\n";
static string result; FunctionIndex function = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_length_getter();
result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_num_name(); return interrogate_function_name(function);
return result.c_str();
} }
const char * const char *
interrogate_make_seq_element_name(MakeSeqIndex make_seq) { interrogate_make_seq_element_name(MakeSeqIndex make_seq) {
//cerr << "interrogate_make_seq_element_name(" << make_seq << ")\n"; //cerr << "interrogate_make_seq_element_name(" << make_seq << ")\n";
static string result; static string result;
result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_element_name(); FunctionIndex function = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_element_getter();
return result.c_str(); return interrogate_function_name(function);
} }
int int

View File

@ -363,11 +363,10 @@ EXPCL_INTERROGATEDB FunctionWrapperIndex interrogate_get_wrapper_by_unique_name(
// and get_thing(n) are used to synthesize a new method called // and get_thing(n) are used to synthesize a new method called
// get_things(). // get_things().
// The class of which the make_seq is a method.
EXPCL_INTERROGATEDB TypeIndex interrogate_make_seq_class(MakeSeqIndex make_seq);
// The name of the syntheized method, e.g. "get_things"
EXPCL_INTERROGATEDB const char *interrogate_make_seq_seq_name(MakeSeqIndex make_seq); EXPCL_INTERROGATEDB const char *interrogate_make_seq_seq_name(MakeSeqIndex make_seq);
EXPCL_INTERROGATEDB const char *interrogate_make_seq_scoped_name(MakeSeqIndex make_seq);
EXPCL_INTERROGATEDB bool interrogate_make_seq_has_comment(ElementIndex element);
EXPCL_INTERROGATEDB const char *interrogate_make_seq_comment(ElementIndex element);
// The name of the real method that returns the length, e.g. "get_num_things" // The name of the real method that returns the length, e.g. "get_num_things"
EXPCL_INTERROGATEDB const char *interrogate_make_seq_num_name(MakeSeqIndex make_seq); EXPCL_INTERROGATEDB const char *interrogate_make_seq_num_name(MakeSeqIndex make_seq);
// The name of the real method that returns the nth element, e.g. "get_thing" // The name of the real method that returns the nth element, e.g. "get_thing"

View File

@ -67,7 +67,7 @@ PUBLISHED:
INLINE PN_stdfloat get_sample_t(int n) const; INLINE PN_stdfloat get_sample_t(int n) const;
INLINE const LPoint3 &get_sample_point(int n) const; INLINE const LPoint3 &get_sample_point(int n) const;
MAKE_SEQ(get_sample_ts, get_num_samples, get_sample_t); MAKE_SEQ(get_sample_ts, get_num_samples, get_sample_t);
MAKE_SEQ(get_sample_points, get_num_samples, get_sample_points); MAKE_SEQ(get_sample_points, get_num_samples, get_sample_point);
private: private:
int find_segment(PN_stdfloat t); int find_segment(PN_stdfloat t);