Browse Source

libpython/pydispach: simple API (Signal) and small fix for unloading

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@55323 15284696-431f-4ddb-bdfa-cd5b030d7da7
Vaclav Petras 12 năm trước cách đây
mục cha
commit
28674ac746

+ 1 - 1
lib/python/pydispatch/Makefile

@@ -8,7 +8,7 @@ PYDIR = $(ETC)/python
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/pydispatch
 
-MODULES = dispatcher errors robustapply robust saferef signals
+MODULES = dispatcher errors robustapply robust saferef signal
 
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)

+ 4 - 4
lib/python/pydispatch/dispatcher.py

@@ -27,11 +27,11 @@ Internal attributes:
 """
 from __future__ import generators
 import weakref
-from pydispatch import saferef, robustapply, errors
+from grass.pydispatch import saferef, robustapply, errors
 
 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
-__cvsid__ = "$Id: dispatcher.py,v 1.1 2010/03/30 15:45:55 mcfletch Exp $"
-__version__ = "$Revision: 1.1 $"[11:-2]
+__cvsid__ = "Id: dispatcher.py,v 1.1 2010/03/30 15:45:55 mcfletch Exp"
+__version__ = "Revision: 1.1"
 
 class _Parameter:
 	"""Used to represent default parameter values."""
@@ -367,7 +367,7 @@ def sendExact( signal=Any, sender=Anonymous, *arguments, **named ):
 
 def _removeReceiver(receiver):
 	"""Remove receiver from connections."""
-	if not sendersBack:
+	if not sendersBack or not connections:
 		# During module cleanup the mapping will be replaced with None
 		return False
 	backKey = id(receiver)

+ 5 - 1
lib/python/pydispatch/pydispatchlib.dox

@@ -4,10 +4,14 @@ by GRASS Development Team (http://grass.osgeo.org)
 
 \section pydispachIntro Introduction
 
-TODO
+Files dispatcher.py, errors.py, robustapply.py, robust.py and saferef.py are
+part of the original PyDispacher.
+File signal.py is the object-based easy to use interface created for GRASS.
 
 \section pydispachAuthors Authors
 
 Patrick K. O'Brien, Mike C. Fletcher and Contributors (original authors, see pydispatch/license.txt and pydispatch/PKG-INFO for details)
+Vaclav Petras (signal.py)
+Anna Kratochilova (signal.py)
 
 */

+ 2 - 2
lib/python/pydispatch/robust.py

@@ -1,6 +1,6 @@
 """Module implementing error-catching version of send (sendRobust)"""
-from pydispatch.dispatcher import Any, Anonymous, liveReceivers, getAllReceivers
-from pydispatch.robustapply import robustApply
+from grass.pydispatch.dispatcher import Any, Anonymous, liveReceivers, getAllReceivers
+from grass.pydispatch.robustapply import robustApply
 
 def sendRobust(
 	signal=Any, 

+ 74 - 0
lib/python/pydispatch/signal.py

@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Mar 11 18:39:13 2013
+
+@author Vaclav Petras <wenzeslaus gmail.com>
+"""
+
+
+from grass.pydispatch import dispatcher
+
+
+def _islambda(function):
+    """Tests if object is a lambda function.
+
+    Should work on the most of Python implementations where name of lambda
+    function is not unique.
+    """
+    return isinstance(function, type(lambda: None)) and function.__name__== (lambda: None).__name__
+
+
+class Signal(object):
+    def __init__(self, name):
+        self._name = name
+
+    def connect(self, handler, weak=None):
+        if weak is None:
+            if _islambda(handler):
+                weak = False
+            else:
+                weak = True
+        dispatcher.connect(receiver=handler, signal=self, weak=weak)
+
+    def disconnect(self, handler):
+        dispatcher.disconnect(receiver=handler, signal=self, weak=None)
+
+    def emit(self, *args, **kwargs):
+        dispatcher.send(signal=self, *args, **kwargs)
+
+    def __call__(self, *arguments, **named):
+        if 'signal' in named:
+            del named['signal']
+        self.emit(*arguments, **named)
+
+
+if __name__ == '__main__':
+    def handler1():
+        print "handler1"
+    def handler2(text):
+        print "handler2: %s" % text
+    class A(object):
+        def showText(self, text):
+            print "showing text:", text
+        def showMessage(self):
+            print "showing message"
+
+    def test():
+        import sys
+        signal1 = Signal('signal1')
+        signal2 = Signal('signal2')
+        signal3 = Signal('signal3')
+        signal1.connect(handler1)
+        signal2.connect(handler2)
+        signal2.connect(lambda text: sys.stdout.write('lambda handler 1: %s\n' % text))
+        signal2.connect(signal3)
+        signal3.connect(handler2)
+
+        a = A()
+        signal2.connect(a.showText)
+        signal2.connect(a.showMessage)
+
+        signal1.emit()
+        signal2.emit(text="Hello")
+
+    test()