Fixed bug where calling 'clear all' only once caused a problem where the wrap module recreated the RTTI table but MATLAB then deletes it, causing an error about the RTTI table being missing later on.

release/4.3a0
Richard Roberts 2012-07-17 19:49:36 +00:00
parent 4b772b43cf
commit b5e10eadb8
1 changed files with 47 additions and 30 deletions

View File

@ -14,7 +14,7 @@
* @author Frank Dellaert * @author Frank Dellaert
* @author Alex Cunningham * @author Alex Cunningham
* @author Andrew Melim * @author Andrew Melim
* @author Richard Roberts * @author Richard Roberts
**/ **/
#include "Module.h" #include "Module.h"
@ -463,12 +463,9 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co
void Module::finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const { void Module::finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const {
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
file.oss << "{\n"; file.oss << "{\n";
file.oss << " mstream mout;\n"; // Send stdout to MATLAB console, see matlab.h file.oss << " mstream mout;\n"; // Send stdout to MATLAB console
file.oss << " std::streambuf *outbuf = std::cout.rdbuf(&mout);\n\n"; file.oss << " std::streambuf *outbuf = std::cout.rdbuf(&mout);\n\n";
file.oss << " if(!_RTTIRegister_" << name << "_done) {\n"; file.oss << " _" << name << "_RTTIRegister();\n\n";
file.oss << " _" << name << "_RTTIRegister();\n";
file.oss << " _RTTIRegister_" << name << "_done = true;\n";
file.oss << " }\n";
file.oss << " int id = unwrap<int>(in[0]);\n\n"; file.oss << " int id = unwrap<int>(in[0]);\n\n";
file.oss << " switch(id) {\n"; file.oss << " switch(id) {\n";
for(size_t id = 0; id < functionNames.size(); ++id) { for(size_t id = 0; id < functionNames.size(); ++id) {
@ -478,7 +475,7 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co
} }
file.oss << " }\n"; file.oss << " }\n";
file.oss << "\n"; file.oss << "\n";
file.oss << " std::cout.rdbuf(outbuf);\n"; // Restore cout, see matlab.h file.oss << " std::cout.rdbuf(outbuf);\n"; // Restore cout
file.oss << "}\n"; file.oss << "}\n";
} }
@ -538,50 +535,70 @@ void Module::WriteCollectorsAndCleanupFcn(FileWriter& wrapperFile, const std::st
} }
// generate mexAtExit cleanup function // generate mexAtExit cleanup function
wrapperFile.oss << "\nvoid _deleteAllObjects()\n"; wrapperFile.oss <<
wrapperFile.oss << "{\n"; "\nvoid _deleteAllObjects()\n"
"{\n"
" mstream mout;\n" // Send stdout to MATLAB console
" std::streambuf *outbuf = std::cout.rdbuf(&mout);\n\n"
" bool anyDeleted = false;\n";
BOOST_FOREACH(const Class& cls, classes) { BOOST_FOREACH(const Class& cls, classes) {
const string matlabName = cls.qualifiedName(); const string matlabName = cls.qualifiedName();
const string cppName = cls.qualifiedName("::"); const string cppName = cls.qualifiedName("::");
const string collectorType = "Collector_" + matlabName; const string collectorType = "Collector_" + matlabName;
const string collectorName = "collector_" + matlabName; const string collectorName = "collector_" + matlabName;
wrapperFile.oss << " for(" << collectorType << "::iterator iter = " << collectorName << ".begin();\n"; wrapperFile.oss <<
wrapperFile.oss << " iter != " << collectorName << ".end(); ) {\n"; " for(" << collectorType << "::iterator iter = " << collectorName << ".begin();\n"
wrapperFile.oss << " delete *iter;\n"; " iter != " << collectorName << ".end(); ) {\n"
wrapperFile.oss << " " << collectorName << ".erase(iter++);\n"; " delete *iter;\n"
wrapperFile.oss << " }\n"; " " << collectorName << ".erase(iter++);\n"
" anyDeleted = true;\n"
" }\n";
} }
wrapperFile.oss << "}\n\n"; wrapperFile.oss <<
" if(anyDeleted)\n"
" cout <<\n"
" \"WARNING: Wrap modules with variables in the workspace have been reloaded due to\\n\"\n"
" \"calling destructors, call 'clear all' again if you plan to now recompile a wrap\\n\"\n"
" \"module, so that your recompiled module is used instead of the old one.\" << endl;\n"
" std::cout.rdbuf(outbuf);\n" // Restore cout
"}\n\n";
} }
/* ************************************************************************* */ /* ************************************************************************* */
void Module::WriteRTTIRegistry(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes) { void Module::WriteRTTIRegistry(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes) {
wrapperFile.oss << wrapperFile.oss <<
"static bool _RTTIRegister_" << moduleName << "_done = false;\n"
"void _" << moduleName << "_RTTIRegister() {\n" "void _" << moduleName << "_RTTIRegister() {\n"
" std::map<std::string, std::string> types;\n"; " const mxArray *alreadyCreated = mexGetVariablePtr(\"global\", \"gtsam_" + moduleName + "_rttiRegistry_created\");\n"
" if(!alreadyCreated) {\n"
" std::map<std::string, std::string> types;\n";
BOOST_FOREACH(const Class& cls, classes) { BOOST_FOREACH(const Class& cls, classes) {
if(cls.isVirtual) if(cls.isVirtual)
wrapperFile.oss << wrapperFile.oss <<
" types.insert(std::make_pair(typeid(" << cls.qualifiedName("::") << ").name(), \"" << cls.qualifiedName() << "\"));\n"; " types.insert(std::make_pair(typeid(" << cls.qualifiedName("::") << ").name(), \"" << cls.qualifiedName() << "\"));\n";
} }
wrapperFile.oss << "\n"; wrapperFile.oss << "\n";
wrapperFile.oss << wrapperFile.oss <<
" mxArray *registry = mexGetVariable(\"global\", \"gtsamwrap_rttiRegistry\");\n" " mxArray *registry = mexGetVariable(\"global\", \"gtsamwrap_rttiRegistry\");\n"
" if(!registry)\n" " if(!registry)\n"
" registry = mxCreateStructMatrix(1, 1, 0, NULL);\n" " registry = mxCreateStructMatrix(1, 1, 0, NULL);\n"
" typedef std::pair<std::string, std::string> StringPair;\n" " typedef std::pair<std::string, std::string> StringPair;\n"
" BOOST_FOREACH(const StringPair& rtti_matlab, types) {\n" " BOOST_FOREACH(const StringPair& rtti_matlab, types) {\n"
" int fieldId = mxAddField(registry, rtti_matlab.first.c_str());\n" " int fieldId = mxAddField(registry, rtti_matlab.first.c_str());\n"
" if(fieldId < 0)\n" " if(fieldId < 0)\n"
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
" mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());\n"
" mxSetFieldByNumber(registry, 0, fieldId, matlabName);\n"
" }\n"
" if(mexPutVariable(\"global\", \"gtsamwrap_rttiRegistry\", registry) != 0)\n"
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n" " mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
" mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());\n" " mxDestroyArray(registry);\n"
" mxSetFieldByNumber(registry, 0, fieldId, matlabName);\n" " \n"
" mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);\n"
" if(mexPutVariable(\"global\", \"gtsam_" + moduleName + "_rttiRegistry_created\", newAlreadyCreated) != 0)\n"
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
" mxDestroyArray(newAlreadyCreated);\n"
" }\n" " }\n"
" if(mexPutVariable(\"global\", \"gtsamwrap_rttiRegistry\", registry) != 0)\n"
" mexErrMsgTxt(\"gtsam wrap: Error indexing RTTI types, inheritance will not work correctly\");\n"
" mxDestroyArray(registry);\n"
"}\n" "}\n"
"\n"; "\n";
} }