169 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Python
		
	
	
		
		
			
		
	
	
			169 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Python
		
	
	
|  | """Code generation templates for the Matlab wrapper.""" | ||
|  | 
 | ||
|  | import textwrap | ||
|  | 
 | ||
|  | 
 | ||
|  | class WrapperTemplate: | ||
|  |     """Class to encapsulate string templates for use in wrapper generation""" | ||
|  |     boost_headers = textwrap.dedent("""
 | ||
|  |             #include <boost/archive/text_iarchive.hpp> | ||
|  |             #include <boost/archive/text_oarchive.hpp> | ||
|  |             #include <boost/serialization/export.hpp> | ||
|  |         """)
 | ||
|  | 
 | ||
|  |     typdef_collectors = textwrap.dedent('''\
 | ||
|  |                 typedef std::set<std::shared_ptr<{class_name_sep}>*> Collector_{class_name}; | ||
|  |                 static Collector_{class_name} collector_{class_name}; | ||
|  |             ''')
 | ||
|  | 
 | ||
|  |     delete_obj = textwrap.indent(textwrap.dedent('''\
 | ||
|  |                 {{ for(Collector_{class_name}::iterator iter = collector_{class_name}.begin(); | ||
|  |                     iter != collector_{class_name}.end(); ) {{ | ||
|  |                   delete *iter; | ||
|  |                   collector_{class_name}.erase(iter++); | ||
|  |                   anyDeleted = true; | ||
|  |                 }} }} | ||
|  |             '''),
 | ||
|  |                                  prefix='  ') | ||
|  | 
 | ||
|  |     delete_all_objects = textwrap.dedent('''
 | ||
|  |             void _deleteAllObjects() | ||
|  |             {{ | ||
|  |               mstream mout; | ||
|  |               std::streambuf *outbuf = std::cout.rdbuf(&mout);\n | ||
|  |               bool anyDeleted = false; | ||
|  |             {delete_objs} | ||
|  |               if(anyDeleted) | ||
|  |                 cout << | ||
|  |                   "WARNING:  Wrap modules with variables in the workspace have been reloaded due to\\n" | ||
|  |                   "calling destructors, call \'clear all\' again if you plan to now recompile a wrap\\n" | ||
|  |                   "module, so that your recompiled module is used instead of the old one." << endl; | ||
|  |               std::cout.rdbuf(outbuf); | ||
|  |             }} | ||
|  |         ''')
 | ||
|  | 
 | ||
|  |     rtti_register = textwrap.dedent('''\
 | ||
|  |             void _{module_name}_RTTIRegister() {{ | ||
|  |               const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_{module_name}_rttiRegistry_created"); | ||
|  |               if(!alreadyCreated) {{ | ||
|  |                 std::map<std::string, std::string> types; | ||
|  | 
 | ||
|  |             {rtti_classes} | ||
|  | 
 | ||
|  |                 mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry"); | ||
|  |                 if(!registry) | ||
|  |                   registry = mxCreateStructMatrix(1, 1, 0, NULL); | ||
|  |                 typedef std::pair<std::string, std::string> StringPair; | ||
|  |                 for(const StringPair& rtti_matlab: types) {{ | ||
|  |                   int fieldId = mxAddField(registry, rtti_matlab.first.c_str()); | ||
|  |                   if(fieldId < 0) {{ | ||
|  |                     mexErrMsgTxt("gtsam wrap:  Error indexing RTTI types, inheritance will not work correctly"); | ||
|  |                   }} | ||
|  |                   mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str()); | ||
|  |                   mxSetFieldByNumber(registry, 0, fieldId, matlabName); | ||
|  |                 }} | ||
|  |                 if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {{ | ||
|  |                   mexErrMsgTxt("gtsam wrap:  Error indexing RTTI types, inheritance will not work correctly"); | ||
|  |                 }} | ||
|  |                 mxDestroyArray(registry); | ||
|  | 
 | ||
|  |                 mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL); | ||
|  |                 if(mexPutVariable("global", "gtsam_{module_name}_rttiRegistry_created", newAlreadyCreated) != 0) {{ | ||
|  |                   mexErrMsgTxt("gtsam wrap:  Error indexing RTTI types, inheritance will not work correctly"); | ||
|  |                 }} | ||
|  |                 mxDestroyArray(newAlreadyCreated); | ||
|  |               }} | ||
|  |             }} | ||
|  |         ''')
 | ||
|  | 
 | ||
|  |     collector_function_upcast_from_void = textwrap.dedent('''\
 | ||
|  |             void {class_name}_upcastFromVoid_{id}(int nargout, mxArray *out[], int nargin, const mxArray *in[]) {{ | ||
|  |               mexAtExit(&_deleteAllObjects); | ||
|  |               typedef std::shared_ptr<{cpp_name}> Shared; | ||
|  |               std::shared_ptr<void> *asVoid = *reinterpret_cast<std::shared_ptr<void>**> (mxGetData(in[0])); | ||
|  |               out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); | ||
|  |               Shared *self = new Shared(std::static_pointer_cast<{cpp_name}>(*asVoid)); | ||
|  |               *reinterpret_cast<Shared**>(mxGetData(out[0])) = self; | ||
|  |             }}\n | ||
|  |         ''')
 | ||
|  | 
 | ||
|  |     class_serialize_method = textwrap.dedent('''\
 | ||
|  |             function varargout = string_serialize(this, varargin) | ||
|  |               % STRING_SERIALIZE usage: string_serialize() : returns string | ||
|  |               % Doxygen can be found at https://gtsam.org/doxygen/ | ||
|  |               if length(varargin) == 0 | ||
|  |                 varargout{{1}} = {wrapper}({wrapper_id}, this, varargin{{:}}); | ||
|  |               else | ||
|  |                 error('Arguments do not match any overload of function {class_name}.string_serialize'); | ||
|  |               end | ||
|  |             end\n | ||
|  |             function sobj = saveobj(obj) | ||
|  |               % SAVEOBJ Saves the object to a matlab-readable format | ||
|  |               sobj = obj.string_serialize(); | ||
|  |             end | ||
|  |         ''')
 | ||
|  | 
 | ||
|  |     collector_function_serialize = textwrap.indent(textwrap.dedent("""\
 | ||
|  |             typedef std::shared_ptr<{full_name}> Shared; | ||
|  |             checkArguments("string_serialize",nargout,nargin-1,0); | ||
|  |             Shared obj = unwrap_shared_ptr<{full_name}>(in[0], "ptr_{namespace}{class_name}"); | ||
|  |             ostringstream out_archive_stream; | ||
|  |             boost::archive::text_oarchive out_archive(out_archive_stream); | ||
|  |             out_archive << *obj; | ||
|  |             out[0] = wrap< string >(out_archive_stream.str()); | ||
|  |         """),
 | ||
|  |                                                    prefix='  ') | ||
|  | 
 | ||
|  |     collector_function_deserialize = textwrap.indent(textwrap.dedent("""\
 | ||
|  |             typedef std::shared_ptr<{full_name}> Shared; | ||
|  |             checkArguments("{namespace}{class_name}.string_deserialize",nargout,nargin,1); | ||
|  |             string serialized = unwrap< string >(in[0]); | ||
|  |             istringstream in_archive_stream(serialized); | ||
|  |             boost::archive::text_iarchive in_archive(in_archive_stream); | ||
|  |             Shared output(new {full_name}()); | ||
|  |             in_archive >> *output; | ||
|  |             out[0] = wrap_shared_ptr(output,"{namespace}.{class_name}", false); | ||
|  |         """),
 | ||
|  |                                                      prefix='  ') | ||
|  | 
 | ||
|  |     mex_function = textwrap.dedent('''
 | ||
|  |             void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) | ||
|  |             {{ | ||
|  |               mstream mout; | ||
|  |               std::streambuf *outbuf = std::cout.rdbuf(&mout);\n | ||
|  |               _{module_name}_RTTIRegister();\n | ||
|  |               int id = unwrap<int>(in[0]);\n | ||
|  |               try {{ | ||
|  |                 switch(id) {{ | ||
|  |             {cases}    }} | ||
|  |               }} catch(const std::exception& e) {{ | ||
|  |                 mexErrMsgTxt(("Exception from gtsam:\\n" + std::string(e.what()) + "\\n").c_str()); | ||
|  |               }}\n | ||
|  |               std::cout.rdbuf(outbuf); | ||
|  |             }} | ||
|  |         ''')
 | ||
|  | 
 | ||
|  |     collector_function_shared_return = textwrap.indent(textwrap.dedent('''\
 | ||
|  |             {{ | ||
|  |             std::shared_ptr<{name}> shared({shared_obj}); | ||
|  |             out[{id}] = wrap_shared_ptr(shared,"{name}"); | ||
|  |             }}{new_line}'''),
 | ||
|  |                                                        prefix='  ') | ||
|  | 
 | ||
|  |     matlab_deserialize = textwrap.indent(textwrap.dedent("""\
 | ||
|  |                 function varargout = string_deserialize(varargin) | ||
|  |                   % STRING_DESERIALIZE usage: string_deserialize() : returns {class_name} | ||
|  |                   % Doxygen can be found at https://gtsam.org/doxygen/ | ||
|  |                   if length(varargin) == 1 | ||
|  |                     varargout{{1}} = {wrapper}({id}, varargin{{:}}); | ||
|  |                   else | ||
|  |                     error('Arguments do not match any overload of function {class_name}.string_deserialize'); | ||
|  |                   end | ||
|  |                 end\n | ||
|  |                 function obj = loadobj(sobj) | ||
|  |                   % LOADOBJ Saves the object to a matlab-readable format | ||
|  |                   obj = {class_name}.string_deserialize(sobj); | ||
|  |                 end | ||
|  |             """),
 | ||
|  |                                          prefix='  ') |