wrap_mods_inheritance branch: in progress with inheritance in matlab wrapper
parent
c1ef79722b
commit
3c27daae18
13
gtsam.h
13
gtsam.h
|
@ -64,7 +64,18 @@ namespace gtsam {
|
||||||
// base
|
// base
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
class LieVector {
|
class Value {
|
||||||
|
// Testable
|
||||||
|
void print(string s) const;
|
||||||
|
bool equals(const gtsam::Value& expected, double tol) const;
|
||||||
|
|
||||||
|
// Manifold
|
||||||
|
size_t dim() const;
|
||||||
|
gtsam::Value retract(Vector v) const;
|
||||||
|
Vector localCoordinates(const gtsam::Value& t2) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LieVector : gtsam::Value {
|
||||||
// Standard constructors
|
// Standard constructors
|
||||||
LieVector();
|
LieVector();
|
||||||
LieVector(Vector v);
|
LieVector(Vector v);
|
||||||
|
|
|
@ -64,7 +64,7 @@ void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
|
||||||
file.oss << cppType << " " << name << " = unwrap< ";
|
file.oss << cppType << " " << name << " = unwrap< ";
|
||||||
|
|
||||||
file.oss << cppType << " >(" << matlabName;
|
file.oss << cppType << " >(" << matlabName;
|
||||||
if (is_ptr || is_ref) file.oss << ", \"" << matlabType << "\"";
|
if (is_ptr || is_ref) file.oss << ", \"ptr_" << matlabType << "\"";
|
||||||
file.oss << ");" << endl;
|
file.oss << ");" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,11 @@ void Class::matlab_proxy(const string& classFile, const string& wrapperName, Fil
|
||||||
|
|
||||||
// emit class proxy code
|
// emit class proxy code
|
||||||
// we want our class to inherit the handle class for memory purposes
|
// we want our class to inherit the handle class for memory purposes
|
||||||
proxyFile.oss << "classdef " << matlabName << " < handle" << endl;
|
const string parent = qualifiedParent.empty() ?
|
||||||
|
"handle" : ::wrap::qualifiedName("", qualifiedParent);
|
||||||
|
proxyFile.oss << "classdef " << matlabName << " < " << parent << endl;
|
||||||
proxyFile.oss << " properties" << endl;
|
proxyFile.oss << " properties" << endl;
|
||||||
proxyFile.oss << " self = 0" << endl;
|
proxyFile.oss << " ptr_" << matlabName << " = 0" << endl;
|
||||||
proxyFile.oss << " end" << endl;
|
proxyFile.oss << " end" << endl;
|
||||||
proxyFile.oss << " methods" << endl;
|
proxyFile.oss << " methods" << endl;
|
||||||
|
|
||||||
|
@ -116,10 +118,7 @@ void Class::matlab_proxy(const string& classFile, const string& wrapperName, Fil
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
string Class::qualifiedName(const string& delim) const {
|
string Class::qualifiedName(const string& delim) const {
|
||||||
string result;
|
return ::wrap::qualifiedName(delim, namespaces, name);
|
||||||
BOOST_FOREACH(const string& ns, namespaces)
|
|
||||||
result += ns + delim;
|
|
||||||
return result + name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -136,14 +135,14 @@ string Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& w
|
||||||
(uint64_t('r'));
|
(uint64_t('r'));
|
||||||
|
|
||||||
const string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
const string matlabName = qualifiedName(), cppName = qualifiedName("::");
|
||||||
const string wrapFunctionName = matlabName + "_constructor_" + boost::lexical_cast<string>(id);
|
const string wrapFunctionName = matlabName + "_collectorInsert_" + boost::lexical_cast<string>(id);
|
||||||
|
|
||||||
// MATLAB constructor that assigns pointer to matlab object then calls c++
|
// MATLAB constructor that assigns pointer to matlab object then calls c++
|
||||||
// function to add the object to the collector.
|
// function to add the object to the collector.
|
||||||
proxyFile.oss << " if nargin == 2 && isa(varargin{1}, 'uint64') && ";
|
proxyFile.oss << " if nargin == 2 && isa(varargin{1}, 'uint64') && ";
|
||||||
proxyFile.oss << "varargin{1} == uint64(" << ptr_constructor_key << ")\n";
|
proxyFile.oss << "varargin{1} == uint64(" << ptr_constructor_key << ")\n";
|
||||||
proxyFile.oss << " obj.self = varargin{2};\n";
|
proxyFile.oss << " obj.self = varargin{2};\n";
|
||||||
proxyFile.oss << " " << wrapperName << "(obj.self);\n";
|
proxyFile.oss << " " << wrapperName << "(" << id << ", obj.self);\n";
|
||||||
|
|
||||||
// C++ function to add pointer from MATLAB to collector. The pointer always
|
// C++ function to add pointer from MATLAB to collector. The pointer always
|
||||||
// comes from a C++ return value; this mechanism allows the object to be added
|
// comes from a C++ return value; this mechanism allows the object to be added
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct Class {
|
||||||
|
|
||||||
// Then the instance variables are set directly by the Module constructor
|
// Then the instance variables are set directly by the Module constructor
|
||||||
std::string name; ///< Class name
|
std::string name; ///< Class name
|
||||||
|
std::vector<std::string> qualifiedParent; ///< The *single* parent - the last string is the parent class name, preceededing elements are a namespace stack
|
||||||
Methods methods; ///< Class methods
|
Methods methods; ///< Class methods
|
||||||
StaticMethods static_methods; ///< Static methods
|
StaticMethods static_methods; ///< Static methods
|
||||||
std::vector<std::string> namespaces; ///< Stack of namespaces
|
std::vector<std::string> namespaces; ///< Stack of namespaces
|
||||||
|
|
|
@ -53,7 +53,7 @@ void Constructor::proxy_fragment(FileWriter& file, const std::string& wrapperNam
|
||||||
file.oss << "\n obj.self = " << wrapperName << "(" << id;
|
file.oss << "\n obj.self = " << wrapperName << "(" << id;
|
||||||
// emit constructor arguments
|
// emit constructor arguments
|
||||||
for(size_t i=0;i<nrArgs;i++) {
|
for(size_t i=0;i<nrArgs;i++) {
|
||||||
file.oss << ",";
|
file.oss << ", ";
|
||||||
file.oss << "varargin{" << i+1 << "}";
|
file.oss << "varargin{" << i+1 << "}";
|
||||||
}
|
}
|
||||||
file.oss << ");\n";
|
file.oss << ");\n";
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF
|
||||||
const vector<string>& using_namespaces,
|
const vector<string>& using_namespaces,
|
||||||
vector<string>& functionNames) const {
|
vector<string>& functionNames) const {
|
||||||
|
|
||||||
proxyFile.oss << " function varargout = " << name << "(self, varargin)\n";
|
proxyFile.oss << " function varargout = " << name << "(this, varargin)\n";
|
||||||
|
|
||||||
for(size_t overload = 0; overload < argLists.size(); ++overload) {
|
for(size_t overload = 0; overload < argLists.size(); ++overload) {
|
||||||
const ArgumentList& args = argLists[overload];
|
const ArgumentList& args = argLists[overload];
|
||||||
|
@ -74,7 +74,7 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF
|
||||||
output = "";
|
output = "";
|
||||||
else
|
else
|
||||||
output = "varargout{1} = ";
|
output = "varargout{1} = ";
|
||||||
proxyFile.oss << " " << output << wrapperName << "(" << id << ", self, varargin{:});\n";
|
proxyFile.oss << " " << output << wrapperName << "(" << id << ", this, varargin{:});\n";
|
||||||
|
|
||||||
// Output C++ wrapper code
|
// Output C++ wrapper code
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ string Method::wrapper_fragment(FileWriter& file,
|
||||||
|
|
||||||
// get class pointer
|
// get class pointer
|
||||||
// example: shared_ptr<Test> = unwrap_shared_ptr< Test >(in[0], "Test");
|
// example: shared_ptr<Test> = unwrap_shared_ptr< Test >(in[0], "Test");
|
||||||
file.oss << " Shared obj = unwrap_shared_ptr<" << cppClassName << ">(in[0], \"" << cppClassName << "\");" << endl;
|
file.oss << " Shared obj = unwrap_shared_ptr<" << cppClassName << ">(in[0], \"ptr_" << matlabClassName << "\");" << endl;
|
||||||
// unwrap arguments, see Argument.cpp
|
// unwrap arguments, see Argument.cpp
|
||||||
args.matlab_unwrap(file,1);
|
args.matlab_unwrap(file,1);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ Module::Module(const string& interfacePath,
|
||||||
Rule eigenType_p =
|
Rule eigenType_p =
|
||||||
(str_p("Vector") | "Matrix");
|
(str_p("Vector") | "Matrix");
|
||||||
|
|
||||||
Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p)[assign_a(class_name)];
|
Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p);
|
||||||
|
|
||||||
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
|
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
|
||||||
|
|
||||||
|
@ -114,6 +114,10 @@ Module::Module(const string& interfacePath,
|
||||||
className_p[assign_a(arg.type)] >>
|
className_p[assign_a(arg.type)] >>
|
||||||
(ch_p('*')[assign_a(arg.is_ptr,true)] | ch_p('&')[assign_a(arg.is_ref,true)]);
|
(ch_p('*')[assign_a(arg.is_ptr,true)] | ch_p('&')[assign_a(arg.is_ref,true)]);
|
||||||
|
|
||||||
|
Rule classParent_p =
|
||||||
|
*(namespace_name_p[push_back_a(cls.qualifiedParent)] >> str_p("::")) >>
|
||||||
|
className_p[push_back_a(cls.qualifiedParent)];
|
||||||
|
|
||||||
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')];
|
||||||
|
|
||||||
Rule argument_p =
|
Rule argument_p =
|
||||||
|
@ -198,7 +202,7 @@ Module::Module(const string& interfacePath,
|
||||||
(!*include_p
|
(!*include_p
|
||||||
>> str_p("class")[push_back_a(cls.includes, include_path)][assign_a(include_path, null_str)]
|
>> str_p("class")[push_back_a(cls.includes, include_path)][assign_a(include_path, null_str)]
|
||||||
>> className_p[assign_a(cls.name)]
|
>> className_p[assign_a(cls.name)]
|
||||||
>> '{'
|
>> ((':' >> classParent_p >> '{') | '{') // By having (parent >> '{' | '{') here instead of (!parent >> '{'), we trigger a parse error on a badly-formed parent spec
|
||||||
>> *(functions_p | comments_p)
|
>> *(functions_p | comments_p)
|
||||||
>> str_p("};"))
|
>> str_p("};"))
|
||||||
[assign_a(constructor.name, cls.name)]
|
[assign_a(constructor.name, cls.name)]
|
||||||
|
|
|
@ -342,9 +342,14 @@ gtsam::Matrix unwrap< gtsam::Matrix >(const mxArray* array) {
|
||||||
[create_object] creates a MATLAB proxy class object with a mexhandle
|
[create_object] creates a MATLAB proxy class object with a mexhandle
|
||||||
in the self property. Matlab does not allow the creation of matlab
|
in the self property. Matlab does not allow the creation of matlab
|
||||||
objects from within mex files, hence we resort to an ugly trick: we
|
objects from within mex files, hence we resort to an ugly trick: we
|
||||||
invoke the proxy class constructor by calling MATLAB, and pass 13
|
invoke the proxy class constructor by calling MATLAB with a special
|
||||||
dummy arguments to let the constructor know we want an object without
|
uint64 value ptr_constructor_key and the pointer itself. MATLAB
|
||||||
the self property initialized. We then assign the mexhandle to self.
|
allocates the object. Then, the special constructor in our wrap code
|
||||||
|
that is activated when the ptr_constructor_key is passed in passes
|
||||||
|
the pointer back into a C++ function to add the pointer to its
|
||||||
|
collector. We go through this extra "C++ to MATLAB to C++ step" in
|
||||||
|
order to be able to add to the collector could be in a different wrap
|
||||||
|
module.
|
||||||
*/
|
*/
|
||||||
mxArray* create_object(const char *classname, void *pointer) {
|
mxArray* create_object(const char *classname, void *pointer) {
|
||||||
mxArray *result;
|
mxArray *result;
|
||||||
|
@ -376,9 +381,9 @@ mxArray* wrap_shared_ptr(boost::shared_ptr< Class >* shared_ptr, const char *cla
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Class>
|
template <typename Class>
|
||||||
boost::shared_ptr<Class> unwrap_shared_ptr(const mxArray* obj, const string& className) {
|
boost::shared_ptr<Class> unwrap_shared_ptr(const mxArray* obj, const string& propertyName) {
|
||||||
|
|
||||||
mxArray* mxh = mxGetProperty(obj,0,"self");
|
mxArray* mxh = mxGetProperty(obj,0, propertyName);
|
||||||
if (mxGetClassID(mxh) != mxUINT32OR64_CLASS || mxIsComplex(mxh)
|
if (mxGetClassID(mxh) != mxUINT32OR64_CLASS || mxIsComplex(mxh)
|
||||||
|| mxGetM(mxh) != 1 || mxGetN(mxh) != 1) error(
|
|| mxGetM(mxh) != 1 || mxGetN(mxh) != 1) error(
|
||||||
"Parameter is not an Shared type.");
|
"Parameter is not an Shared type.");
|
||||||
|
|
|
@ -135,6 +135,17 @@ void generateIncludes(FileWriter& file, const string& class_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
string qualifiedName(const string& separator, const vector<string>& names, const string& finalName) {
|
||||||
|
string result;
|
||||||
|
for(size_t i = 0; i < names.size() - 1; ++i)
|
||||||
|
result += (names[i] + separator);
|
||||||
|
if(finalName.empty())
|
||||||
|
result += names.back();
|
||||||
|
else
|
||||||
|
result += (names.back() + separator + finalName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
|
@ -98,4 +98,10 @@ void generateUsingNamespace(FileWriter& file, const std::vector<std::string>& us
|
||||||
void generateIncludes(FileWriter& file, const std::string& class_name,
|
void generateIncludes(FileWriter& file, const std::string& class_name,
|
||||||
const std::vector<std::string>& includes);
|
const std::vector<std::string>& includes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a qualified name, if finalName is empty, only the names vector will
|
||||||
|
* be used (i.e. there won't be a trailing separator on the qualified name).
|
||||||
|
*/
|
||||||
|
std::string qualifiedName(const std::string& separator, const std::vector<std::string>& names, const std::string& finalName = "");
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
Loading…
Reference in New Issue