From: Andreas Monzner Date: Thu, 14 Feb 2008 19:44:14 +0000 (+0000) Subject: add support for cyclic garbage collection to eTimer and eSocketNotifier X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=6f73e6abddf4170357c490966d0e1c622eb376f5 add support for cyclic garbage collection to eTimer and eSocketNotifier class, add simpler method to set a timer callback.. or remove.. instead of timer.timeout.get().append(func).. or .remove(func)... now it is possible to do timer.callback.append(func)... timer.callback.remove(func) (the old method still works..but is now deprecated) --- diff --git a/lib/base/ebase.cpp b/lib/base/ebase.cpp index effd725..bf41dc0 100644 --- a/lib/base/ebase.cpp +++ b/lib/base/ebase.cpp @@ -390,3 +390,420 @@ void eMainloop::applyTimeOffset() } eApplication* eApp = 0; + +#include "structmember.h" + +extern "C" { + +// eTimer replacement + +struct eTimerPy +{ + PyObject_HEAD + eTimer *tm; + PyObject *in_weakreflist; /* List of weak references */ +}; + +static int +eTimerPy_traverse(eTimerPy *self, visitproc visit, void *arg) +{ + PyObject *obj = self->tm->timeout.get(); + Py_VISIT(obj); + return 0; +} + +static int +eTimerPy_clear(eTimerPy *self) +{ + PyObject *obj = self->tm->timeout.get(); + Py_CLEAR(obj); + return 0; +} + +static void +eTimerPy_dealloc(eTimerPy* self) +{ + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + eTimerPy_clear(self); + delete self->tm; + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject * +eTimerPy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + eTimerPy *self = (eTimerPy *)type->tp_alloc(type, 0); + self->tm = new eTimer(eApp); + self->in_weakreflist = NULL; + return (PyObject *)self; +} + +static PyObject * +eTimerPy_is_active(eTimerPy* self) +{ + PyObject *ret = NULL; + ret = !!self->tm->isActive() ? Py_True : Py_False; + Org_Py_INCREF(ret); + return ret; +} + +static PyObject * +eTimerPy_start(eTimerPy* self, PyObject *args) +{ + long v=0; + long singleShot=0; + if (PyTuple_Size(args) > 1) + { + if (!PyArg_ParseTuple(args, "ll", &v, &singleShot)) // when 2nd arg is a value + { + PyObject *obj=0; + if (!PyArg_ParseTuple(args, "lO", &v, &obj)) // get 2nd arg as python object + return NULL; + else if (obj == Py_True) + singleShot=1; + else if (obj != Py_False) + return NULL; + } + } + else if (!PyArg_ParseTuple(args, "l", &v)) + return NULL; + self->tm->start(v, singleShot); + Py_RETURN_NONE; +} + +static PyObject * +eTimerPy_start_long(eTimerPy* self, PyObject *args) +{ + long v=0; + if (!PyArg_ParseTuple(args, "l", &v)) { + return NULL; + } + self->tm->startLongTimer(v); + Py_RETURN_NONE; +} + +static PyObject * +eTimerPy_change_interval(eTimerPy* self, PyObject *args) +{ + long v=0; + if (!PyArg_ParseTuple(args, "l", &v)) { + return NULL; + } + self->tm->changeInterval(v); + Py_RETURN_NONE; +} + +static PyObject * +eTimerPy_stop(eTimerPy* self) +{ + self->tm->stop(); + Py_RETURN_NONE; +} + +static PyObject * +eTimerPy_get_callback_list(eTimerPy *self) +{ //used for compatibilty with the old eTimer + return self->tm->timeout.get(); +} + +static PyMethodDef eTimerPy_methods[] = { + {"isActive", (PyCFunction)eTimerPy_is_active, METH_NOARGS, + "returns the timer state" + }, + {"start", (PyCFunction)eTimerPy_start, METH_VARARGS, + "start timer with interval in msecs" + }, + {"startLongTimer", (PyCFunction)eTimerPy_start_long, METH_VARARGS, + "start timer with interval in secs" + }, + {"changeInterval", (PyCFunction)eTimerPy_change_interval, METH_VARARGS, + "change interval of a timer (in msecs)" + }, + {"stop", (PyCFunction)eTimerPy_stop, METH_NOARGS, + "stops the timer" + }, + //used for compatibilty with the old eTimer + {"get", (PyCFunction)eTimerPy_get_callback_list, METH_NOARGS, + "get timeout callback list" + }, + {NULL} /* Sentinel */ +}; + +static PyObject * +eTimerPy_get_cb_list(eTimerPy *self, void *closure) +{ + return self->tm->timeout.get(); +} + +static PyObject * +eTimerPy_timeout(eTimerPy *self, void *closure) +{ //used for compatibilty with the old eTimer + Org_Py_INCREF((PyObject*)self); + return (PyObject*)self; +} + +static PyGetSetDef eTimerPy_getseters[] = { + {"callback", + (getter)eTimerPy_get_cb_list, (setter)0, + "returns the callback python list", + NULL}, + + {"timeout", //used for compatibilty with the old eTimer + (getter)eTimerPy_timeout, (setter)0, + "synonym for our self", + NULL}, + + {NULL} /* Sentinel */ +}; + +static PyTypeObject eTimerPyType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "eBaseImpl.eTimer", /*tp_name*/ + sizeof(eTimerPy), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)eTimerPy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + "eTimer objects", /* tp_doc */ + (traverseproc)eTimerPy_traverse, /* tp_traverse */ + (inquiry)eTimerPy_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(eTimerPy, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + eTimerPy_methods, /* tp_methods */ + 0, /* tp_members */ + eTimerPy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + eTimerPy_new, /* tp_new */ +}; + +// eSocketNotifier replacement + +struct eSocketNotifierPy +{ + PyObject_HEAD + eSocketNotifier *sn; + PyObject *in_weakreflist; /* List of weak references */ +}; + +static int +eSocketNotifierPy_traverse(eSocketNotifierPy *self, visitproc visit, void *arg) +{ + PyObject *obj = self->sn->activated.get(); + Py_VISIT(obj); + return 0; +} + +static int +eSocketNotifierPy_clear(eSocketNotifierPy *self) +{ + PyObject *obj = self->sn->activated.get(); + Py_CLEAR(obj); + return 0; +} + +static void +eSocketNotifierPy_dealloc(eSocketNotifierPy* self) +{ + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + eSocketNotifierPy_clear(self); + delete self->sn; + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject * +eSocketNotifierPy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + eSocketNotifierPy *self = (eSocketNotifierPy *)type->tp_alloc(type, 0); + int fd, req, immediate_start = 1, size = PyTuple_Size(args); + if (size > 2) + { + if (!PyArg_ParseTuple(args, "iii", &fd, &req, &immediate_start)) + { + PyObject *obj = NULL; + if (!PyArg_ParseTuple(args, "iiO", &fd, &req, &immediate_start)) + return NULL; + if (obj == Py_False) + immediate_start = 0; + else if (obj != Py_True) + return NULL; + } + } + else if (size < 2 || !PyArg_ParseTuple(args, "ii", &fd, &req)) + return NULL; + self->sn = new eSocketNotifier(eApp, fd, req, immediate_start); + self->in_weakreflist = NULL; + return (PyObject *)self; +} + +static PyObject * +eSocketNotifierPy_is_running(eSocketNotifierPy* self) +{ + PyObject *ret = self->sn->isRunning() ? Py_True : Py_False; + Org_Py_INCREF(ret); + return ret; +} + +static PyObject * +eSocketNotifierPy_start(eSocketNotifierPy* self) +{ + self->sn->start(); + Py_RETURN_NONE; +} + +static PyObject * +eSocketNotifierPy_stop(eSocketNotifierPy* self) +{ + self->sn->stop(); + Py_RETURN_NONE; +} + +static PyObject * +eSocketNotifierPy_get_fd(eSocketNotifierPy* self) +{ + return PyInt_FromLong(self->sn->getFD()); +} + +static PyObject * +eSocketNotifierPy_get_requested(eSocketNotifierPy* self) +{ + return PyInt_FromLong(self->sn->getRequested()); +} + +static PyObject * +eSocketNotifierPy_set_requested(eSocketNotifierPy* self, PyObject *args) +{ + int req; + if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &req)) + return NULL; + self->sn->setRequested(req); + Py_RETURN_NONE; +} + +static PyMethodDef eSocketNotifierPy_methods[] = { + {"isRunning", (PyCFunction)eSocketNotifierPy_is_running, METH_NOARGS, + "returns the running state" + }, + {"start", (PyCFunction)eSocketNotifierPy_start, METH_NOARGS, + "start the sn" + }, + {"stop", (PyCFunction)eSocketNotifierPy_stop, METH_NOARGS, + "stops the sn" + }, + {"getFD", (PyCFunction)eSocketNotifierPy_get_fd, METH_NOARGS, + "get file descriptor" + }, + {"getRequested", (PyCFunction)eSocketNotifierPy_get_requested, METH_NOARGS, + "get requested" + }, + {"setRequested", (PyCFunction)eSocketNotifierPy_set_requested, METH_VARARGS, + "set requested" + }, + {NULL} /* Sentinel */ +}; + +static PyObject * +eSocketNotifierPy_get_cb_list(eSocketNotifierPy *self, void *closure) +{ + return self->sn->activated.get(); +} + +static PyGetSetDef eSocketNotifierPy_getseters[] = { + {"callback", + (getter)eSocketNotifierPy_get_cb_list, (setter)0, + "returns the callback python list", + NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject eSocketNotifierPyType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "eBaseImpl.eSocketNotifier", /*tp_name*/ + sizeof(eSocketNotifierPy), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)eSocketNotifierPy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + "eTimer objects", /* tp_doc */ + (traverseproc)eSocketNotifierPy_traverse, /* tp_traverse */ + (inquiry)eSocketNotifierPy_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(eSocketNotifierPy, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + eSocketNotifierPy_methods, /* tp_methods */ + 0, /* tp_members */ + eSocketNotifierPy_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + eSocketNotifierPy_new, /* tp_new */ +}; + +static PyMethodDef module_methods[] = { + {NULL} /* Sentinel */ +}; + +void eBaseInit(void) +{ + PyObject* m; + + m = Py_InitModule3("eBaseImpl", module_methods, + "Module that implements some enigma classes with working cyclic garbage collection."); + + if (m == NULL) + return; + + if (!PyType_Ready(&eTimerPyType)) + { + Org_Py_INCREF((PyObject*)&eTimerPyType); + PyModule_AddObject(m, "eTimer", (PyObject*)&eTimerPyType); + } + if (!PyType_Ready(&eSocketNotifierPyType)) + { + Org_Py_INCREF((PyObject*)&eSocketNotifierPyType); + PyModule_AddObject(m, "eSocketNotifier", (PyObject*)&eSocketNotifierPyType); + } +} +} diff --git a/lib/base/ebase.h b/lib/base/ebase.h index 4378711..c4dab62 100644 --- a/lib/base/ebase.h +++ b/lib/base/ebase.h @@ -132,8 +132,6 @@ static inline long timeout_usec ( const timeval & orig ) return (orig-now).tv_sec*1000000 + (orig-now).tv_usec; } -#endif - class eMainloop; // die beiden signalquellen: SocketNotifier... @@ -154,6 +152,7 @@ private: int fd; int state; int requested; // requested events (POLLIN, ...) + void activate(int what) { /*emit*/ activated(what); } public: /** * \brief Constructs a eSocketNotifier. @@ -166,7 +165,6 @@ public: ~eSocketNotifier(); PSignal1 activated; - void activate(int what) { /*emit*/ activated(what); } void start(); void stop(); @@ -177,6 +175,8 @@ public: void setRequested(int req) { requested=req; } }; +#endif + class eTimer; // werden in einer mainloop verarbeitet @@ -265,6 +265,7 @@ public: } }; +#ifndef SWIG // ... und Timer /** * \brief Gives a callback after a specified timeout. @@ -280,6 +281,7 @@ class eTimer bool bSingleShot; bool bActive; void addTimeOffset(int); + void activate(); public: /** * \brief Constructs a timer. @@ -291,17 +293,17 @@ public: ~eTimer() { if (bActive) stop(); } PSignal0 timeout; - void activate(); bool isActive() { return bActive; } + timeval &getNextActivation() { return nextActivation; } void start(long msec, bool b=false); void stop(); void changeInterval(long msek); -#ifndef SWIG - bool operator<(const eTimer& t) const { return nextActivation < t.nextActivation; } -#endif void startLongTimer( int seconds ); + bool operator<(const eTimer& t) const { return nextActivation < t.nextActivation; } }; +#endif // SWIG + #endif diff --git a/lib/python/Components/Clock.py b/lib/python/Components/Clock.py index ddd6ffb..338101e 100644 --- a/lib/python/Components/Clock.py +++ b/lib/python/Components/Clock.py @@ -14,7 +14,7 @@ class Clock(VariableText, HTMLComponent, GUIComponent): self.doClock() self.clockTimer = eTimer() - self.clockTimer.timeout.get().append(self.doClock) + self.clockTimer.callback.append(self.doClock) def onShow(self): self.doClock() diff --git a/lib/python/Components/ConditionalWidget.py b/lib/python/Components/ConditionalWidget.py index f4b9983..192813f 100644 --- a/lib/python/Components/ConditionalWidget.py +++ b/lib/python/Components/ConditionalWidget.py @@ -9,7 +9,7 @@ class ConditionalWidget(GUIComponent): if (withTimer): self.conditionCheckTimer = eTimer() - self.conditionCheckTimer.timeout.get().append(self.update) + self.conditionCheckTimer.callback.append(self.update) self.conditionCheckTimer.start(1000) def postWidgetCreate(self, instance): @@ -38,7 +38,7 @@ class BlinkingWidget(GUIComponent): self.blinking = False self.setBlinkTime(500) self.timer = eTimer() - self.timer.timeout.get().append(self.blink) + self.timer.callback.append(self.blink) def setBlinkTime(self, time): self.blinktime = time diff --git a/lib/python/Components/ConfigList.py b/lib/python/Components/ConfigList.py index f42d6a9..d1b295b 100644 --- a/lib/python/Components/ConfigList.py +++ b/lib/python/Components/ConfigList.py @@ -19,7 +19,7 @@ class ConfigList(HTMLComponent, GUIComponent, object): def execBegin(self): rcinput = eRCInput.getInstance() rcinput.setKeyboardMode(rcinput.kmAscii) - self.timer.timeout.get().append(self.timeout) + self.timer.callback.append(self.timeout) def execEnd(self): rcinput = eRCInput.getInstance() diff --git a/lib/python/Components/Converter/ConditionalShowHide.py b/lib/python/Components/Converter/ConditionalShowHide.py index 50e8b1a..f5ec703 100644 --- a/lib/python/Components/Converter/ConditionalShowHide.py +++ b/lib/python/Components/Converter/ConditionalShowHide.py @@ -10,8 +10,8 @@ class ConditionalShowHide(Converter, object): if self.blink: self.blinktime = 500 self.timer = eTimer() - self.timer.timeout.get().append(self.blinkFunc) - else: + self.timer.callback.append(self.blinkFunc) + else self.timer = None def blinkFunc(self): diff --git a/lib/python/Components/Converter/Poll.py b/lib/python/Components/Converter/Poll.py index f41765d..33b9f30 100644 --- a/lib/python/Components/Converter/Poll.py +++ b/lib/python/Components/Converter/Poll.py @@ -3,7 +3,7 @@ from enigma import eTimer class Poll(object): def __init__(self): self.__poll_timer = eTimer() - self.__poll_timer.timeout.get().append(self.poll) + self.__poll_timer.callback.append(self.poll) self.__interval = 1000 self.__enabled = False diff --git a/lib/python/Components/PerServiceDisplay.py b/lib/python/Components/PerServiceDisplay.py index 6e02cce..2d0a71e 100644 --- a/lib/python/Components/PerServiceDisplay.py +++ b/lib/python/Components/PerServiceDisplay.py @@ -11,7 +11,7 @@ class PerServiceBase(object): self.navcore = navcore self.navcore.event.append(self.event_callback) self.poll_timer = eTimer() - self.poll_timer.timeout.get().append(self.poll) + self.poll_timer.callback.append(self.poll) self.with_event = with_event # start with stopped state, so simulate that diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index 3cc8c66..f6ecaf0 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -24,7 +24,7 @@ class MovingPixmap(Pixmap): self.clearPath() self.moveTimer = eTimer() - self.moveTimer.timeout.get().append(self.doMove) + self.moveTimer.callback.append(self.doMove) def clearPath(self, repeated = False): if (self.moving): diff --git a/lib/python/Components/ServicePosition.py b/lib/python/Components/ServicePosition.py index 6f7082d..985f884 100644 --- a/lib/python/Components/ServicePosition.py +++ b/lib/python/Components/ServicePosition.py @@ -12,7 +12,7 @@ class ServicePosition(PerServiceDisplay, object): def __init__(self, navcore, type): object.__init__(self) self.updateTimer = eTimer() - self.updateTimer.timeout.get().append(self.update) + self.updateTimer.callback.append(self.update) PerServiceDisplay.__init__(self, navcore, { iPlayableService.evStart: self.newService, diff --git a/lib/python/Components/Sources/Boolean.py b/lib/python/Components/Sources/Boolean.py index 21c2c2b..97b92bc 100644 --- a/lib/python/Components/Sources/Boolean.py +++ b/lib/python/Components/Sources/Boolean.py @@ -16,7 +16,7 @@ class Boolean(Source, object): self.fixed = fixed if poll > 0: self.poll_timer = eTimer() - self.poll_timer.timeout.get().append(self.poll) + self.poll_timer.callback.append(self.poll) self.poll_timer.start(poll) else: self.poll_timer = None diff --git a/lib/python/Components/Sources/Clock.py b/lib/python/Components/Sources/Clock.py index b59a20d..60fa7ac 100644 --- a/lib/python/Components/Sources/Clock.py +++ b/lib/python/Components/Sources/Clock.py @@ -8,7 +8,7 @@ class Clock(Source): def __init__(self): Source.__init__(self) self.clock_timer = eTimer() - self.clock_timer.timeout.get().append(self.poll) + self.clock_timer.callback.append(self.poll) self.clock_timer.start(1000) @cached diff --git a/lib/python/Components/Sources/FrontendStatus.py b/lib/python/Components/Sources/FrontendStatus.py index 4d38f75..141bd8a 100644 --- a/lib/python/Components/Sources/FrontendStatus.py +++ b/lib/python/Components/Sources/FrontendStatus.py @@ -9,7 +9,7 @@ class FrontendStatus(Source): self.frontend_source = frontend_source self.invalidate() self.poll_timer = eTimer() - self.poll_timer.timeout.get().append(self.updateFrontendStatus) + self.poll_timer.callback.append(self.updateFrontendStatus) self.poll_timer.start(update_interval) def invalidate(self): diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py index 4f31fa4..80a07df 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py @@ -380,7 +380,7 @@ class GraphMultiEPG(Screen): },-1) self.updateTimelineTimer = eTimer() - self.updateTimelineTimer.timeout.get().append(self.moveTimeLines) + self.updateTimelineTimer.callback.append(self.moveTimeLines) self.updateTimelineTimer.start(60*1000) self.onLayoutFinish.append(self.onCreate) diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 63e2b30..03d7617 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -159,11 +159,11 @@ class MediaPlayer(Screen, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSup self.righttimer = False self.rightKeyTimer = eTimer() - self.rightKeyTimer.timeout.get().append(self.rightTimerFire) + self.rightKeyTimer.callback.append(self.rightTimerFire) self.lefttimer = False self.leftKeyTimer = eTimer() - self.leftKeyTimer.timeout.get().append(self.leftTimerFire) + self.leftKeyTimer.callback.append(self.leftTimerFire) self.currList = "filelist" diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index b305b65..6d41305 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -94,7 +94,7 @@ class ThumbView(Screen): self["label0"].setText(_("no Picture found")) self.ThumbTimer = eTimer() - self.ThumbTimer.timeout.get().append(self.showThumb) + self.ThumbTimer.callback.append(self.showThumb) self.fillPage() @@ -244,11 +244,11 @@ class PicView(Screen): self["pause"] = Pixmap() self.decodeTimer = eTimer() - self.decodeTimer.timeout.get().append(self.decodePic) + self.decodeTimer.callback.append(self.decodePic) self.decodeTimer.start(300, True) self.slideTimer = eTimer() - self.slideTimer.timeout.get().append(self.slidePic) + self.slideTimer.callback.append(self.slidePic) def Pause(self): @@ -457,7 +457,7 @@ class picmain(Screen): self["thumbnail"] = Pixmap() self.ThumbTimer = eTimer() - self.ThumbTimer.timeout.get().append(self.showThumb) + self.ThumbTimer.callback.append(self.showThumb) self.ThumbTimer.start(500, True) def up(self): diff --git a/lib/python/Plugins/Extensions/SimpleRSS/plugin.py b/lib/python/Plugins/Extensions/SimpleRSS/plugin.py index b521835..3c96dd4 100644 --- a/lib/python/Plugins/Extensions/SimpleRSS/plugin.py +++ b/lib/python/Plugins/Extensions/SimpleRSS/plugin.py @@ -139,7 +139,7 @@ class RSSPoller: def __init__(self): self.poll_timer = eTimer() - self.poll_timer.timeout.get().append(self.poll) + self.poll_timer.callback.append(self.poll) self.poll_timer.start(0, 1) self.last_links = Set() self.dialog = None diff --git a/lib/python/Plugins/SystemPlugins/OldSoftwareUpdate/plugin.py b/lib/python/Plugins/SystemPlugins/OldSoftwareUpdate/plugin.py index 17abb0f..c721638 100644 --- a/lib/python/Plugins/SystemPlugins/OldSoftwareUpdate/plugin.py +++ b/lib/python/Plugins/SystemPlugins/OldSoftwareUpdate/plugin.py @@ -30,7 +30,7 @@ class Upgrade(Screen): self.update = True self.delayTimer = eTimer() - self.delayTimer.timeout.get().append(self.doUpdateDelay) + self.delayTimer.callback.append(self.doUpdateDelay) def go(self): if self.update: diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py index e394db4..1f22204 100644 --- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py @@ -123,7 +123,7 @@ class PositionerSetup(Screen): self.updateColors("tune") self.statusTimer = eTimer() - self.statusTimer.timeout.get().append(self.updateStatus) + self.statusTimer.callback.append(self.updateStatus) self.statusTimer.start(50, False) def restartPrevService(self, yesno): diff --git a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py index c0fbe74..8127514 100644 --- a/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py +++ b/lib/python/Plugins/SystemPlugins/SoftwareUpdate/plugin.py @@ -268,7 +268,7 @@ class UpdatePlugin(Screen): self.activity = 0 self.activityTimer = eTimer() - self.activityTimer.timeout.get().append(self.doActivityTimer) + self.activityTimer.callback.append(self.doActivityTimer) self.activityTimer.start(100, False) self.ipkg = IpkgComponent() diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index c6d6b86..9defb9e 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -66,7 +66,7 @@ class VideoHardware: # until we have the hotplug poll socket # self.timer = eTimer() -# self.timer.timeout.get().append(self.readPreferredModes) +# self.timer.callback.append(self.readPreferredModes) # self.timer.start(1000) def readAvailableModes(self): diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index e1402ae..d640ac2 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -1,28 +1,39 @@ +from Tools.Profile import profile + from Screen import Screen from Components.Button import Button from Components.ServiceList import ServiceList from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap from Components.MenuList import MenuList from Components.ServiceEventTracker import ServiceEventTracker +profile("ChannelSelection.py 1") from EpgSelection import EPGSelection from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode from Components.config import config, ConfigSubsection, ConfigText from Tools.NumericalTextInput import NumericalTextInput +profile("ChannelSelection.py 2") from Components.NimManager import nimmanager +profile("ChannelSelection.py 2.1") from Components.Sources.Source import ObsoleteSource +profile("ChannelSelection.py 2.2") from Components.Sources.RdsDecoder import RdsDecoder +profile("ChannelSelection.py 2.3") from Components.Sources.ServiceEvent import ServiceEvent +profile("ChannelSelection.py 2.4") from Components.Input import Input +profile("ChannelSelection.py 3") from Components.ParentalControl import parentalControl from Components.Pixmap import Pixmap from Screens.InputBox import InputBox, PinInput from Screens.MessageBox import MessageBox from Screens.ServiceInfo import ServiceInfo +profile("ChannelSelection.py 4") from Screens.RdsDisplay import RassInteractive from ServiceReference import ServiceReference from Tools.BoundFunction import boundFunction from re import compile from os import remove +profile("ChannelSelection.py after imports") FLAG_SERVICE_NEW_FOUND = 64 #define in lib/dvb/idvb.h as dxNewFound = 64 @@ -276,7 +287,7 @@ class SelectionEventInfo: self["ServiceEvent"] = ServiceEvent() self.servicelist.connectSelChanged(self.__selectionChanged) self.timer = eTimer() - self.timer.timeout.get().append(self.updateEventInfo) + self.timer.callback.append(self.updateEventInfo) self.onShown.append(self.__selectionChanged) def __selectionChanged(self): @@ -1081,7 +1092,7 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect }) self.lastChannelRootTimer = eTimer() - self.lastChannelRootTimer.timeout.get().append(self.__onCreate) + self.lastChannelRootTimer.callback.append(self.__onCreate) self.lastChannelRootTimer.start(100,True) self.history_tv = [ ] diff --git a/lib/python/Screens/Ci.py b/lib/python/Screens/Ci.py index 10423ad..5028301 100644 --- a/lib/python/Screens/Ci.py +++ b/lib/python/Screens/Ci.py @@ -29,7 +29,7 @@ class MMIDialog(Screen): self.slotid = slotid self.timer = eTimer() - self.timer.timeout.get().append(self.keyCancel) + self.timer.callback.append(self.keyCancel) #else the skins fails self["title"] = Label("") diff --git a/lib/python/Screens/EventView.py b/lib/python/Screens/EventView.py index 7746b13..1bb3d0b 100644 --- a/lib/python/Screens/EventView.py +++ b/lib/python/Screens/EventView.py @@ -22,7 +22,7 @@ class EventViewBase: self["key_red"] = Button("") if similarEPGCB is not None: self.SimilarBroadcastTimer = eTimer() - self.SimilarBroadcastTimer.timeout.get().append(self.getSimilarEvents) + self.SimilarBroadcastTimer.callback.append(self.getSimilarEvents) else: self.SimilarBroadcastTimer = None if self.isRecording: diff --git a/lib/python/Screens/HarddiskSetup.py b/lib/python/Screens/HarddiskSetup.py index 1578fae..19a674e 100644 --- a/lib/python/Screens/HarddiskSetup.py +++ b/lib/python/Screens/HarddiskSetup.py @@ -24,10 +24,10 @@ class HarddiskWait(Screen): self.timer = eTimer() if type == HarddiskSetup.HARDDISK_INITIALIZE: text = _("Initializing Harddisk...") - self.timer.timeout.get().append(self.doInit) + self.timer.callback.append(self.doInit) else: text = _("Checking Filesystem...") - self.timer.timeout.get().append(self.doCheck) + self.timer.callback.append(self.doCheck) self["wait"] = Label(text) self.timer.start(100) diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py index 228ca4e..80b4239 100644 --- a/lib/python/Screens/InfoBar.py +++ b/lib/python/Screens/InfoBar.py @@ -2,19 +2,16 @@ from Tools.Profile import profile, profile_final from Screen import Screen -profile("LOAD:MovieSelection") -from Screens.MovieSelection import MovieSelection +profile("LOAD:enigma") +from enigma import iPlayableService + profile("LOAD:ChannelSelectionRadio") from Screens.ChannelSelection import ChannelSelectionRadio +profile("LOAD:MovieSelection") +from Screens.MovieSelection import MovieSelection profile("LOAD:ChoiceBox") from Screens.ChoiceBox import ChoiceBox -profile("LOAD:InitBar_Components") -from Components.Sources.Source import ObsoleteSource -from Components.ActionMap import HelpableActionMap -from Components.config import config -from Components.ServiceEventTracker import ServiceEventTracker - profile("LOAD:InfoBarGenerics") from Screens.InfoBarGenerics import InfoBarShowHide, \ InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRdsDecoder, \ @@ -25,12 +22,15 @@ from Screens.InfoBarGenerics import InfoBarShowHide, \ InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \ InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarSleepTimer, InfoBarServiceErrorPopupSupport +profile("LOAD:InitBar_Components") +from Components.Sources.Source import ObsoleteSource +from Components.ActionMap import HelpableActionMap +from Components.config import config +from Components.ServiceEventTracker import ServiceEventTracker + profile("LOAD:HelpableScreen") from Screens.HelpMenu import HelpableScreen -profile("LOAD:enigma") -from enigma import iPlayableService - class InfoBar(InfoBarShowHide, InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarAudioSelection, diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 28e619f..b62a466 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -71,7 +71,7 @@ class InfoBarShowHide: self.__locked = 0 self.hideTimer = eTimer() - self.hideTimer.timeout.get().append(self.doTimerHide) + self.hideTimer.callback.append(self.doTimerHide) self.hideTimer.start(5000, True) self.onShow.append(self.__onShow) @@ -171,7 +171,7 @@ class NumberZap(Screen): }) self.Timer = eTimer() - self.Timer.timeout.get().append(self.keyOK) + self.Timer.callback.append(self.keyOK) self.Timer.start(3000, True) class InfoBarNumberZap: @@ -1018,7 +1018,7 @@ class InfoBarTimeshift: self.timeshift_enabled = 0 self.timeshift_state = 0 self.ts_rewind_timer = eTimer() - self.ts_rewind_timer.timeout.get().append(self.rewindService) + self.ts_rewind_timer.callback.append(self.rewindService) self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { diff --git a/lib/python/Screens/Ipkg.py b/lib/python/Screens/Ipkg.py index 216cf8c..eac0347 100644 --- a/lib/python/Screens/Ipkg.py +++ b/lib/python/Screens/Ipkg.py @@ -28,7 +28,7 @@ class Ipkg(Screen): self.activity = 0 self.activityTimer = eTimer() - self.activityTimer.timeout.get().append(self.doActivityTimer) + self.activityTimer.callback.append(self.doActivityTimer) #self.activityTimer.start(100, False) self.ipkg = IpkgComponent() diff --git a/lib/python/Screens/MessageBox.py b/lib/python/Screens/MessageBox.py index df27667..51f3987 100644 --- a/lib/python/Screens/MessageBox.py +++ b/lib/python/Screens/MessageBox.py @@ -61,7 +61,7 @@ class MessageBox(Screen): self.timeout = timeout if timeout > 0: self.timer = eTimer() - self.timer.timeout.get().append(self.timerTick) + self.timer.callback.append(self.timerTick) self.onExecBegin.append(self.startTimer) self.origTitle = None if self.execing: diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index e0bd4ab..8fb1eb8 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -129,7 +129,7 @@ class SelectionEventInfo: self["Service"] = ServiceEvent() self.list.connectSelChanged(self.__selectionChanged) self.timer = eTimer() - self.timer.timeout.get().append(self.updateEventInfo) + self.timer.callback.append(self.updateEventInfo) self.onShown.append(self.__selectionChanged) def __selectionChanged(self): @@ -156,7 +156,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo): self.bouquet_mark_edit = False self.delayTimer = eTimer() - self.delayTimer.timeout.get().append(self.updateHDDData) + self.delayTimer.callback.append(self.updateHDDData) self["waitingtext"] = Label(_("Please wait... Loading list...")) diff --git a/lib/python/Screens/ParentalControlSetup.py b/lib/python/Screens/ParentalControlSetup.py index f5f48e2..6ae12ca 100644 --- a/lib/python/Screens/ParentalControlSetup.py +++ b/lib/python/Screens/ParentalControlSetup.py @@ -148,7 +148,7 @@ class ParentalControlEditor(Screen): self.currentLetter = chr(SPECIAL_CHAR) self.readServiceList() self.chooseLetterTimer = eTimer() - self.chooseLetterTimer.timeout.get().append(self.chooseLetter) + self.chooseLetterTimer.callback.append(self.chooseLetter) self.onLayoutFinish.append(self.LayoutFinished) self["actions"] = NumberActionMap(["DirectionActions", "ColorActions", "OkCancelActions", "NumberActions"], diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py index 2a8c3df..3e71912 100644 --- a/lib/python/Screens/ScanSetup.py +++ b/lib/python/Screens/ScanSetup.py @@ -298,7 +298,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport): }, -2) self.statusTimer = eTimer() - self.statusTimer.timeout.get().append(self.updateStatus) + self.statusTimer.callback.append(self.updateStatus) #self.statusTimer.start(5000, True) self.list = [] diff --git a/lib/python/Screens/SubservicesQuickzap.py b/lib/python/Screens/SubservicesQuickzap.py index c098886..448b4b4 100644 --- a/lib/python/Screens/SubservicesQuickzap.py +++ b/lib/python/Screens/SubservicesQuickzap.py @@ -23,7 +23,7 @@ class SubservicesQuickzap(InfoBarShowHide, InfoBarMenu, InfoBarServiceName, Info self.currentlyPlayingSubservice = 0 self.timer = eTimer() - self.timer.timeout.get().append(self.playSubservice) + self.timer.callback.append(self.playSubservice) self.onLayoutFinish.append(self.onLayoutFinished) self["actions"] = NumberActionMap( [ "InfobarSubserviceQuickzapActions", "NumberActions", "DirectionActions", "ColorActions" ], diff --git a/lib/python/Screens/Wizard.py b/lib/python/Screens/Wizard.py index 1b13315..c987ac6 100644 --- a/lib/python/Screens/Wizard.py +++ b/lib/python/Screens/Wizard.py @@ -162,7 +162,7 @@ class Wizard(Screen, HelpableScreen): self.currStep = 1 self.timeoutTimer = eTimer() - self.timeoutTimer.timeout.get().append(self.timeoutCounterFired) + self.timeoutTimer.callback.append(self.timeoutCounterFired) self["text"] = Label() diff --git a/lib/python/Tools/NumericalTextInput.py b/lib/python/Tools/NumericalTextInput.py index 2cbc0f4..696b8e2 100644 --- a/lib/python/Tools/NumericalTextInput.py +++ b/lib/python/Tools/NumericalTextInput.py @@ -56,7 +56,7 @@ class NumericalTextInput: if handleTimeout: self.timer = eTimer() - self.timer.timeout.get().append(self.timeout) + self.timer.callback.append(self.timeout) else: self.timer = None self.lastKey = -1 diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 06d7435..e3b4cd2 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -135,7 +135,6 @@ typedef long time_t; %include %include -%immutable eTimer::timeout; %immutable eSocketNotifier::activated; %include %include diff --git a/lib/python/python.cpp b/lib/python/python.cpp index 84716e7..ad029fb 100644 --- a/lib/python/python.cpp +++ b/lib/python/python.cpp @@ -3,6 +3,7 @@ #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L extern "C" void init_enigma(); +extern "C" void eBaseInit(void); extern void bsodFatal(); #define SKIP_PART2 @@ -124,6 +125,7 @@ ePython::ePython() PyEval_InitThreads(); init_enigma(); + eBaseInit(); } ePython::~ePython() diff --git a/lib/python/python.h b/lib/python/python.h index 76f6aa8..9edc50a 100644 --- a/lib/python/python.h +++ b/lib/python/python.h @@ -314,10 +314,16 @@ inline ePyObject Impl_PyTuple_GET_ITEM(ePyObject list, unsigned int pos) } #endif +inline void Impl_INCREF(PyObject *ob) +{ + Py_INCREF(ob); +} + inline void Impl_DECREF(PyObject *ob) { Py_DECREF(ob); } +#define Org_Py_INCREF(obj) Impl_INCREF(obj) #define Org_Py_DECREF(obj) Impl_DECREF(obj) #undef Py_DECREF #undef Py_XDECREF diff --git a/mytest.py b/mytest.py index fd72529..7e7c662 100644 --- a/mytest.py +++ b/mytest.py @@ -1,3 +1,8 @@ +import eBaseImpl +import enigma +enigma.eTimer = eBaseImpl.eTimer +enigma.eSocketNotifier = eBaseImpl.eSocketNotifier + from Tools.Profile import profile, profile_final profile("PYTHON_START") @@ -141,7 +146,7 @@ class Session: self.summary_desktop = summary_desktop self.nav = navigation self.delay_timer = eTimer() - self.delay_timer.timeout.get().append(self.processDelay) + self.delay_timer.callback.append(self.processDelay) self.current_dialog = None @@ -350,7 +355,7 @@ class VolumeControl: self.muteDialog = session.instantiateDialog(Mute) self.hideVolTimer = eTimer() - self.hideVolTimer.timeout.get().append(self.volHide) + self.hideVolTimer.callback.append(self.volHide) vol = config.audio.volume.value self.volumeDialog.setValue(vol) diff --git a/tests/enigma.py b/tests/enigma.py index bf23262..2bf2a59 100644 --- a/tests/enigma.py +++ b/tests/enigma.py @@ -75,7 +75,7 @@ def stop(): def run(duration = 1000): stoptimer = eTimer() stoptimer.start(duration * 1000.0) - stoptimer.timeout.get().append(stop) + stoptimer.callback.append(stop) while not stopped: runIteration() diff --git a/timer.py b/timer.py index 6f3a05f..0569635 100644 --- a/timer.py +++ b/timer.py @@ -139,7 +139,7 @@ class Timer: self.processed_timers = [ ] self.timer = eTimer() - self.timer.timeout.get().append(self.calcNextActivation) + self.timer.callback.append(self.calcNextActivation) self.lastActivation = time() self.calcNextActivation()