#include "cReactor.h"
static PyObject *AlreadyCalledException, *AlreadyCancelledException;
staticforward PyTypeObject cDelayedCallType;
cDelayedCall *
cDelayedCall_new(int delay_ms,
PyObject *callable,
PyObject *args,
PyObject *kw)
{
cDelayedCall *call;
struct timeval call_time;
gettimeofday(&call_time, NULL);
call_time.tv_usec += (delay_ms * 1000);
call_time.tv_sec += call_time.tv_usec / 1000000;
call_time.tv_usec = call_time.tv_usec % 1000000;
call = PyObject_New(cDelayedCall, &cDelayedCallType);
memcpy(&call->call_time, &call_time, sizeof(call_time));
call->reactor = NULL;
call->called = 0;
Py_INCREF(callable);
call->callable = callable;
if (!args)
{
call->args = PyTuple_New(0);
}
else
{
Py_INCREF(args);
call->args = args;
}
if (!kw)
{
call->kw = PyDict_New();
}
else
{
Py_INCREF(kw);
call->kw = kw;
}
return call;
}
static void
cDelayedCall_dealloc(PyObject *self)
{
cDelayedCall *call = (cDelayedCall *)self;
Py_DECREF(call->callable);
Py_XDECREF(call->args);
Py_XDECREF(call->kw);
free(call);
}
static PyObject *
cDelayedCall_getTime(PyObject *self, PyObject *args)
{
cDelayedCall *call = (cDelayedCall *)self;
double call_time;
if (!PyArg_ParseTuple(args, ":getTime"))
return NULL;
if (!call->reactor) {
if (call->called) {
PyErr_SetString(AlreadyCalledException, "");
return NULL;
} else {
PyErr_SetString(AlreadyCancelledException, "");
return NULL;
}
}
call_time = call->call_time.tv_sec + call->call_time.tv_usec / 1000000;
return PyFloat_FromDouble(call_time);
}
static PyObject *
cDelayedCall_cancel(PyObject *self, PyObject *args)
{
int rc;
cDelayedCall *call = (cDelayedCall *)self;
if (!call->reactor) {
if (call->called) {
PyErr_SetString(AlreadyCalledException, "");
return NULL;
} else {
PyErr_SetString(AlreadyCancelledException, "");
return NULL;
}
}
rc = cReactorUtil_RemoveDelayedCall(call->reactor, call);
if (rc != 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
cDelayedCall_delay(PyObject *self, PyObject *args)
{
cDelayedCall *call = (cDelayedCall *)self;
PyObject *delay_obj = NULL;
int delay_ms = 0;
int rc;
if (!PyArg_ParseTuple(args, "O:delay", &delay_obj))
return NULL;
if (delay_obj)
{
delay_ms = cReactorUtil_ConvertDelay(delay_obj);
if (delay_ms < 0)
{
return NULL;
}
}
if (!call->reactor) {
if (call->called) {
PyErr_SetString(AlreadyCalledException, "");
return NULL;
} else {
PyErr_SetString(AlreadyCancelledException, "");
return NULL;
}
}
call->call_time.tv_usec += (delay_ms * 1000);
call->call_time.tv_sec += call->call_time.tv_usec / 1000000;
call->call_time.tv_usec = call->call_time.tv_usec % 1000000;
rc = cReactorUtil_ReInsertDelayedCall(call->reactor, call);
if (rc != 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
cDelayedCall_reset(PyObject *self, PyObject *args)
{
cDelayedCall *call = (cDelayedCall *)self;
PyObject *delay_obj = NULL;
int delay_ms = 0;
int rc;
if (!PyArg_ParseTuple(args, "O:reset", &delay_obj))
return NULL;
if (delay_obj)
{
delay_ms = cReactorUtil_ConvertDelay(delay_obj);
if (delay_ms < 0)
{
return NULL;
}
}
if (!call->reactor) {
if (call->called) {
PyErr_SetString(AlreadyCalledException, "");
return NULL;
} else {
PyErr_SetString(AlreadyCancelledException, "");
return NULL;
}
}
gettimeofday(&call->call_time, NULL);
call->call_time.tv_usec += (delay_ms * 1000);
call->call_time.tv_sec += call->call_time.tv_usec / 1000000;
call->call_time.tv_usec = call->call_time.tv_usec % 1000000;
rc = cReactorUtil_ReInsertDelayedCall(call->reactor, call);
if (rc != 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
cDelayedCall_active(PyObject *self, PyObject *args)
{
cDelayedCall *call = (cDelayedCall *)self;
if (!PyArg_ParseTuple(args, ":active"))
return NULL;
if (call->called)
return PyInt_FromLong(0);
else
return PyInt_FromLong(1);
}
static PyMethodDef cDelayedCall_methods[] =
{
{ "getTime", cDelayedCall_getTime, METH_VARARGS, "getTime" },
{ "cancel", cDelayedCall_cancel, METH_VARARGS, "cancel" },
{ "delay", cDelayedCall_delay, METH_VARARGS, "delay" },
{ "reset", cDelayedCall_reset, METH_VARARGS, "reset" },
{ "active", cDelayedCall_active, METH_VARARGS, "active" },
{ NULL, NULL, METH_VARARGS, NULL },
};
static PyObject *
cDelayedCall_getattr(PyObject *self, char *attr_name)
{
PyObject *obj;
obj = Py_FindMethod(cDelayedCall_methods, self, attr_name);
if (obj)
return obj;
PyErr_SetString(PyExc_AttributeError, attr_name);
return NULL;
}
static PyTypeObject cDelayedCallType =
{
PyObject_HEAD_INIT(NULL)
0,
"cDelayedCall",
sizeof(cDelayedCall),
0,
cDelayedCall_dealloc,
NULL,
cDelayedCall_getattr,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL,
NULL,
NULL,
0,
};
void
cDelayedCall_init(void)
{
cDelayedCallType.ob_type = &PyType_Type;
AlreadyCalledException =
cReactorUtil_FromImport("twisted.internet.error",
"AlreadyCalled");
if (!AlreadyCalledException) {
PyErr_Print();
return;
}
AlreadyCancelledException =
cReactorUtil_FromImport("twisted.internet.error",
"AlreadyCancelled");
if (!AlreadyCancelledException) {
PyErr_Print();
return;
}
}