MIRA
Classes | Namespaces | Macros | Functions
ReflectorWrapper.h File Reference
#include <Python.h>
#include <python/BoostPythonWrapper.h>
#include <boost/python/stl_iterator.hpp>
#include <boost/preprocessor/arithmetic/div.hpp>
#include <boost/preprocessor/arithmetic/mul.hpp>
#include <serialization/ReflectorInterface.h>
#include <serialization/GetterSetter.h>
#include <serialization/adapters/std/vector>
#include <python/PythonException.h>
#include <python/RPCDefinitions.h>
#include <python/ScopedGIL.h>
#include <python/Version.h>
Include dependency graph for ReflectorWrapper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ReflectorWrapperVersionHelper< Reflector >
 
struct  ReflectorWrapperVersionHelper< MetaSerializer >
 
struct  ReflectorWrapperRPCCallHelper< ReturnType >
 
struct  ReflectorWrapperRPCCallHelper< void >
 
class  BaseReflectorWrapper
 
class  ReflectorWrapper< Reflector >
 

Namespaces

 mira
 
 mira::python
 

Macros

#define REFLECTORWRAPPERGEN_SERVICE_METHODS(z, n, _)
 
#define REFLECTORWRAPPERGEN_SERVICE_METHODS(z, n, _)
 
#define REFLECTOR_WRAPPER_CALL_member(access, T)
 
#define REFLECTOR_WRAPPER_CALL_roproperty(access, T)
 
#define REFLECTOR_WRAPPER_CALL_LIST_member(access, T)
 
#define REFLECTOR_WRAPPER_CALL_LIST_roproperty(access, T)
 
#define REFLECTOR_WRAPPER_CALL_property   REFLECTOR_WRAPPER_CALL_member
 
#define REFLECTOR_WRAPPER_CALL_LIST_property   REFLECTOR_WRAPPER_CALL_LIST_member
 
#define REFLECTOR_WRAPPER_CHECK_GETSET_member
 
#define REFLECTOR_WRAPPER_CHECK_GETSET_roproperty
 
#define REFLECTOR_WRAPPER_CHECK_GETSET_property   REFLECTOR_WRAPPER_CHECK_GETSET_member
 
#define REFLECTOR_WRAPPER_CALL_IF_TYPE(PyType, CType, access)
 
#define REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyType, CType, access)
 
#define REFLECTOR_WRAPPER_FIND_TYPE(access)
 
#define REFLECTOR_WRAPPER_FIND_LIST_TYPE(access)
 
#define REFLECTOR_WRAPPER_ACCESS(access)
 
#define REFLECTORWRAPPERGEN_SERVICE_CALLS(z, n, _)
 
#define REFLECTORWRAPPERGEN_NAME_DESC_DECL(z, n, _)   const std::string& name##n, const std::string& description##n
 
#define REFLECTORWRAPPERGEN_NAME_DESC(z, n, _)   name##n.c_str(), description##n.c_str()
 
#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS(z, n, _)
 
#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS(z, n, _)
 
#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE_DECL(z, n, _)   const std::string& name##n, const std::string& description##n, boost::python::object sample##n
 
#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE(z, n, _)
 
#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS_SAMPLES(z, n, _)
 
#define REFLECTORWRAPPERGEN_P_DECL(z, n, _)   boost::python::object p##n
 
#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING(z, n, _)
 
#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING_OBJECT(z, n, _)
 
#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DISPATCH(z, n, _)
 

Functions

template<typename T >
std::vector< T > listToVector (const boost::python::object &l)
 

Macro Definition Documentation

◆ REFLECTORWRAPPERGEN_SERVICE_METHODS [1/2]

#define REFLECTORWRAPPERGEN_SERVICE_METHODS (   z,
  n,
 
)
Value:
static ReturnType rpcCall##n(boost::python::object callable BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, const json::Value& p)) { \
using namespace boost::python; \
ScopedGILLock lock; \
try \
{ \
boost::python::object value = callable(BOOST_PP_ENUM_PARAMS_Z(z, n, p)); \
return boost::python::extract<ReturnType>(value); \
} \
catch(boost::python::error_already_set&) \
{ \
MIRA_THROW(XInvalidParameter, "Error calling rpc method: " << getLastExceptionString()); \
} \
return ReturnType(); \
}
std::string getLastExceptionString()
Extract the message from the last python exception.

◆ REFLECTORWRAPPERGEN_SERVICE_METHODS [2/2]

#define REFLECTORWRAPPERGEN_SERVICE_METHODS (   z,
  n,
 
)
Value:
static void rpcCall##n(boost::python::object callable BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, const json::Value& p)) { \
using namespace boost::python; \
ScopedGILLock lock; \
try \
{ \
callable(BOOST_PP_ENUM_PARAMS_Z(z, n, p)); \
} \
catch(boost::python::error_already_set&) \
{ \
MIRA_THROW(XInvalidParameter, "Error calling rpc method: " << getLastExceptionString()); \
} \
}
std::string getLastExceptionString()
Extract the message from the last python exception.

◆ REFLECTOR_WRAPPER_CALL_member

#define REFLECTOR_WRAPPER_CALL_member (   access,
 
)
Value:
if (defaultValue.is_none())\
{\
mReflector.access(name.c_str(),\
Getter<T>(boost::bind(&ReflectorWrapper<Reflector>::get<T>, getterCallable)),\
Setter<T>(boost::bind(&ReflectorWrapper<Reflector>::set<T>, setterCallable, _1)),\
comment.c_str());\
}\
else\
{\
mReflector.access(name.c_str(),\
Getter<T>(boost::bind(&ReflectorWrapper<Reflector>::get<T>, getterCallable)),\
Setter<T>(boost::bind(&ReflectorWrapper<Reflector>::set<T>, setterCallable, _1)),\
comment.c_str(),\
extract<T>(defaultValue));\
}

◆ REFLECTOR_WRAPPER_CALL_roproperty

#define REFLECTOR_WRAPPER_CALL_roproperty (   access,
 
)
Value:
mReflector.access(name.c_str(),\
Getter<T>(boost::bind(&ReflectorWrapper<Reflector>::get<T>, getterCallable)),\
comment.c_str());

◆ REFLECTOR_WRAPPER_CALL_LIST_member

#define REFLECTOR_WRAPPER_CALL_LIST_member (   access,
 
)
Value:
if (defaultValue.is_none())\
{\
mReflector.access(name.c_str(),\
Getter<std::vector<T>>(boost::bind(&ReflectorWrapper<Reflector>::getList<T>, getterCallable)),\
Setter<std::vector<T>>(boost::bind(&ReflectorWrapper<Reflector>::setList<T>, setterCallable, _1)),\
comment.c_str());\
}\
else\
{\
std::vector<T> dv = listToVector<T>(defaultValue); \
mReflector.access(name.c_str(),\
Getter<std::vector<T>>(boost::bind(&ReflectorWrapper<Reflector>::getList<T>, getterCallable)),\
Setter<std::vector<T>>(boost::bind(&ReflectorWrapper<Reflector>::setList<T>, setterCallable, _1)),\
comment.c_str(),\
dv);\
}

◆ REFLECTOR_WRAPPER_CALL_LIST_roproperty

#define REFLECTOR_WRAPPER_CALL_LIST_roproperty (   access,
 
)
Value:
mReflector.access(name.c_str(),\
Getter<std::vector<T>>(boost::bind(&ReflectorWrapper<Reflector>::getList<T>, getterCallable)),\
comment.c_str());

◆ REFLECTOR_WRAPPER_CALL_property

#define REFLECTOR_WRAPPER_CALL_property   REFLECTOR_WRAPPER_CALL_member

◆ REFLECTOR_WRAPPER_CALL_LIST_property

#define REFLECTOR_WRAPPER_CALL_LIST_property   REFLECTOR_WRAPPER_CALL_LIST_member

◆ REFLECTOR_WRAPPER_CHECK_GETSET_member

#define REFLECTOR_WRAPPER_CHECK_GETSET_member
Value:
if (!PyCallable_Check(getterCallable.ptr()))\
MIRA_THROW(XRuntime, "getter parameter is no callable object.");\
if (!PyCallable_Check(setterCallable.ptr())) \
MIRA_THROW(XRuntime, "setter parameter is no callable object.");\

◆ REFLECTOR_WRAPPER_CHECK_GETSET_roproperty

#define REFLECTOR_WRAPPER_CHECK_GETSET_roproperty
Value:
if (!PyCallable_Check(getterCallable.ptr()))\
MIRA_THROW(XRuntime, "getter parameter is no callable object.");\

◆ REFLECTOR_WRAPPER_CHECK_GETSET_property

#define REFLECTOR_WRAPPER_CHECK_GETSET_property   REFLECTOR_WRAPPER_CHECK_GETSET_member

◆ REFLECTOR_WRAPPER_CALL_IF_TYPE

#define REFLECTOR_WRAPPER_CALL_IF_TYPE (   PyType,
  CType,
  access 
)
Value:
if (PyType_IsSubtype((PyTypeObject*)type.ptr(), &PyType))\
{\
REFLECTOR_WRAPPER_CALL_##access(access, CType)\
return;\
}
PropertyHint type(const std::string &t)

◆ REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE

#define REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE (   PyType,
  CType,
  access 
)
Value:
if (PyType_IsSubtype((PyTypeObject*)listType.ptr(), &PyType))\
{\
REFLECTOR_WRAPPER_CALL_LIST_##access(access, CType)\
return;\
}

◆ REFLECTOR_WRAPPER_FIND_TYPE

#define REFLECTOR_WRAPPER_FIND_TYPE (   access)
Value:
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyBool_Type, bool, access) \
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyInt_Type, int, access) \
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyLong_Type, int64, access) \
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyFloat_Type, double, access) \
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyString_Type, std::string, access) \
REFLECTOR_WRAPPER_CALL_IF_TYPE(PyUnicode_Type, std::string, access)
#define REFLECTOR_WRAPPER_CALL_IF_TYPE(PyType, CType, access)
Definition: ReflectorWrapper.h:256
int64_t int64

◆ REFLECTOR_WRAPPER_FIND_LIST_TYPE

#define REFLECTOR_WRAPPER_FIND_LIST_TYPE (   access)
Value:
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyBool_Type, bool, access) \
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyInt_Type, int, access) \
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyLong_Type, int64, access) \
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyFloat_Type, double, access) \
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyString_Type, std::string, access) \
REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyUnicode_Type, std::string, access)
int64_t int64
#define REFLECTOR_WRAPPER_CALL_IF_LIST_TYPE(PyType, CType, access)
Definition: ReflectorWrapper.h:263

◆ REFLECTOR_WRAPPER_ACCESS

#define REFLECTOR_WRAPPER_ACCESS (   access)
Value:
using namespace boost::python;\
REFLECTOR_WRAPPER_CHECK_GETSET_##access\
\
if (PyObject_IsInstance(type.ptr(), (PyObject*) &PyList_Type))\
{\
int n = PyList_Size(type.ptr());\
if (n!=1)\
MIRA_THROW(XRuntime, "List must contain exactly one type information.");\
object listType = type[0];\
if (!PyType_Check(listType.ptr()))\
MIRA_THROW(XRuntime, "Type parameter in list is no type object.");\
\
std::string typeStr = extract<std::string>(str(listType));\
MIRA_THROW(XRuntime, "Reflect not implemented for primitive type " + typeStr + ".");\
}\
else\
{\
if (!PyType_Check(type.ptr()))\
MIRA_THROW(XRuntime, "Type parameter is no type object.");\
\
std::string typeStr = extract<std::string>(str(type));\
MIRA_THROW(XRuntime, "Reflect not implemented for primitive type " + typeStr + ".");\
}
#define REFLECTOR_WRAPPER_FIND_LIST_TYPE(access)
Definition: ReflectorWrapper.h:293
#define REFLECTOR_WRAPPER_FIND_TYPE(access)
Definition: ReflectorWrapper.h:285
PropertyHint type(const std::string &t)

◆ REFLECTORWRAPPERGEN_SERVICE_CALLS

#define REFLECTORWRAPPERGEN_SERVICE_CALLS (   z,
  n,
 
)
Value:
if (argCount == n) \
mReflector.template method<ReturnType, BOOST_PP_ENUM_PARAMS(n, json::Value BOOST_PP_INTERCEPT)>(name.c_str(), boost::bind(&ReflectorWrapperRPCCallHelper<ReturnType>::BOOST_PP_CAT(rpcCall, n), callable, BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z,BOOST_PP_INC(n), _)), comment.c_str());

◆ REFLECTORWRAPPERGEN_NAME_DESC_DECL

#define REFLECTORWRAPPERGEN_NAME_DESC_DECL (   z,
  n,
 
)    const std::string& name##n, const std::string& description##n

◆ REFLECTORWRAPPERGEN_NAME_DESC

#define REFLECTORWRAPPERGEN_NAME_DESC (   z,
  n,
 
)    name##n.c_str(), description##n.c_str()

◆ REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS [1/2]

#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS (   z,
  n,
 
)
Value:
template<typename ReturnType = json::Value> \
void methodWithParamDescription##n(const std::string& name, boost::python::object callable, const std::string& comment, \
BOOST_PP_ENUM(n, REFLECTORWRAPPERGEN_NAME_DESC_DECL, _)) \
{ \
mReflector.template method<ReturnType, BOOST_PP_ENUM_PARAMS(n, json::Value BOOST_PP_INTERCEPT)>( \
name.c_str(), \
boost::bind(&ReflectorWrapperRPCCallHelper<ReturnType>::rpcCall##n, \
callable, BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, BOOST_PP_INC(n), _)), \
comment.c_str(), \
BOOST_PP_ENUM(n, REFLECTORWRAPPERGEN_NAME_DESC, _)); \
}
#define REFLECTORWRAPPERGEN_NAME_DESC(z, n, _)
Definition: ReflectorWrapper.h:482
#define REFLECTORWRAPPERGEN_NAME_DESC_DECL(z, n, _)
Definition: ReflectorWrapper.h:481

◆ REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS [2/2]

#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS (   z,
  n,
 
)
Value:
template<typename ReturnType = json::Value> \
void methodWithParamDescription##n(const std::string& name, boost::python::object callable, const std::string& comment, \
BOOST_PP_ENUM(n, REFLECTORWRAPPERGEN_NAME_DESC_DECL, _)) {}
#define REFLECTORWRAPPERGEN_NAME_DESC_DECL(z, n, _)
Definition: ReflectorWrapper.h:481

◆ REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE_DECL

#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE_DECL (   z,
  n,
 
)    const std::string& name##n, const std::string& description##n, boost::python::object sample##n

◆ REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE

#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE (   z,
  n,
 
)
Value:
name##n.c_str(), description##n.c_str(), \
boost::python::extract<json::Value>(PyObject_HasAttrString(sample##n.ptr(), "convertObjectToJSON") ? sample##n.attr("convertObjectToJSON")() : sample##n)()

◆ REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS_SAMPLES

#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DESCRIPTIONS_SAMPLES (   z,
  n,
 
)
Value:
template<typename ReturnType = json::Value> \
void methodWithParamDescriptionAndSample##n(const std::string& name, boost::python::object callable, const std::string& comment, \
{ \
boost::function<ReturnType(BOOST_PP_ENUM_PARAMS(n, json::Value BOOST_PP_INTERCEPT))> fn; \
fn = boost::bind(&ReflectorWrapperRPCCallHelper<json::Value>::rpcCall##n, \
callable, BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, BOOST_PP_INC(n), _)); \
\
mReflector.template method<ReturnType, BOOST_PP_ENUM_PARAMS(n, json::Value BOOST_PP_INTERCEPT)>( \
name.c_str(), fn, comment.c_str(), \
BOOST_PP_ENUM(n, REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE, _)); \
}
#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE(z, n, _)
#define REFLECTORWRAPPERGEN_NAME_DESC_SAMPLE_DECL(z, n, _)

◆ REFLECTORWRAPPERGEN_P_DECL

#define REFLECTORWRAPPERGEN_P_DECL (   z,
  n,
 
)    boost::python::object p##n

◆ REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING

#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING (   z,
  n,
 
)
Value:
boost::python::extract<std::string>(BOOST_PP_CAT(p, BOOST_PP_MUL(2, n)))(), \
boost::python::extract<std::string>(BOOST_PP_CAT(p, BOOST_PP_INC(BOOST_PP_MUL(2, n))))()

◆ REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING_OBJECT

#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING_OBJECT (   z,
  n,
 
)
Value:
boost::python::extract<std::string>(BOOST_PP_CAT(p, BOOST_PP_MUL(3, n)))(), \
boost::python::extract<std::string>(BOOST_PP_CAT(p, BOOST_PP_INC(BOOST_PP_MUL(3, n))))(), \
BOOST_PP_CAT(p, BOOST_PP_INC(BOOST_PP_INC(BOOST_PP_MUL(3, n))))

◆ REFLECTORWRAPPERGEN_SERVICE_CALLS_DISPATCH

#define REFLECTORWRAPPERGEN_SERVICE_CALLS_DISPATCH (   z,
  n,
 
)
Value:
template<typename ReturnType = json::Value> \
void methodDispatch##n(const std::string& name, boost::python::object callable, const std::string& comment, \
BOOST_PP_ENUM(n, REFLECTORWRAPPERGEN_P_DECL, _)) \
{ \
int argCount = argumentCount(callable); \
if (argCount*2 == n) { \
this->template BOOST_PP_CAT(methodWithParamDescription, BOOST_PP_DIV(n,2))<ReturnType> \
(name, callable, comment \
BOOST_PP_ENUM_TRAILING(BOOST_PP_DIV(n,2), REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING, p)); \
return; \
} \
if (argCount*3 == n) { \
this->template BOOST_PP_CAT(methodWithParamDescriptionAndSample, BOOST_PP_DIV(n,3))<ReturnType> \
(name, callable, comment \
BOOST_PP_ENUM_TRAILING(BOOST_PP_DIV(n,3), REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING_OBJECT, p)); \
return; \
} \
\
MIRA_THROW(XRuntime, "Number of names/descriptions/sample values for parameters in call to Reflector::method('" << name \
<< "', ...) do not match the provided function's signature (" << n << " equals neither 2*" \
<< argCount << " nor 3*" << argCount << "). Please provide (string) name AND description for EACH "\
"RPC method parameter, or name, description AND sample value for EACH parameter."); \
}
#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING(z, n, _)
#define REFLECTORWRAPPERGEN_P_TO_STRING_P_TO_STRING_OBJECT(z, n, _)
#define REFLECTORWRAPPERGEN_P_DECL(z, n, _)