Author: rshortt
Date: Mon Jan 7 15:23:44 2008
New Revision: 2945
Log:
A new Twisted based notifier. This one integrates into the twisted reactor
loop and acts as a layer between kaa
s timers and sockets. It uses the default reactor (selectreactor) and behaves
very much like the generic notifier. There's a bit more work to be done
(marked by FIXME comments) and it still needs more testing.
Added:
trunk/base/src/notifier/pynotifier/nf_twisted.py
Modified:
trunk/base/src/notifier/nf_wrapper.py
trunk/base/src/notifier/pynotifier/__init__.py
Modified: trunk/base/src/notifier/nf_wrapper.py
==============================================================================
--- trunk/base/src/notifier/nf_wrapper.py (original)
+++ trunk/base/src/notifier/nf_wrapper.py Mon Jan 7 15:23:44 2008
@@ -175,7 +175,7 @@
# ourself into the gtk notifier
module = 'gtk'
- if not module in ( 'generic', 'gtk'):
+ if not module in ('generic', 'gtk', 'twisted_experimental'):
raise AttributeError('unsupported notifier %s' % module)
# use the selected module
Modified: trunk/base/src/notifier/pynotifier/__init__.py
==============================================================================
--- trunk/base/src/notifier/pynotifier/__init__.py (original)
+++ trunk/base/src/notifier/pynotifier/__init__.py Mon Jan 7 15:23:44 2008
@@ -43,7 +43,7 @@
step = None
# notifier types
-( GENERIC, QT, GTK, WX ) = range( 4 )
+( GENERIC, QT, GTK, WX, TWISTED_EXPERIMENTAL ) = range( 5 )
# socket conditions
IO_READ = None
@@ -69,6 +69,9 @@
elif model == WX:
import nf_wx as nf_impl
log.warn( 'the WX notifier is deprecated and is no longer
maintained' )
+ elif model == TWISTED_EXPERIMENTAL:
+ import nf_twisted as nf_impl
+ log.info("using nf_twisted")
else:
raise Exception( 'unknown notifier model' )
Added: trunk/base/src/notifier/pynotifier/nf_twisted.py
==============================================================================
--- (empty file)
+++ trunk/base/src/notifier/pynotifier/nf_twisted.py Mon Jan 7 15:23:44 2008
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Author: Rob Shortt <[EMAIL PROTECTED]>
+#
+# A notifier implementation using Twisted.
+#
+# Copyright (C) 2008
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version
+# 2.1 as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""
+This is a notifier implementation using Twisted - http://www.twistedmatrix.com/
+Twisted is an async framework that has much in common with pynotifier and kaa.
+
+Here are some links of interest to aid development and debuging:
+
+The reactor base class, posixbase, and selectreactor:
+http://twistedmatrix.com/trac/browser/trunk/twisted/internet/base.py
+http://twistedmatrix.com/trac/browser/trunk/twisted/internet/posixbase.py
+http://twistedmatrix.com/trac/browser/trunk/twisted/internet/selectreactor.py
+
+Timers and scheduling:
+http://twistedmatrix.com/projects/core/documentation/howto/time.html
+
+Twisted doc index:
+http://twistedmatrix.com/projects/core/documentation/howto/index.html
+"""
+
+# Twisted uses zope.interface
+from zope.interface import implements
+
+# Twisted imports
+from twisted.internet.interfaces import IReadDescriptor, IWriteDescriptor
+from twisted.internet import reactor
+from twisted.internet import task
+
+# internal packages
+import dispatch
+
+IO_READ = 1
+IO_WRITE = 2
+IO_EXCEPT = 4
+
+__sockobjs = {}
+__sockobjs[IO_READ] = {}
+__sockobjs[IO_WRITE] = {}
+__timers = {}
+__timer_id = 0
+__dispatch_timer = None
+
+
+class SocketReadCB:
+ """
+ An object to implement Twisted's IReadDescriptor. When there is data
+ available on the socket doRead() will get called.
+ """
+ implements(IReadDescriptor)
+
+ def __init__(self, socket, method):
+ self.socket = socket
+ self.method = method
+
+ def doRead(self):
+ """
+ Call the callback method with the socket as the only argument. If it
+ returns False remove this socket from our notifier.
+ """
+ if self.method(self.socket) == False:
+ socket_remove(self.socket, IO_READ)
+
+ def fileno(self):
+ # FIXME: check is socket is a socket or int
+ return self.socket
+
+ def logPrefix(self):
+ # FIXME: debug and improve if needed
+ return "doRead: "
+
+ def connectionLost(self, reason):
+ # FIXME: debug and improve if needed
+ print "connectionLost"
+
+
+class SocketWriteCB:
+ """
+ An object to implement Twisted's IWriteDescriptor. When there is data
+ available on the socket doWrite() will get called.
+ """
+ implements(IWriteDescriptor)
+
+ def __init__(self, socket, method):
+ self.socket = socket
+ self.method = method
+
+ def doWrite(self):
+ """
+ Call the callback method with the socket as the only argument. If it
+ returns False remove this socket from our notifier.
+ """
+ if self.method(self.socket) == False:
+ socket_remove(self.socket, IO_WRITE)
+
+ def fileno(self):
+ # FIXME: check is socket is a socket or int
+ return self.socket
+
+ def logPrefix(self):
+ # FIXME: debug and improve if needed
+ return "doWrite: "
+
+ def connectionLost(self, reason):
+ # FIXME: debug and improve if needed
+ print "connectionLost"
+
+
+def socket_add(id, method, condition = IO_READ):
+ """
+ The first argument specifies a socket, the second argument has to be a
+ function that is called whenever there is data ready in the socket.
+
+ Objects that implement Twisted's IRead/WriteDescriptor interfaces get
+ passed to the reactor to monitor.
+ """
+ global __sockobjs
+
+ if condition == IO_READ:
+ s = SocketReadCB(id, method)
+ reactor.addReader(s)
+
+ elif condition == IO_WRITE:
+ s = SocketWriteCB(id, method)
+ reactor.addWriter(s)
+
+ else:
+ return
+
+ __sockobjs[condition][id] = s
+
+
+def socket_remove(id, condition=IO_READ):
+ """
+ Removes the IRead/WriteDescriptor object with this socket from
+ the Twisted reactor.
+ """
+ global __sockobjs
+ sockobj = __sockobjs[condition].get(id)
+
+ if sockobj:
+ if condition == IO_READ:
+ reactor.removeReader(sockobj)
+ elif condition == IO_WRITE:
+ reactor.removeWriter(sockobj)
+ del __sockobjs[condition][id]
+
+
+def timer_add(interval, method):
+ """
+ The first argument specifies an interval in milliseconds, the second
+ argument a function. This is function is called after interval
+ seconds. If it returns true it's called again after interval
+ seconds, otherwise it is removed from the scheduler. The third
+ (optional) argument is a parameter given to the called
+ function. This function returns an unique identifer which can be
+ used to remove this timer
+ """
+ global __timer_id
+
+ try:
+ __timer_id += 1
+ except OverflowError:
+ __timer_id = 0
+
+ t = task.LoopingCall(method)
+ t.start(interval/1000.0, now=False)
+ __timers[__timer_id] = t
+
+ return __timer_id
+
+
+def timer_remove(id):
+ """
+ Removes the timer identifed by the unique ID from the main loop.
+ """
+ t = __timers.get(id)
+ if t != None:
+ t.stop()
+ del __timers[id]
+
+
+def dispatcher_add(method):
+ dispatch.dispatcher_add(method)
+
+dispatcher_remove = dispatch.dispatcher_remove
+
+
+def step(sleep = True, external = True, simulate = False):
+ global __timers
+
+ reactor.runUntilCurrent()
+ t2 = reactor.timeout()
+ t = reactor.running and t2
+ reactor.doIteration(t)
+
+
+def loop():
+ reactor.run()
+
+
+def _init():
+ global __dispatch_timer
+ __dispatch_timer = task.LoopingCall(dispatch.dispatcher_run)
+ __dispatch_timer.start(dispatch.MIN_TIMER/1000.0)
+
+ reactor.startRunning(installSignalHandlers=True)
+
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog