From 34cdeaae9369af5dce3ce3a4a7756c033bc44cc5 Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Mon, 3 Jul 2006 06:00:18 +0000 Subject: worked on formats. working on themes now; testing adding functions and methods to objects git-svn-id: http://svn.irssi.org/repos/irssi-python@4295 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- pysource.c | 166 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 70 insertions(+), 96 deletions(-) (limited to 'pysource.c') diff --git a/pysource.c b/pysource.c index f3a0663..413ab2c 100644 --- a/pysource.c +++ b/pysource.c @@ -4,153 +4,127 @@ typedef struct _PY_SOURCE_REC { - int once; int tag; + GSList **tag_list; int fd; - GSList **container; /* "container" points to a list owned by a Script object */ - PyObject *handler; + PyObject *func; PyObject *data; } PY_SOURCE_REC; -static PY_SOURCE_REC *py_source_new(GSList **list, int once, PyObject *handler, PyObject *data) +static PY_SOURCE_REC *py_source_rec_new(GSList **tag_list, int fd, PyObject *func, PyObject *data) { PY_SOURCE_REC *rec; rec = g_new0(PY_SOURCE_REC, 1); - rec->once = once; - rec->fd = -1; - rec->handler = handler; + rec->tag_list = tag_list; + rec->fd = fd; + rec->func = func; rec->data = data; - rec->container = list; - Py_INCREF(handler); - Py_XINCREF(data); + Py_INCREF(func); + Py_XINCREF(data); return rec; } +static int py_remove_tag(GSList **list, int handle) +{ + GSList *node; + + node = g_slist_find(*list, GINT_TO_POINTER(handle)); + if (!node) + return 0; + + *list = g_slist_delete_link(*list, node); + + return 1; +} + static void py_source_destroy(PY_SOURCE_REC *rec) { - g_source_remove(rec->tag); - Py_DECREF(rec->handler); + g_return_if_fail(py_remove_tag(rec->tag_list, rec->tag) == 1); + Py_DECREF(rec->func); Py_XDECREF(rec->data); g_free(rec); } -static int py_source_proxy(PY_SOURCE_REC *rec) +static int py_handle_ret(PyObject *ret) { - char args[3] = {0,0,0}; - int fd; - PyObject *ret; - PyObject *handler, *data; - - /* Copy data out of the rec (there's not much). The rec may be deleted in - the if block below or by the Python code executed. Protect handler & data - with INCREF. - */ + int res; - fd = rec->fd; - handler = rec->handler; - data = rec->data; - Py_INCREF(handler); - Py_XINCREF(data); - - if (rec->once) + if (!ret) { - *rec->container = g_slist_remove(*rec->container, rec); - py_source_destroy(rec); + PyErr_Print(); + res = FALSE; + } + else + { + res = PyObject_IsTrue(ret); + Py_DECREF(ret); } - /* call python function with fd and/or data if available. - IO handler will be called with either "iO" or "i". - Timeout with "O" or "". - */ + return res; +} - if (fd >= 0) - { - /* IO handler */ - args[0] = 'i'; - if (data) - args[1] = 'O'; +static int py_timeout_proxy(PY_SOURCE_REC *rec) +{ + PyObject *ret; - ret = PyObject_CallFunction(handler, args, fd, data); - } + g_return_val_if_fail(rec != NULL, FALSE); + + if (rec->data) + ret = PyObject_CallFunction(rec->func, "O", rec->data); else - { - /* Timeout handler */ - if (data) - args[0] = 'O'; + ret = PyObject_CallFunction(rec->func, ""); - ret = PyObject_CallFunction(handler, args, data); - } + return py_handle_ret(ret); +} - if (!ret) - PyErr_Print(); +static int py_io_proxy(GIOChannel *src, GIOCondition condition, PY_SOURCE_REC *rec) +{ + PyObject *ret; + + g_return_val_if_fail(rec != NULL, FALSE); + + if (rec->data) + ret = PyObject_CallFunction(rec->func, "iiO", rec->fd, condition, rec->data); else - Py_DECREF(ret); + ret = PyObject_CallFunction(rec->func, "ii", rec->fd, condition); - Py_DECREF(handler); - Py_XDECREF(data); - - return 1; + return py_handle_ret(ret); } -int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data, int once) +int pysource_timeout_add_list(GSList **list, int msecs, PyObject *func, PyObject *data) { PY_SOURCE_REC *rec; g_return_val_if_fail(func != NULL, -1); - rec = py_source_new(list, once, func, data); - rec->tag = g_timeout_add(msecs, (GSourceFunc)py_source_proxy, rec); - - *list = g_slist_append(*list, rec); - + rec = py_source_rec_new(list, -1, func, data); + rec->tag = g_timeout_add_full(G_PRIORITY_DEFAULT, msecs, + (GSourceFunc)py_timeout_proxy, rec, + (GDestroyNotify)py_source_destroy); + + *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag)); + return rec->tag; } -int pysource_input_add_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data, int once) +int pysource_io_add_watch_list(GSList **list, int fd, int cond, PyObject *func, PyObject *data) { PY_SOURCE_REC *rec; GIOChannel *channel; g_return_val_if_fail(func != NULL, 1); - rec = py_source_new(list, once, func, data); - rec->fd = fd; + + rec = py_source_rec_new(list, fd, func, data); channel = g_io_channel_unix_new(fd); - rec->tag = g_input_add(channel, cond, (GInputFunction)py_source_proxy, rec); + rec->tag = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, + (GIOFunc)py_io_proxy, rec, + (GDestroyNotify)py_source_destroy); g_io_channel_unref(channel); - *list = g_slist_append(*list, rec); + *list = g_slist_append(*list, GINT_TO_POINTER(rec->tag)); return rec->tag; } - -int pysource_remove_tag(GSList **list, int handle) -{ - GSList *node; - - for (node = *list; node != NULL; node = node->next) - { - PY_SOURCE_REC *rec = node->data; - - if (rec->tag == handle) - { - py_source_destroy(rec); - *list = g_slist_delete_link(*list, node); - - return 1; - } - } - - return 0; -} - -void pysource_remove_list(GSList *list) -{ - GSList *node; - - for (node = list; node != NULL; node = node->next) - py_source_destroy(node->data); -} - -- cgit