[C++-sig] playing with pygame
Brett Calcott
brett.calcott at paradise.net.nz
Wed Jun 4 13:19:27 CEST 2003
Pygame (www.pygame.org) is a standard "C" type extension for python based on
the Simple Direct Media Layer. It is broken into several modules and exposes
the C objects to each other via a simple mechanism using a array of "slots",
that are initialised via python.
Here is the simplest class, a rect, snipped from the header pygame.h:
/* RECT */
#define PYGAMEAPI_RECT_FIRSTSLOT 20
#define PYGAMEAPI_RECT_NUMSLOTS 4
typedef struct {
short x, y;
short w, h;
}GAME_Rect;
typedef struct {
PyObject_HEAD
GAME_Rect r;
} PyRectObject;
#define PyRect_AsRect(x) (((PyRectObject*)x)->r)
#ifndef PYGAMEAPI_RECT_INTERNAL
#define PyRect_Check(x) ((x)->ob_type ==
(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 0])
#define PyRect_Type (*(PyTypeObject*)PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT +
0])
#define PyRect_New
(*(PyObject*(*)(GAME_Rect*))PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 1])
#define PyRect_New4 \
(*(PyObject*(*)(short,short,short,short))PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSL
OT + 2])
#define GameRect_FromObject \
(*(GAME_Rect*(*)(PyObject*,
GAME_Rect*))PyGAME_C_API[PYGAMEAPI_RECT_FIRSTSLOT + 3])
Here is the bit that exposes this to other modules:
#define import_pygame_rect() { \
PyObject *module = PyImport_ImportModule("pygame.rect"); \
if (module != NULL) { \
PyObject *dict = PyModule_GetDict(module); \
PyObject *c_api = PyDict_GetItemString(dict, PYGAMEAPI_LOCAL_ENTRY); \
if(PyCObject_Check(c_api)) {\
int i; void** localptr = (void**)PyCObject_AsVoidPtr(c_api); \
for(i = 0; i < PYGAMEAPI_RECT_NUMSLOTS; ++i) \
PyGAME_C_API[i + PYGAMEAPI_RECT_FIRSTSLOT] = localptr[i]; \
} Py_DECREF(module); } }
#endif
where this appears later on:
#ifndef NO_PYGAME_C_API
#define PYGAMEAPI_TOTALSLOTS 60
static void* PyGAME_C_API[PYGAMEAPI_TOTALSLOTS] = {NULL};
#endif
(Hope that makes sense)
So, I can do this:
#include <...boostpythonstuff...>
#include <pygame.h>
void look_at_rect(object o)
{
PyObject *p = o.ptr();
if (PyRect_Check(p))
{
GAME_Rect &r = PyRect_AsRect(p);
std::cout << r.x << ',' << r.y;
}
}
BOOST_PYTHON_MODULE(pygame_boost)
{
import_pygame_rect();
def("look_at_rect", look_at_rect);
}
Now the QUESTION:
I should be able to register a conversion though. I got as far as this:
lvalue_from_pytype<extract_member<PyRectObject,
GAME_Rect, &PyRectObject::r>, &PyRect_Type>();
But, this won't compile as:
'python_type' : invalid template argument for
'boost::python::lvalue_from_pytype', constant expression expected
I think I understand the problem, but what is the solution?
Cheers,
Brett
More information about the Cplusplus-sig
mailing list