summaryrefslogtreecommitdiffstats
path: root/objects
diff options
context:
space:
mode:
authorChristopher Davis <loafier@gmail.com>2006-06-25 05:47:20 +0000
committerChristopher Davis <loafier@gmail.com>2006-06-25 05:47:20 +0000
commit3b04cf6a1210f97d8144ee1ba646186aca4912ef (patch)
treed2d4081cd3043bd3b1d403f93f147e94a471aeac /objects
parentd75ad2cebb61a3cb46570cecbc257693c528da0b (diff)
downloadirssi-python-3b04cf6a1210f97d8144ee1ba646186aca4912ef.tar.gz
irssi-python-3b04cf6a1210f97d8144ee1ba646186aca4912ef.tar.xz
irssi-python-3b04cf6a1210f97d8144ee1ba646186aca4912ef.zip
worked more on signals. added signal emit, signal register,
unregister, cmd unbind, signal remove. Needs testing. Need to find a better way of dealing with constants, too. git-svn-id: http://svn.irssi.org/repos/irssi-python@4291 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'objects')
-rw-r--r--objects/base-objects.h9
-rw-r--r--objects/pyscript-object.c213
-rw-r--r--objects/pyscript-object.h2
3 files changed, 196 insertions, 28 deletions
diff --git a/objects/base-objects.h b/objects/base-objects.h
index d2f6acb..ed2edfc 100644
--- a/objects/base-objects.h
+++ b/objects/base-objects.h
@@ -20,6 +20,15 @@
type *data; \
int cleanup_installed;
+/* to access data from any irssi object */
+typedef struct
+{
+ PyObject_HEAD
+ void *data;
+} PyIrssiObject;
+
+#define DATA(obj) (((PyIrssiObject *)obj)->data)
+
/* base for classes with a type */
typedef struct
{
diff --git a/objects/pyscript-object.c b/objects/pyscript-object.c
index d4ec5f1..665828c 100644
--- a/objects/pyscript-object.c
+++ b/objects/pyscript-object.c
@@ -65,9 +65,10 @@ static PyObject *PyScript_new(PyTypeObject *type, PyObject *args, PyObject *kwds
return (PyObject *)self;
}
-//FIXME: add prioriety as arg
PyDoc_STRVAR(PyScript_command_bind_doc,
- "Bind a command"
+ "command_bind(command, func, catetory=None, priority=SIGNAL_PRIORITY_DEFAULT) -> None\n"
+ "\n"
+ "Add handler for a command\n"
);
static PyObject *PyScript_command_bind(PyScript *self, PyObject *args, PyObject *kwds)
{
@@ -76,59 +77,193 @@ static PyObject *PyScript_command_bind(PyScript *self, PyObject *args, PyObject
PyObject *func;
char *category = NULL;
int priority = SIGNAL_PRIORITY_DEFAULT;
- PY_SIGNAL_REC *srec;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|si", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|zi", kwlist,
&cmd, &func, &category, &priority))
return NULL;
if (!PyCallable_Check(func))
return PyErr_Format(PyExc_TypeError, "func must be callable");
- srec = pysignals_command_bind(cmd, func, category, priority);
- if (!srec)
+ if (!pysignals_command_bind_list(&self->signals, cmd, func, category, priority))
return PyErr_Format(PyExc_RuntimeError, "unable to bind command");
- /* add record to internal list*/
- self->signals = g_slist_append(self->signals, srec);
-
Py_RETURN_NONE;
}
PyDoc_STRVAR(PyScript_signal_add_doc,
- "add signal"
+ "signal_add(signal, func, priority=SIGNAL_PRIORITY_DEFAULT) -> None\n"
+ "\n"
+ "Add handler for signal"
);
static PyObject *PyScript_signal_add(PyScript *self, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"signal", "func", "category", "priority", NULL};
+ static char *kwlist[] = {"signal", "func", "priority", NULL};
char *signal;
PyObject *func;
- char *category = NULL;
int priority = SIGNAL_PRIORITY_DEFAULT;
- PY_SIGNAL_REC *srec;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|si", kwlist,
- &signal, &func, &category, &priority))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|i", kwlist,
+ &signal, &func, &priority))
return NULL;
if (!PyCallable_Check(func))
return PyErr_Format(PyExc_TypeError, "func must be callable");
- srec = pysignals_signal_add(signal, func, priority);
- if (!srec)
+ if (!pysignals_signal_add_list(&self->signals, signal, func, priority))
return PyErr_Format(PyExc_KeyError, "unable to find signal, '%s'", signal);
- self->signals = g_slist_append(self->signals, srec);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(PyScript_signal_remove_doc,
+ "signal_remove(signal, func=None) -> None\n"
+ "\n"
+ "Remove signal handler\n"
+);
+static PyObject *PyScript_signal_remove(PyScript *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"signal", "func", NULL};
+ char *signal = "";
+ PyObject *func = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
+ &signal, &func))
+ return NULL;
+
+ if (!PyCallable_Check(func) && func != Py_None)
+ return PyErr_Format(PyExc_TypeError, "func must be callable or None");
+ if (func == Py_None)
+ func = NULL;
+
+ if (!pysignals_remove_search(&self->signals, signal, func, PSG_SIGNAL))
+ return PyErr_Format(PyExc_KeyError, "can't find signal");
+
Py_RETURN_NONE;
}
-static PyMemberDef PyScript_members[] = {
- {"argv", T_OBJECT, offsetof(PyScript, argv), 0, "Script arguments"},
- {"module", T_OBJECT_EX, offsetof(PyScript, module), RO, "Script module"},
- {"modules", T_OBJECT_EX, offsetof(PyScript, modules), 0, "Imported modules"},
- {NULL} /* Sentinel */
-};
+PyDoc_STRVAR(PyScript_command_unbind_doc,
+ "command_unbind(command, func=None) -> None\n"
+ "\n"
+ "Remove command handler\n"
+);
+static PyObject *PyScript_command_unbind(PyScript *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"command", "func", NULL};
+ char *command = "";
+ PyObject *func = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
+ &command, &func))
+ return NULL;
+
+ if (!PyCallable_Check(func) && func != Py_None)
+ return PyErr_Format(PyExc_TypeError, "func must be callable or None");
+
+ if (func == Py_None)
+ func = NULL;
+
+ if (!pysignals_remove_search(&self->signals, command, func, PSG_COMMAND))
+ return PyErr_Format(PyExc_KeyError, "can't find command");
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(PyScript_signal_register_doc,
+ "signal_register(signal, arglist) -> None\n"
+ "\n"
+ "Register a new dynamic signal for use with irssi_python\n"
+ "arglist is a string of character codes representing the type of each argument\n"
+ "of the signal handler function.\n"
+ "\n"
+ " Scalars\n"
+ " s -> char *\n"
+ " i -> int\n"
+ "\n"
+ " Chat objects\n"
+ " c -> CHATNET_REC\n"
+ " S -> SERVER_REC\n"
+ " C -> CHANNEL_REC\n"
+ " q -> QUERY_REC\n"
+ " n -> NICK_REC\n"
+ " W -> WI_ITEM_REC\n"
+ "\n"
+ " Irssi objects\n"
+ " d -> DCC_REC\n"
+ "\n"
+ " Other objects\n"
+ " r -> RECONNECT_REC\n"
+ " o -> COMMAND_REC\n"
+ " l -> LOG_REC\n"
+ " a -> RAWLOG_REC\n"
+ " g -> IGNORE_REC\n"
+ " b -> BAN_REC\n"
+ " N -> NETSPLIT_REC\n"
+ " e -> NETSPLIT_SERVER_REC\n"
+ " O -> NOTIFYLIST_REC\n"
+ " p -> PROCESS_REC\n"
+ " t -> TEXT_DEST_REC\n"
+ " w -> WINDOW_REC\n"
+);
+static PyObject *PyScript_signal_register(PyScript *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"signal", "arglist", NULL};
+ static const char *good_codes = "sicSCqnWdrolagbNeOptw";
+ char *signal = "";
+ char *arglist = "";
+ int i;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
+ &signal, &arglist))
+ return NULL;
+
+ for (i = 0; arglist[i]; i++)
+ if (!strchr(good_codes, arglist[i]))
+ return PyErr_Format(PyExc_TypeError, "invalid code, %c", arglist[i]);
+
+ if (i >= SIGNAL_MAX_ARGUMENTS)
+ return PyErr_Format(PyExc_TypeError,
+ "arglist greater than SIGNAL_MAX_ARGUMENTS (%d)",
+ SIGNAL_MAX_ARGUMENTS);
+
+ if (!pysignals_register(signal, arglist))
+ return PyErr_Format(PyExc_TypeError, "signal present with different args");
+
+ self->registered_signals = g_slist_append(self->registered_signals,
+ g_strdup(signal));
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(PyScript_signal_unregister_doc,
+ "signal_unregister(signal) -> None\n"
+ "\n"
+ "Unregister dynamic signal\n"
+);
+static PyObject *PyScript_signal_unregister(PyScript *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"signal", NULL};
+ char *signal = "";
+ GSList *search;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
+ &signal))
+ return NULL;
+
+ search = g_slist_find_custom(self->registered_signals, signal, (GCompareFunc)strcmp);
+ if (!search)
+ return PyErr_Format(PyExc_KeyError, "script has not registered that signal");
+
+ g_free(search->data);
+ self->registered_signals = g_slist_delete_link(self->registered_signals, search);
+
+ if (!pysignals_unregister(signal))
+ return PyErr_Format(PyExc_SystemError,
+ "script registered signal, but signal does not exist");
+
+ Py_RETURN_NONE;
+}
/* Methods for object */
static PyMethodDef PyScript_methods[] = {
@@ -136,6 +271,21 @@ static PyMethodDef PyScript_methods[] = {
PyScript_command_bind_doc},
{"signal_add", (PyCFunction)PyScript_signal_add, METH_VARARGS | METH_KEYWORDS,
PyScript_signal_add_doc},
+ {"signal_remove", (PyCFunction)PyScript_signal_remove, METH_VARARGS | METH_KEYWORDS,
+ PyScript_signal_remove_doc},
+ {"command_unbind", (PyCFunction)PyScript_command_unbind, METH_VARARGS | METH_KEYWORDS,
+ PyScript_command_unbind_doc},
+ {"signal_register", (PyCFunction)PyScript_signal_register, METH_VARARGS | METH_KEYWORDS,
+ PyScript_signal_register_doc},
+ {"signal_unregister", (PyCFunction)PyScript_signal_unregister, METH_VARARGS | METH_KEYWORDS,
+ PyScript_signal_unregister_doc},
+ {NULL} /* Sentinel */
+};
+
+static PyMemberDef PyScript_members[] = {
+ {"argv", T_OBJECT, offsetof(PyScript, argv), 0, "Script arguments"},
+ {"module", T_OBJECT_EX, offsetof(PyScript, module), RO, "Script module"},
+ {"modules", T_OBJECT_EX, offsetof(PyScript, modules), 0, "Imported modules"},
{NULL} /* Sentinel */
};
@@ -224,11 +374,20 @@ void pyscript_remove_signals(PyObject *script)
self = (PyScript *) script;
- for (node = self->signals; node != NULL; node = node->next)
- pysignals_remove_generic((PY_SIGNAL_REC *)node->data);
-
+ /* remove bound signals */
+ pysignals_remove_list(self->signals);
g_slist_free(self->signals);
self->signals = NULL;
+
+ /* remove registered signals */
+ for (node = self->registered_signals; node; node = node->next)
+ {
+ pysignals_unregister(node->data);
+ g_free(node->data);
+ }
+
+ g_slist_free(self->registered_signals);
+ self->registered_signals = NULL;
}
void pyscript_clear_modules(PyObject *script)
diff --git a/objects/pyscript-object.h b/objects/pyscript-object.h
index ee32d8c..8565053 100644
--- a/objects/pyscript-object.h
+++ b/objects/pyscript-object.h
@@ -3,13 +3,13 @@
#include <Python.h>
#include <glib.h>
-//FIXME: add list of registered dynamic signal names
typedef struct {
PyObject_HEAD
PyObject *module; /* module object */
PyObject *argv; /* list of argument strings from the load command */
PyObject *modules; /* dict of imported modules for script */
GSList *signals; /* list of bound signals and commands */
+ GSList *registered_signals; /* list of signal names registered */
} PyScript;
extern PyTypeObject PyScriptType;