60#ifndef INCLUDE_MEXPLUS_DISPATCH_H_
61#define INCLUDE_MEXPLUS_DISPATCH_H_
68#ifndef MEXPLUS_AT_EXIT
69#define MEXPLUS_AT_EXIT
72#ifndef MEXPLUS_AT_INIT
73#define MEXPLUS_AT_INIT
76#ifndef MEXPLUS_AT_ERROR
77#define MEXPLUS_AT_ERROR(name)
100 const mxArray *prhs[]) = 0;
123template <
class OperationClass>
130 mexPrintf(
"Tag: %s\n", tag);
139 typedef std::map<OperationNameAdmitter*, OperationCreator*>
RegistryMap;
148 RegistryMap::const_iterator it =
find(name);
150 static_cast<Operation*
>(NULL) : it->second->create();
156 return ®istry_table;
160 static RegistryMap::const_iterator
find(
const std::string& name) {
161 RegistryMap::const_iterator it;
163 if ((*it->first)(name))
219 intptr_t
id =
reinterpret_cast<intptr_t
>(instance);
220 instances->insert(std::make_pair(
id, std::shared_ptr<T>(instance)));
235 static T*
get(intptr_t
id) {
237 typename InstanceMap::iterator instance = instances->find(
id);
238 if (instance == instances->end())
239 mexErrMsgIdAndTxt(
"mexplus:session:notFound",
240 "Invalid id %d. Did you create?",
242 return instance->second.get();
244 static T*
get(
const mxArray* pointer) {
259 typename InstanceMap::iterator instance = instances->find(
id);
260 return instance != instances->end();
262 static bool exist(
const mxArray* pointer) {
284 if (mxIsEmpty(pointer))
285 mexErrMsgIdAndTxt(
"mexplus:session:invalidType",
"Id is empty.");
286 if (
sizeof(intptr_t) == 8 && !mxIsInt64(pointer) && !mxIsUint64(pointer))
287 mexErrMsgIdAndTxt(
"mexplus:session:invalidType",
288 "Invalid id type %s.",
289 mxGetClassName(pointer));
290 if (
sizeof(intptr_t) == 4 && !mxIsInt32(pointer) && !mxIsUint32(pointer))
291 mexErrMsgIdAndTxt(
"mexplus:session:invalidType",
292 "Invalid id type %s.",
293 mxGetClassName(pointer));
294 return *
reinterpret_cast<intptr_t*
>(mxGetData(pointer));
315#define MEX_DEFINE(name) \
316class Operation_##name : public mexplus::Operation { \
318 virtual void operator()(int nlhs, \
321 const mxArray *prhs[]); \
323 static bool Operation_Admitter(const std::string& func) { \
324 return func == #name;\
326 static const mexplus::OperationCreatorImpl<Operation_##name> creator_; \
328const mexplus::OperationCreatorImpl<Operation_##name> \
329 Operation_##name::creator_(Operation_##name::Operation_Admitter, NULL); \
330void Operation_##name::operator()
345#define MEX_DEFINE2(name, admitter) \
346static const char* tag = NULL ; \
347class Operation_##name : public mexplus::Operation { \
349 virtual void operator()(int nlhs, \
352 const mxArray *prhs[]); \
354 static const mexplus::OperationCreatorImpl<Operation_##name> creator_; \
356const mexplus::OperationCreatorImpl<Operation_##name> \
357 Operation_##name::creator_(admitter, tag); \
358void Operation_##name::operator()
362#define MEX_DISPATCH \
363void mexFunction(int nlhs, mxArray *plhs[], \
364 int nrhs, const mxArray *prhs[]) { \
366 if (nrhs < 1 || !mxIsChar(prhs[0])) \
367 mexErrMsgIdAndTxt("mexplus:dispatch:argumentError", \
368 "Invalid argument: missing operation."); \
369 std::string operation_name(\
370 mxGetChars(prhs[0]), \
371 mxGetChars(prhs[0]) + mxGetNumberOfElements(prhs[0])); \
372 std::unique_ptr<mexplus::Operation> operation(\
373 mexplus::OperationFactory::create(operation_name)); \
374 if (operation.get() == NULL) { \
375 MEXPLUS_AT_ERROR(operation_name); \
376 mexErrMsgIdAndTxt("mexplus:dispatch:argumentError", \
377 "Invalid operation: %s", operation_name.c_str()); \
379 (*operation)(nlhs, plhs, nrhs - 1, prhs + 1); \
Base class for operation creators.
Definition dispatch.h:105
OperationCreator(OperationNameAdmitter *admitter)
Register an operation in the constructor.
Definition dispatch.h:109
virtual Operation * create()=0
Implementation must return a new instance of the operation.
virtual ~OperationCreator()
Destructor.
Definition dispatch.h:114
Implementation of the operation creator to be used as composition in an Operator class.
Definition dispatch.h:124
virtual Operation * create()
Implementation must return a new instance of the operation.
Definition dispatch.h:132
OperationCreatorImpl(OperationNameAdmitter *admitter, const char *tag)
Definition dispatch.h:126
Factory class for operations.
Definition dispatch.h:137
static RegistryMap::const_iterator find(const std::string &name)
Definition dispatch.h:160
friend void CreateOperation(OperationNameAdmitter *admitter, OperationCreator *creator)
Register a new creator.
Definition dispatch.h:172
std::map< OperationNameAdmitter *, OperationCreator * > RegistryMap
Definition dispatch.h:139
static Operation * create(const std::string &name)
Create a new instance of the registered operation.
Definition dispatch.h:147
static RegistryMap * registry()
Obtain a pointer to the registration table.
Definition dispatch.h:154
Abstract operation class.
Definition dispatch.h:90
virtual void operator()(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])=0
Execute the operation.
virtual ~Operation()
Destructor.
Definition dispatch.h:94
Key-value storage to make a stateful MEX function.
Definition dispatch.h:211
std::map< intptr_t, std::shared_ptr< T > > InstanceMap
Definition dispatch.h:213
~Session()
Definition dispatch.h:280
static void clear()
Clear all session instances.
Definition dispatch.h:267
static intptr_t getIntPointer(const mxArray *pointer)
Convert mxArray to intptr_t.
Definition dispatch.h:283
static const T & getConst(const mxArray *pointer)
Definition dispatch.h:252
static void destroy(const mxArray *pointer)
Definition dispatch.h:230
static bool exist(intptr_t id)
Check if the given id exists.
Definition dispatch.h:257
static const InstanceMap & getInstanceMap()
Get instance map.
Definition dispatch.h:274
static bool exist(const mxArray *pointer)
Definition dispatch.h:262
static T * get(intptr_t id)
Retrieve an instance or throw if no instance is found.
Definition dispatch.h:235
static InstanceMap * getInstances()
Get static instance storage.
Definition dispatch.h:298
Session()
Constructor prohibited.
Definition dispatch.h:279
static T * get(const mxArray *pointer)
Definition dispatch.h:244
static void destroy(intptr_t id)
Destroy an instance.
Definition dispatch.h:226
static intptr_t create(T *instance)
Create an instance.
Definition dispatch.h:217
static const T & getConst(intptr_t id)
Retrieve a const instance or throw if no instance is found.
Definition dispatch.h:249
MEX function arguments helper library.
Definition arguments.h:40
bool OperationNameAdmitter(const std::string &name)
Definition dispatch.h:82
void CreateOperation(OperationNameAdmitter *admitter, OperationCreator *creator)
Register a new creator in OperationFactory.
Definition dispatch.h:172