Back to index

gcompris  8.2.2
py-mod-anim.c
Go to the documentation of this file.
00001 #include <Python.h>
00002 #include <pygobject.h>
00003 #include "gcompris/gcompris.h"
00004 #include "py-gcompris-board.h"
00005 #include "py-mod-anim.h"
00006 
00007 #define THROW_INACTIVE_ANIMATION                                        \
00008 {                                                                       \
00009     PyErr_SetString(PyExc_RuntimeError, "Tried to access an inactive "  \
00010                                         "AnimCanvas");                  \
00011     return NULL;                                                        \
00012 }
00013 
00014 static int Animation_init(py_GcomprisAnimation *self, PyObject*, PyObject*);
00015 static void Animation_free(py_GcomprisAnimation *self);
00016 
00017 static int AnimCanvas_init(py_GcomprisAnimCanvas*, PyObject*, PyObject*);
00018 static void AnimCanvas_free(py_GcomprisAnimCanvas*);
00019 static PyObject *AnimCanvas_getattr(py_GcomprisAnimCanvas*, char*);
00020 
00021 /* AnimCanvas methods */
00022 static PyObject *py_gcompris_animcanvas_setstate(PyObject*, PyObject*);
00023 static PyObject *py_gcompris_animcanvas_swapanim(PyObject*, PyObject*);
00024 static PyObject *py_gcompris_animcanvas_destroy(PyObject*, PyObject*);
00025 
00026 static PyMethodDef AnimCanvasMethods[] = {
00027   {"setState", py_gcompris_animcanvas_setstate, METH_VARARGS,
00028     "gcompris_animcanvas_setstate"},
00029   {"swapAnimation", py_gcompris_animcanvas_swapanim, METH_VARARGS,
00030     "gcompris_animcanvas_swapanim"},
00031   {"destroy", py_gcompris_animcanvas_destroy, METH_VARARGS,
00032     "gcompris_animcanvas_destroy"},
00033   {NULL, NULL, 0, NULL}
00034 };
00035 
00036 static PyMethodDef AnimationMethods[] = {
00037   {NULL, NULL, 0, NULL}
00038 };
00039 
00040 static PyTypeObject py_GcomprisAnimationType = {
00041 #if defined(WIN32)
00042   PyObject_HEAD_INIT(NULL)
00043 #else /* ! WIN32 */
00044   PyObject_HEAD_INIT(&PyType_Type)
00045 #endif
00046   0,                            /* ob_size */
00047   "pyGcomprisAnimation",        /* tp_name */
00048   sizeof(py_GcomprisAnimation), /* tp_basicsize */
00049   0,                            /* tp_itemsize */
00050   (destructor)Animation_free,   /* tp_dealloc */
00051   0,                            /* tp_print */
00052   0,                            /* tp_getattr */
00053   0,                            /* tp_setattr */
00054   0,                            /* tp_compare */
00055   0,                            /* tp_repr */
00056   0,                            /* tp_as_number */
00057   0,                            /* tp_as_sequence */
00058   0,                            /* tp_as_mapping */
00059   0,                            /* tp_hash */
00060   0,                            /* tp_call */
00061   0,                            /* tp_str */
00062   0,                            /* tp_getattro */
00063   0,                            /* tp_setattro */
00064   0,                            /* tp_as_buffer */
00065   Py_TPFLAGS_DEFAULT,           /* tp_flags */
00066   "Animation objects",          /* tp_doc */
00067   0,                            /* tp_traverse */
00068   0,                            /* tp_clear */
00069   0,                            /* tp_richcompare */
00070   0,                            /* tp_weaklistoffset */
00071   0,                            /* tp_iter */
00072   0,                            /* tp_iternext */
00073   AnimationMethods,             /* tp_methods */
00074   0,                            /* tp_members */
00075   0,                            /* tp_getset */
00076   0,                            /* tp_base */
00077   0,                            /* tp_dict */
00078   0,                            /* tp_descr_get */
00079   0,                            /* tp_descr_set */
00080   0,                            /* tp_dictoffset */
00081   (initproc)Animation_init,     /* tp_init */
00082   0,                            /* tp_alloc */
00083   0,                            /* tp_new */
00084 };
00085 
00086 static PyTypeObject py_GcomprisAnimCanvasType = {
00087 #if defined(WIN32)
00088   PyObject_HEAD_INIT(NULL)
00089 #else /* ! WIN32 */
00090   PyObject_HEAD_INIT(&PyType_Type)
00091 #endif
00092   0,                                /* ob_size */
00093   "pyGcomprisAnimCanvas",           /* tp_name */
00094   sizeof(py_GcomprisAnimCanvas),    /* tp_basicsize */
00095   0,                                /* tp_itemsize */
00096   (destructor)AnimCanvas_free,      /* tp_dealloc */
00097   0,                                /* tp_print */
00098   (getattrfunc)AnimCanvas_getattr,  /* tp_getattr */
00099   0,                            /* tp_setattr */
00100   0,                            /* tp_compare */
00101   0,                            /* tp_repr */
00102   0,                            /* tp_as_number */
00103   0,                            /* tp_as_sequence */
00104   0,                            /* tp_as_mapping */
00105   0,                            /* tp_hash */
00106   0,                            /* tp_call */
00107   0,                            /* tp_str */
00108   0,                            /* tp_getattro */
00109   0,                            /* tp_setattro */
00110   0,                            /* tp_as_buffer */
00111   Py_TPFLAGS_DEFAULT,           /* tp_flags */
00112   "Animated canvas objects",    /* tp_doc */
00113   0,                            /* tp_traverse */
00114   0,                            /* tp_clear */
00115   0,                            /* tp_richcompare */
00116   0,                            /* tp_weaklistoffset */
00117   0,                            /* tp_iter */
00118   0,                            /* tp_iternext */
00119   AnimCanvasMethods,            /* tp_methods */
00120   0,                            /* tp_members */
00121   0,                            /* tp_getset */
00122   0,                            /* tp_base */
00123   0,                            /* tp_dict */
00124   0,                            /* tp_descr_get */
00125   0,                            /* tp_descr_set */
00126   0,                            /* tp_dictoffset */
00127   (initproc)AnimCanvas_init,    /* tp_init */
00128   0,                            /* tp_alloc */
00129   0,                            /* tp_new */
00130 };
00131 
00132 static PyMethodDef PythonGcomprisAnimModule[] = {
00133   {NULL, NULL, 0, NULL}
00134 };
00135 
00136 /*============================================================================*/
00137 /*                      GcomprisAnimation functions                           */
00138 /*============================================================================*/
00139 static int
00140 Animation_init(py_GcomprisAnimation *self, PyObject *args, PyObject *key)
00141 {
00142   static char *kwlist[] =
00143   {
00144     "filename", NULL
00145   };
00146 
00147   char *file=NULL;
00148 
00149   if(!PyArg_ParseTupleAndKeywords(args, key, "|s", kwlist,
00150                                    &file))
00151     {
00152       PyErr_SetString(PyExc_RuntimeError, "Invalid arguments to Animation()");
00153       return -1;
00154     }
00155 
00156   if(file)
00157     {
00158       self->a = gc_anim_load(file);
00159     }
00160 
00161   if(!self->a)
00162     {
00163       PyErr_SetString(PyExc_RuntimeError, "Failed to load Animation");
00164       return -1;
00165     }
00166   return 0;
00167 }
00168 
00169 static void Animation_free(py_GcomprisAnimation *self)
00170 {
00171   g_warning("*** Garbage collecting Animation ***\n");
00172   if( self->a)
00173       gc_anim_free(self->a);
00174   PyObject_DEL(self);
00175 }
00176 
00177 /*============================================================================*/
00178 /*                            Animation Methods                               */
00179 /*============================================================================*/
00180 
00181 static int
00182 AnimCanvas_init(py_GcomprisAnimCanvas *self, PyObject *args, PyObject *key)
00183 {
00184   GcomprisAnimCanvasItem *item;
00185   GcomprisAnimation *anim;
00186   GnomeCanvasGroup *parent;
00187   PyObject *py_p, *py_a;
00188 
00189   if(!PyArg_ParseTuple(args, "OO:AnimCanvas_init", &py_a, &py_p)) {
00190       PyErr_SetString(PyExc_RuntimeError, "Invalid arguments to AnimCanvas()");
00191       return -1;
00192   }
00193   if(!PyObject_TypeCheck(py_a, &py_GcomprisAnimationType) ||
00194      !PyObject_TypeCheck(py_p,pygobject_lookup_class(GNOME_TYPE_CANVAS_GROUP))){
00195 
00196       PyErr_SetString(PyExc_TypeError, "AnimCanvas() needs an Animation");
00197       return -1;
00198   }
00199 
00200   parent = (GnomeCanvasGroup*) pygobject_get(py_p);
00201   anim = ( (py_GcomprisAnimation*)py_a )->a;
00202   item = (GcomprisAnimCanvasItem*) gc_anim_activate(parent, anim);
00203   self->item = item;
00204   self->anim = py_a;
00205 
00206   Py_INCREF(self->anim);
00207   return 0;
00208 }
00209 
00210 static void
00211 AnimCanvas_free(py_GcomprisAnimCanvas *self)
00212 {
00213   g_warning("*** garbage collecting AnimCanvas ***\n");
00214   if(self->item)
00215     {
00216       g_warning("You should really call destroy() on an AnimCanvas "
00217                 "instead of relying on the refcounter\n");
00218       gc_anim_deactivate(self->item);
00219       self->item = NULL;
00220       Py_DECREF(self->anim);
00221     }
00222   PyObject_DEL(self);
00223 }
00224 
00225 static PyObject *AnimCanvas_getattr(py_GcomprisAnimCanvas *self, char *name)
00226 {
00227   if(!strcmp(name, "gnomecanvas"))
00228     return (PyObject*) pygobject_new( (GObject*) self->item->canvas );
00229   else if(!strcmp(name, "num_states"))
00230     return Py_BuildValue("i", self->item->anim->numstates);
00231 
00232   return Py_FindMethod(AnimCanvasMethods, (PyObject *)self, name);
00233 }
00234 
00235 static PyObject*
00236 py_gcompris_animcanvas_setstate(PyObject *self, PyObject *args)
00237 {
00238   int state;
00239   GcomprisAnimCanvasItem *item = ( (py_GcomprisAnimCanvas*)self )->item;
00240 
00241   if(!item) THROW_INACTIVE_ANIMATION;
00242 
00243   if(!PyArg_ParseTuple(args, "i:gcompris_animcanvas_setstate", &state))
00244     return NULL;
00245 
00246   gc_anim_set_state( item, state );
00247 
00248   Py_INCREF(Py_None);
00249   return Py_None;
00250 }
00251 
00252 static PyObject*
00253 py_gcompris_animcanvas_swapanim(PyObject *self, PyObject *args)
00254 {
00255   py_GcomprisAnimCanvas *s = (py_GcomprisAnimCanvas*)self;
00256   py_GcomprisAnimation *new_anim;
00257   py_GcomprisAnimation *old_anim = (py_GcomprisAnimation*)s->anim;
00258   GcomprisAnimCanvasItem *item = s->item;
00259 
00260   if(!item) THROW_INACTIVE_ANIMATION;
00261 
00262   if(!PyArg_ParseTuple(args, "O:AnimCanvas_swapAnim", (PyObject**)&new_anim))
00263     return NULL;
00264 
00265   gc_anim_swap(item, new_anim->a);
00266   Py_INCREF(new_anim);
00267   s->anim = (PyObject*)new_anim;
00268   Py_DECREF(old_anim);
00269 
00270   Py_INCREF(Py_None);
00271   return Py_None;
00272 }
00273 
00274 static PyObject*
00275 py_gcompris_animcanvas_destroy(PyObject *self, PyObject *args)
00276 {
00277   py_GcomprisAnimCanvas *s = (py_GcomprisAnimCanvas*)self;
00278 
00279   if(!s->item) THROW_INACTIVE_ANIMATION;
00280 
00281   gc_anim_deactivate(s->item);
00282   Py_DECREF(s->anim);
00283   s->item = NULL;
00284   s->anim = NULL;
00285 
00286   Py_INCREF(Py_None);
00287   return Py_None;
00288 }
00289 
00290 #ifndef PyMODINIT_FUNC      /* declarations for DLL import/export */
00291 #define PyMODINIT_FUNC void
00292 #endif
00293 PyMODINIT_FUNC
00294 python_gcompris_anim_module_init(void)
00295 {
00296   PyObject* m;
00297 
00298   py_GcomprisAnimationType.tp_new = PyType_GenericNew;
00299   py_GcomprisAnimationType.ob_type = &PyType_Type;
00300   py_GcomprisAnimCanvasType.tp_new = PyType_GenericNew;
00301   py_GcomprisAnimCanvasType.ob_type = &PyType_Type;
00302   if (PyType_Ready(&py_GcomprisAnimationType) < 0)
00303       return;
00304   if (PyType_Ready(&py_GcomprisAnimCanvasType) < 0)
00305       return;
00306 
00307   m = Py_InitModule("_gcompris_anim", PythonGcomprisAnimModule);
00308 
00309   Py_INCREF(&py_GcomprisAnimationType);
00310   Py_INCREF(&py_GcomprisAnimCanvasType);
00311   PyModule_AddObject(m, "Animation", (PyObject *)&py_GcomprisAnimationType);
00312   PyModule_AddObject(m, "CanvasItem", (PyObject *)&py_GcomprisAnimCanvasType);
00313 }
00314