You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
508 lines
20 KiB
508 lines
20 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#ifndef _pyGlueHelpers_h_ |
|
#define _pyGlueHelpers_h_ |
|
|
|
// A set of macros to take at least some of the tediousness out of creating straight python glue code |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Python class definition macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// This defines the basic PyObject we need for python classes |
|
#define PYTHON_CLASS_DEFINITION(pythonClassName, glueClassName) \ |
|
struct pythonClassName \ |
|
{ \ |
|
PyObject_HEAD \ |
|
glueClassName *fThis; \ |
|
} |
|
|
|
// This makes sure that our python new function can access our constructors |
|
#define PYTHON_CLASS_NEW_FRIEND(pythonClassName) friend PyObject *pythonClassName##_new(PyTypeObject *type, PyObject *args, PyObject *keywords) |
|
|
|
// This defines the basic new function for a class |
|
#define PYTHON_CLASS_NEW_DEFINITION static PyObject *New() |
|
|
|
#define PYTHON_CLASS_NEW_IMPL(pythonClassName, glueClassName) \ |
|
PyObject *glueClassName::New() \ |
|
{ \ |
|
pythonClassName *newObj = (pythonClassName*)pythonClassName##_type.tp_new(&pythonClassName##_type, NULL, NULL); \ |
|
return (PyObject*)newObj; \ |
|
} |
|
|
|
// This defines the basic check function for a class |
|
#define PYTHON_CLASS_CHECK_DEFINITION static bool Check(PyObject *obj) |
|
|
|
#define PYTHON_CLASS_CHECK_IMPL(pythonClassName, glueClassName) \ |
|
bool glueClassName::Check(PyObject *obj) \ |
|
{ \ |
|
return PyObject_TypeCheck(obj, &pythonClassName##_type); \ |
|
} |
|
|
|
// This defines the basic convert from function for a class |
|
#define PYTHON_CLASS_CONVERT_FROM_DEFINITION(glueClassName) static glueClassName *ConvertFrom(PyObject *obj) |
|
|
|
#define PYTHON_CLASS_CONVERT_FROM_IMPL(pythonClassName, glueClassName) \ |
|
glueClassName *glueClassName::ConvertFrom(PyObject *obj) \ |
|
{ \ |
|
if (!Check(obj)) \ |
|
{ \ |
|
PyErr_SetString(PyExc_TypeError, "object is not a " #pythonClassName); \ |
|
return NULL; \ |
|
} \ |
|
return ((pythonClassName*)obj)->fThis; \ |
|
} |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Python type definition macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// This starts off the type definition (however most of the data still needs to be filled in by hand |
|
#define PYTHON_TYPE_START(pythonClassName) \ |
|
static PyTypeObject pythonClassName##_type = { \ |
|
PyObject_HEAD_INIT(NULL) |
|
|
|
// and easy terminator to make things look pretty |
|
#define PYTHON_TYPE_END } |
|
|
|
// the default new function definition |
|
#define PYTHON_DEFAULT_NEW_DEFINITION(pythonClassName, glueClassName) \ |
|
PyObject *pythonClassName##_new(PyTypeObject *type, PyObject *, PyObject *) \ |
|
{ \ |
|
pythonClassName *self; \ |
|
self = (pythonClassName*)type->tp_alloc(type, 0); \ |
|
if (self != NULL) \ |
|
{ \ |
|
self->fThis = TRACKED_NEW glueClassName(); \ |
|
if (self->fThis == NULL) \ |
|
{ \ |
|
Py_DECREF(self); \ |
|
return NULL; \ |
|
} \ |
|
} \ |
|
\ |
|
return (PyObject*)self; \ |
|
} |
|
|
|
#define PYTHON_DEFAULT_NEW(pythonClassName) pythonClassName##_new |
|
|
|
// the default dealloc function definition |
|
#define PYTHON_DEFAULT_DEALLOC_DEFINITION(pythonClassName) \ |
|
void pythonClassName##_dealloc(pythonClassName *self) \ |
|
{ \ |
|
delete self->fThis; \ |
|
self->ob_type->tp_free((PyObject*)self); \ |
|
} |
|
|
|
#define PYTHON_DEFAULT_DEALLOC(pythonClassName) (destructor)pythonClassName##_dealloc |
|
|
|
// init function defines |
|
#define PYTHON_RETURN_INIT_ERROR return -1; |
|
#define PYTHON_RETURN_INIT_OK return 0; |
|
|
|
// basic no init function stuff, for when you don't want the class to be created by python |
|
#define PYTHON_NO_INIT_DEFINITION(pythonClassName) \ |
|
int pythonClassName##___init__(pythonClassName *, PyObject *, PyObject *) \ |
|
{ \ |
|
PyErr_SetString(PyExc_RuntimeError, "Cannot create " #pythonClassName " objects from Python"); \ |
|
PYTHON_RETURN_INIT_ERROR; \ |
|
} |
|
|
|
#define PYTHON_INIT_DEFINITION(pythonClassName, argsVar, keywordsVar) \ |
|
int pythonClassName##___init__(pythonClassName *self, PyObject *args, PyObject *keywords) |
|
|
|
#define PYTHON_DEFAULT_INIT(pythonClassName) (initproc)pythonClassName##___init__ |
|
|
|
// message table default name |
|
#define PYTHON_DEFAULT_METHODS_TABLE(pythonClassName) pythonClassName##_methods |
|
|
|
// most glue classes can get away with this default structure |
|
#define PLASMA_DEFAULT_TYPE(pythonClassName, docString) \ |
|
PYTHON_TYPE_START(pythonClassName) \ |
|
0, /* ob_size */ \ |
|
"Plasma." #pythonClassName, /* tp_name */ \ |
|
sizeof(pythonClassName), /* tp_basicsize */ \ |
|
0, /* tp_itemsize */ \ |
|
PYTHON_DEFAULT_DEALLOC(pythonClassName), /* tp_dealloc */ \ |
|
0, /* tp_print */ \ |
|
0, /* tp_getattr */ \ |
|
0, /* tp_setattr */ \ |
|
0, /* tp_compare */ \ |
|
0, /* tp_repr */ \ |
|
0, /* tp_as_number */ \ |
|
0, /* tp_as_sequence */ \ |
|
0, /* tp_as_mapping */ \ |
|
0, /* tp_hash */ \ |
|
0, /* tp_call */ \ |
|
0, /* tp_str */ \ |
|
0, /* tp_getattro */ \ |
|
0, /* tp_setattro */ \ |
|
0, /* tp_as_buffer */ \ |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \ |
|
docString, /* tp_doc */ \ |
|
0, /* tp_traverse */ \ |
|
0, /* tp_clear */ \ |
|
0, /* tp_richcompare */ \ |
|
0, /* tp_weaklistoffset */ \ |
|
0, /* tp_iter */ \ |
|
0, /* tp_iternext */ \ |
|
PYTHON_DEFAULT_METHODS_TABLE(pythonClassName), /* tp_methods */ \ |
|
0, /* tp_members */ \ |
|
0, /* tp_getset */ \ |
|
0, /* tp_base */ \ |
|
0, /* tp_dict */ \ |
|
0, /* tp_descr_get */ \ |
|
0, /* tp_descr_set */ \ |
|
0, /* tp_dictoffset */ \ |
|
PYTHON_DEFAULT_INIT(pythonClassName), /* tp_init */ \ |
|
0, /* tp_alloc */ \ |
|
PYTHON_DEFAULT_NEW(pythonClassName),/* tp_new */ \ |
|
PYTHON_TYPE_END |
|
|
|
// default compare/rich compare function name |
|
#define PYTHON_DEFAULT_COMPARE(pythonClassName) pythonClassName##_compare |
|
#define PYTHON_NO_COMPARE 0 |
|
#define PYTHON_DEFAULT_RICH_COMPARE(pythonClassName) pythonClassName##_richCompare |
|
#define PYTHON_NO_RICH_COMPARE 0 |
|
|
|
// default as_ table names |
|
#define PYTHON_DEFAULT_AS_NUMBER(pythonClassName) &pythonClassName##_as_number |
|
#define PYTHON_NO_AS_NUMBER 0 |
|
#define PYTHON_DEFAULT_AS_SEQUENCE(pythonClassName) &pythonClassName##_as_sequence |
|
#define PYTHON_NO_AS_SEQUENCE 0 |
|
#define PYTHON_DEFAULT_AS_MAPPING(pythonClassName) &pythonClassName##_as_mapping |
|
#define PYTHON_NO_AS_MAPPING 0 |
|
|
|
// str function |
|
#define PYTHON_DEFAULT_STR(pythonClassName) (reprfunc)pythonClassName##_str |
|
#define PYTHON_NO_STR 0 |
|
|
|
// get/set table default name |
|
#define PYTHON_DEFAULT_GETSET(pythonClassName) pythonClassName##_getseters |
|
#define PYTHON_NO_GETSET 0 |
|
|
|
// default base pointer |
|
#define PYTHON_DEFAULT_BASE_TYPE(glueBaseClass) glueBaseClass::type_ptr |
|
#define PYTHON_NO_BASE 0 |
|
|
|
// for glue functions that need custom stuff, you need to define the macros yourself |
|
#define PLASMA_CUSTOM_TYPE(pythonClassName, docString) \ |
|
PYTHON_TYPE_START(pythonClassName) \ |
|
0, /* ob_size */ \ |
|
"Plasma." #pythonClassName, /* tp_name */ \ |
|
sizeof(pythonClassName), /* tp_basicsize */ \ |
|
0, /* tp_itemsize */ \ |
|
PYTHON_DEFAULT_DEALLOC(pythonClassName), /* tp_dealloc */ \ |
|
0, /* tp_print */ \ |
|
0, /* tp_getattr */ \ |
|
0, /* tp_setattr */ \ |
|
pythonClassName##_COMPARE, /* tp_compare */ \ |
|
0, /* tp_repr */ \ |
|
pythonClassName##_AS_NUMBER, /* tp_as_number */ \ |
|
pythonClassName##_AS_SEQUENCE, /* tp_as_sequence */ \ |
|
pythonClassName##_AS_MAPPING, /* tp_as_mapping */ \ |
|
0, /* tp_hash */ \ |
|
0, /* tp_call */ \ |
|
pythonClassName##_STR, /* tp_str */ \ |
|
0, /* tp_getattro */ \ |
|
0, /* tp_setattro */ \ |
|
0, /* tp_as_buffer */ \ |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \ |
|
docString, /* tp_doc */ \ |
|
0, /* tp_traverse */ \ |
|
0, /* tp_clear */ \ |
|
pythonClassName##_RICH_COMPARE, /* tp_richcompare */ \ |
|
0, /* tp_weaklistoffset */ \ |
|
0, /* tp_iter */ \ |
|
0, /* tp_iternext */ \ |
|
PYTHON_DEFAULT_METHODS_TABLE(pythonClassName), /* tp_methods */ \ |
|
0, /* tp_members */ \ |
|
pythonClassName##_GETSET, /* tp_getset */ \ |
|
pythonClassName##_BASE, /* tp_base */ \ |
|
0, /* tp_dict */ \ |
|
0, /* tp_descr_get */ \ |
|
0, /* tp_descr_set */ \ |
|
0, /* tp_dictoffset */ \ |
|
PYTHON_DEFAULT_INIT(pythonClassName), /* tp_init */ \ |
|
0, /* tp_alloc */ \ |
|
PYTHON_DEFAULT_NEW(pythonClassName),/* tp_new */ \ |
|
PYTHON_TYPE_END |
|
|
|
// for conviencence when we just need a base class |
|
#define PLASMA_DEFAULT_TYPE_WBASE(pythonClassName, glueBaseClass, docString) \ |
|
PYTHON_TYPE_START(pythonClassName) \ |
|
0, /* ob_size */ \ |
|
"Plasma." #pythonClassName, /* tp_name */ \ |
|
sizeof(pythonClassName), /* tp_basicsize */ \ |
|
0, /* tp_itemsize */ \ |
|
PYTHON_DEFAULT_DEALLOC(pythonClassName), /* tp_dealloc */ \ |
|
0, /* tp_print */ \ |
|
0, /* tp_getattr */ \ |
|
0, /* tp_setattr */ \ |
|
0, /* tp_compare */ \ |
|
0, /* tp_repr */ \ |
|
0, /* tp_as_number */ \ |
|
0, /* tp_as_sequence */ \ |
|
0, /* tp_as_mapping */ \ |
|
0, /* tp_hash */ \ |
|
0, /* tp_call */ \ |
|
0, /* tp_str */ \ |
|
0, /* tp_getattro */ \ |
|
0, /* tp_setattro */ \ |
|
0, /* tp_as_buffer */ \ |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \ |
|
docString, /* tp_doc */ \ |
|
0, /* tp_traverse */ \ |
|
0, /* tp_clear */ \ |
|
0, /* tp_richcompare */ \ |
|
0, /* tp_weaklistoffset */ \ |
|
0, /* tp_iter */ \ |
|
0, /* tp_iternext */ \ |
|
PYTHON_DEFAULT_METHODS_TABLE(pythonClassName), /* tp_methods */ \ |
|
0, /* tp_members */ \ |
|
0, /* tp_getset */ \ |
|
glueBaseClass::type_ptr, /* tp_base */ \ |
|
0, /* tp_dict */ \ |
|
0, /* tp_descr_get */ \ |
|
0, /* tp_descr_set */ \ |
|
0, /* tp_dictoffset */ \ |
|
PYTHON_DEFAULT_INIT(pythonClassName), /* tp_init */ \ |
|
0, /* tp_alloc */ \ |
|
PYTHON_DEFAULT_NEW(pythonClassName),/* tp_new */ \ |
|
PYTHON_TYPE_END |
|
|
|
// small macros so that the type object can be accessed outside the glue file (for subclassing) |
|
#define PYTHON_EXPOSE_TYPE static PyTypeObject* type_ptr |
|
#define PYTHON_EXPOSE_TYPE_DEFINITION(pythonClass, glueClass) PyTypeObject* glueClass::type_ptr = &pythonClass##_type |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Python class import macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// called at the beginning of the class definition function to grab the module |
|
#define PYTHON_CLASS_IMPORT_START(m) \ |
|
if (m == NULL) \ |
|
return; \ |
|
\ |
|
Py_INCREF(m) |
|
|
|
// called at the end of the class definition function to release the module |
|
#define PYTHON_CLASS_IMPORT_END(m) Py_DECREF(m) |
|
|
|
// called for each class you want to add to the module |
|
#define PYTHON_CLASS_IMPORT(m, pythonClassName) \ |
|
if (PyType_Ready(&pythonClassName##_type) < 0) \ |
|
return; \ |
|
\ |
|
Py_INCREF(&pythonClassName##_type); \ |
|
PyModule_AddObject(m, #pythonClassName, (PyObject*)&pythonClassName##_type) |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Python method macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// Handles the three types of methods python uses |
|
#define PYTHON_METHOD_DEFINITION(pythonClassName, methodName, argsVar) \ |
|
static PyObject *pythonClassName##_##methodName(pythonClassName *self, PyObject *argsVar) |
|
#define PYTHON_METHOD_DEFINITION_NOARGS(pythonClassName, methodName) \ |
|
static PyObject *pythonClassName##_##methodName(pythonClassName *self) |
|
#define PYTHON_METHOD_DEFINITION_WKEY(pythonClassName, methodName, argsVar, keywordsVar) \ |
|
static PyObject *pythonClassName##_##methodName(pythonClassName *self, PyObject *argsVar, PyObject *keywordsVar) |
|
|
|
// A very basic function, just calls the class method and returns None |
|
#define PYTHON_BASIC_METHOD_DEFINITION(pythonClassName, methodName, classMethodName) \ |
|
static PyObject *pythonClassName##_##methodName(pythonClassName *self) \ |
|
{ \ |
|
self->fThis->classMethodName(); \ |
|
PYTHON_RETURN_NONE; \ |
|
} |
|
|
|
// Different basic return types |
|
#define PYTHON_RETURN_ERROR {return NULL;} |
|
#define PYTHON_RETURN_NONE {Py_INCREF(Py_None); return Py_None;} |
|
#define PYTHON_RETURN_BOOL(testValue) \ |
|
{ \ |
|
if (testValue) \ |
|
return PyInt_FromLong((long)1); \ |
|
else \ |
|
return PyInt_FromLong((long)0); \ |
|
} |
|
#define PYTHON_RETURN_NOT_IMPLEMENTED {Py_INCREF(Py_NotImplemented); return Py_NotImplemented;} |
|
|
|
// method table start |
|
#define PYTHON_START_METHODS_TABLE(pythonClassName) static PyMethodDef pythonClassName##_methods[] = { |
|
|
|
// method table end (automatically adds sentinal value) |
|
#define PYTHON_END_METHODS_TABLE {NULL} } |
|
|
|
// basic method |
|
#define PYTHON_METHOD(pythonClassName, methodName, docString) \ |
|
{#methodName, (PyCFunction)pythonClassName##_##methodName, METH_VARARGS, docString} |
|
|
|
// method with no arguments |
|
#define PYTHON_METHOD_NOARGS(pythonClassName, methodName, docString) \ |
|
{#methodName, (PyCFunction)pythonClassName##_##methodName, METH_NOARGS, docString} |
|
|
|
// method with keywords |
|
#define PYTHON_METHOD_WKEY(pythonClassName, methodName, docString) \ |
|
{#methodName, (PyCFunction)pythonClassName##_##methodName, METH_VARARGS | METH_KEYWORDS, docString} |
|
|
|
// really basic method |
|
#define PYTHON_BASIC_METHOD(pythonClassName, methodName, docString) \ |
|
{#methodName, (PyCFunction)pythonClassName##_##methodName, METH_NOARGS, docString} |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Get/set macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// setter defines |
|
#define PYTHON_RETURN_SET_ERROR return -1; |
|
#define PYTHON_RETURN_SET_OK return 0; |
|
|
|
// getter function definition |
|
#define PYTHON_GET_DEFINITION(pythonClassName, attribName) \ |
|
static PyObject *pythonClassName##_get##attribName(pythonClassName *self, void *closure) |
|
|
|
// setter function definition |
|
#define PYTHON_SET_DEFINITION(pythonClassName, attribName, valueVarName) \ |
|
static int pythonClassName##_set##attribName(pythonClassName *self, PyObject *valueVarName, void *closure) |
|
|
|
// read-only setter function |
|
#define PYTHON_SET_DEFINITION_READONLY(pythonClassName, attribName) \ |
|
int pythonClassName##_set##attribName(PyObject *self, PyObject *value, void *closure) \ |
|
{ \ |
|
PyErr_SetString(PyExc_RuntimeError, #attribName " is read-only"); \ |
|
PYTHON_RETURN_SET_ERROR; \ |
|
} |
|
|
|
// starts off the get/set table |
|
#define PYTHON_START_GETSET_TABLE(pythonClassName) static PyGetSetDef pythonClassName##_getseters[] = { |
|
|
|
// and easy terminator to make things look pretty (automatically adds sentinal value) |
|
#define PYTHON_END_GETSET_TABLE {NULL} } |
|
|
|
// the get/set definition |
|
#define PYTHON_GETSET(pythonClassName, attribName, docString) {#attribName, \ |
|
(getter)pythonClassName##_get##attribName, (setter)pythonClassName##_set##attribName, \ |
|
docString, NULL} |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// as_ table macros |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// as_number table |
|
#define PYTHON_START_AS_NUMBER_TABLE(pythonClassName) static PyNumberMethods pythonClassName##_as_number = { |
|
#define PYTHON_END_AS_NUMBER_TABLE } |
|
|
|
// as_sequence table |
|
#define PYTHON_START_AS_SEQUENCE_TABLE(pythonClassName) static PySequenceMethods pythonClassName##_as_sequence = { |
|
#define PYTHON_END_AS_SEQUENCE_TABLE } |
|
|
|
// as_mapping table |
|
#define PYTHON_START_AS_MAPPING_TABLE(pythonClassName) static PyMappingMethods pythonClassName##_as_mapping = { |
|
#define PYTHON_END_AS_MAPPING_TABLE } |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Compare/Rich compare functions |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// compare |
|
#define PYTHON_COMPARE_DEFINITION(pythonClassName, obj1, obj2) int pythonClassName##_compare(PyObject *obj1, PyObject *obj2) |
|
#define PYTHON_COMPARE_LESS_THAN return -1 |
|
#define PYTHON_COMPARE_GREATER_THAN return 1 |
|
#define PYTHON_COMPARE_EQUAL return 0 |
|
|
|
// rich compare |
|
#define PYTHON_RICH_COMPARE_DEFINITION(pythonClassName, obj1, obj2, compareType) PyObject *pythonClassName##_richCompare(PyObject *obj1, PyObject *obj2, int compareType) |
|
#define PYTHON_RCOMPARE_TRUE return PyInt_FromLong((long)1) |
|
#define PYTHON_RCOMPARE_FALSE return PyInt_FromLong((long)0) |
|
#define PYTHON_RCOMPARE_ERROR return PyInt_FromLong((long)-1) |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// str functions |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// str function |
|
#define PYTHON_STR_DEFINITION(pythonClassName) PyObject *pythonClassName##_str(pythonClassName *self) |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Global function macros (for those functions that aren't in a class) |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// Global method |
|
#define PYTHON_GLOBAL_METHOD_DEFINITION(methodName, argsVar, docString) \ |
|
static PyObject *methodName(PyObject*, PyObject*); /* forward declaration so struct can go here */ \ |
|
static PyMethodDef methodName##_method = {#methodName, methodName, METH_VARARGS, docString}; \ |
|
static PyObject *methodName(PyObject *self, PyObject *argsVar) /* and now for the actual function */ |
|
|
|
// Global method with no arguments |
|
#define PYTHON_GLOBAL_METHOD_DEFINITION_NOARGS(methodName, docString) \ |
|
static PyObject *methodName(PyObject*); /* forward declaration so struct can go here */ \ |
|
static PyMethodDef methodName##_method = {#methodName, (PyCFunction)methodName, METH_NOARGS, docString}; \ |
|
static PyObject *methodName(PyObject *self) /* and now for the actual function */ |
|
|
|
// Global method with keywords |
|
#define PYTHON_GLOBAL_METHOD_DEFINITION_WKEY(methodName, argsVar, keywordsVar, docString) \ |
|
static PyObject *methodName(PyObject*, PyObject*, PyObject*); /* forward declaration so struct can go here */ \ |
|
static PyMethodDef methodName##_method = {#methodName, (PyCFunction)methodName, METH_VARARGS | METH_KEYWORDS, docString}; \ |
|
static PyObject *methodName(PyObject *self, PyObject *argsVar, PyObject *keywordsVar) /* and now for the actual function */ |
|
|
|
// Basic global method |
|
#define PYTHON_BASIC_GLOBAL_METHOD_DEFINITION(methodName, classMethodName, docString) \ |
|
static PyObject *methodName(PyObject*); /* forward declaration so struct can go here */ \ |
|
static PyMethodDef methodName##_method = {#methodName, (PyCFunction)methodName, METH_NOARGS, docString}; \ |
|
static PyObject *methodName(PyObject *self) /* and now for the actual function */ \ |
|
{ \ |
|
classMethodName(); \ |
|
PYTHON_RETURN_NONE; \ |
|
} |
|
|
|
// this goes in the definition function |
|
#define PYTHON_GLOBAL_METHOD(vectorVarName, methodName) vectorVarName.push_back(methodName##_method) |
|
|
|
// not necessary, but for continuity with the NOARGS function definition above |
|
#define PYTHON_GLOBAL_METHOD_NOARGS(vectorVarName, methodName) vectorVarName.push_back(methodName##_method); |
|
|
|
// not necessary, but for continuity with the WKEY function definition above |
|
#define PYTHON_GLOBAL_METHOD_WKEY(vectorVarName, methodName) vectorVarName.push_back(methodName##_method) |
|
|
|
// not necessary, but for continuity with the BASIC function definition above |
|
#define PYTHON_BASIC_GLOBAL_METHOD(vectorVarName, methodName) vectorVarName.push_back(methodName##_method) |
|
|
|
///////////////////////////////////////////////////////////////////// |
|
// Enum glue (these should all be inside a function) |
|
///////////////////////////////////////////////////////////////////// |
|
|
|
// the start of an enum block |
|
#define PYTHON_ENUM_START(enumName) std::map<std::string, int> enumName##_enumValues |
|
|
|
// for each element of the enum |
|
#define PYTHON_ENUM_ELEMENT(enumName, elementName, elementValue) enumName##_enumValues[#elementName] = elementValue |
|
|
|
// to finish off and define the enum |
|
#define PYTHON_ENUM_END(m, enumName) pyEnum::MakeEnum(m, #enumName, enumName##_enumValues) |
|
|
|
#endif // _pyGlueHelpers_h_
|
|
|