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
|
||||
//*************************************************************************
|
||||
|
||||
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
|
||||
LieVector();
|
||||
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 << " >(" << matlabName;
|
||||
if (is_ptr || is_ref) file.oss << ", \"" << matlabType << "\"";
|
||||
if (is_ptr || is_ref) file.oss << ", \"ptr_" << matlabType << "\"";
|
||||
file.oss << ");" << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,11 @@ void Class::matlab_proxy(const string& classFile, const string& wrapperName, Fil
|
|||
|
||||
// emit class proxy code
|
||||
// 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 << " self = 0" << endl;
|
||||
proxyFile.oss << " ptr_" << matlabName << " = 0" << endl;
|
||||
proxyFile.oss << " end" << 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 result;
|
||||
BOOST_FOREACH(const string& ns, namespaces)
|
||||
result += ns + delim;
|
||||
return result + name;
|
||||
return ::wrap::qualifiedName(delim, namespaces, name);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -136,14 +135,14 @@ string Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& w
|
|||
(uint64_t('r'));
|
||||
|
||||
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++
|
||||
// function to add the object to the collector.
|
||||
proxyFile.oss << " if nargin == 2 && isa(varargin{1}, 'uint64') && ";
|
||||
proxyFile.oss << "varargin{1} == uint64(" << ptr_constructor_key << ")\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
|
||||
// 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
|
||||
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
|
||||
StaticMethods static_methods; ///< Static methods
|
||||
std::vector<std::string> namespaces; ///< Stack of namespaces
|
||||
|
|
|
@ -43,7 +43,7 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF
|
|||
const vector<string>& using_namespaces,
|
||||
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) {
|
||||
const ArgumentList& args = argLists[overload];
|
||||
|
@ -74,7 +74,7 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF
|
|||
output = "";
|
||||
else
|
||||
output = "varargout{1} = ";
|
||||
proxyFile.oss << " " << output << wrapperName << "(" << id << ", self, varargin{:});\n";
|
||||
proxyFile.oss << " " << output << wrapperName << "(" << id << ", this, varargin{:});\n";
|
||||
|
||||
// Output C++ wrapper code
|
||||
|
||||
|
@ -135,7 +135,7 @@ string Method::wrapper_fragment(FileWriter& file,
|
|||
|
||||
// get class pointer
|
||||
// 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
|
||||
args.matlab_unwrap(file,1);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ Module::Module(const string& interfacePath,
|
|||
Rule eigenType_p =
|
||||
(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;
|
||||
|
||||
|
@ -114,6 +114,10 @@ Module::Module(const string& interfacePath,
|
|||
className_p[assign_a(arg.type)] >>
|
||||
(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 argument_p =
|
||||
|
@ -198,7 +202,7 @@ Module::Module(const string& interfacePath,
|
|||
(!*include_p
|
||||
>> str_p("class")[push_back_a(cls.includes, include_path)][assign_a(include_path, null_str)]
|
||||
>> 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)
|
||||
>> str_p("};"))
|
||||
[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
|
||||
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
|
||||
invoke the proxy class constructor by calling MATLAB, and pass 13
|
||||
dummy arguments to let the constructor know we want an object without
|
||||
the self property initialized. We then assign the mexhandle to self.
|
||||
invoke the proxy class constructor by calling MATLAB with a special
|
||||
uint64 value ptr_constructor_key and the pointer itself. MATLAB
|
||||
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 *result;
|
||||
|
@ -376,9 +381,9 @@ mxArray* wrap_shared_ptr(boost::shared_ptr< Class >* shared_ptr, const char *cla
|
|||
}
|
||||
|
||||
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)
|
||||
|| mxGetM(mxh) != 1 || mxGetN(mxh) != 1) error(
|
||||
"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
|
||||
|
|
|
@ -98,4 +98,10 @@ void generateUsingNamespace(FileWriter& file, const std::vector<std::string>& us
|
|||
void generateIncludes(FileWriter& file, const std::string& class_name,
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue