/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Lib/connector.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Thuban/Lib/connector.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1778 - (hide annotations)
Mon Oct 6 17:30:32 2003 UTC (21 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/Lib/connector.py
File MIME type: text/x-python
File size: 5590 byte(s)
(Conduit): New class to help classes
that forward messages

1 bh 6 # This module was copied almost verbatim from Sketch. The only change is
2     # the base class of ConnectorError which was a Sketch specific exception
3     # class.
4    
5     # Sketch - A Python-based interactive drawing program
6 bh 1144 # Copyright (C) 1997, 1998, 2000, 2001, 2003 by Bernhard Herzog
7 bh 6 #
8     # This library is free software; you can redistribute it and/or
9     # modify it under the terms of the GNU Library General Public
10     # License as published by the Free Software Foundation; either
11     # version 2 of the License, or (at your option) any later version.
12     #
13     # This library is distributed in the hope that it will be useful,
14     # but WITHOUT ANY WARRANTY; without even the implied warranty of
15     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16     # Library General Public License for more details.
17     #
18     # You should have received a copy of the GNU Library General Public
19     # License along with this library; if not, write to the Free Software
20     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21    
22     __version__ = "$Revision$"
23    
24     #
25     # The Connector
26     #
27    
28     import sys
29     from types import MethodType
30    
31 jan 374 from Thuban import _
32    
33 bh 6 class ConnectorError(Exception):
34     pass
35    
36     class Connector:
37    
38     def __init__(self):
39     self.connections = {}
40    
41     def Connect(self, object, channel, function, args):
42     idx = id(object)
43     if self.connections.has_key(idx):
44     channels = self.connections[idx]
45     else:
46     channels = self.connections[idx] = {}
47    
48     if channels.has_key(channel):
49     receivers = channels[channel]
50     else:
51     receivers = channels[channel] = []
52    
53     info = (function, args)
54     try:
55     receivers.remove(info)
56     except ValueError:
57     pass
58     receivers.append(info)
59    
60     def Disconnect(self, object, channel, function, args):
61     try:
62     receivers = self.connections[id(object)][channel]
63     except KeyError:
64     raise ConnectorError, \
65 jan 374 _('no receivers for channel %s of %s') % (channel, object)
66 bh 6 try:
67     receivers.remove((function, args))
68     except ValueError:
69     raise ConnectorError,\
70 jan 374 _('receiver %s%s is not connected to channel %s of %s') \
71 bh 6 % (function, args, channel, object)
72    
73     if not receivers:
74     # the list of receivers is empty now, remove the channel
75     channels = self.connections[id(object)]
76     del channels[channel]
77     if not channels:
78     # the object has no more channels
79     del self.connections[id(object)]
80    
81     def Issue(self, object, channel, *args):
82     #print object, channel, args
83     try:
84     receivers = self.connections[id(object)][channel]
85     except KeyError:
86     return
87 bh 1144 # Iterate over a copy of receivers because the receivers might
88     # unsubscribe themselves when receiving a message and Disconnect
89     # would modify receivers in place while we're iterating over it.
90     for func, fargs in receivers[:]:
91 bh 6 try:
92     apply(func, args + fargs)
93     except:
94 jan 374 sys.stderr.write(_("Warning: %s.%s: %s%s\n")
95 bh 6 % (object, channel, func, fargs))
96     import traceback
97     traceback.print_exc()
98    
99     def RemovePublisher(self, object):
100     i = id(object)
101     if self.connections.has_key(i):
102     del self.connections[i]
103     # don't use try: del ... ; except KeyError here. That would create a
104     # new reference of object in a traceback object and this method should
105     # be callable from a __del__ method (at least for versions prior
106     # Python 1.5)
107    
108     def HasSubscribers(self, object):
109     return self.connections.has_key(id(object))
110    
111     def print_connections(self):
112     # for debugging
113     for id, channels in self.connections.items():
114     for name, subscribers in channels.items():
115 bh 62 print hex(id), name
116 bh 6 for func, args in subscribers:
117     if type(func) == MethodType:
118 jan 374 print _('\tmethod %s of %s') % (func.im_func.func_name,
119     func.im_self)
120 bh 6 else:
121     print '\t', func
122    
123    
124    
125     _the_connector = Connector()
126    
127     Connect = _the_connector.Connect
128     Issue = _the_connector.Issue
129     RemovePublisher = _the_connector.RemovePublisher
130     Disconnect = _the_connector.Disconnect
131     def Subscribe(channel, function, *args):
132     return Connect(None, channel, function, args)
133    
134    
135     class Publisher:
136    
137     def __del__(self):
138     # the new finalization code in 1.5.1 might bind RemovePublisher
139     # to None before all objects derived from Publisher are deleted...
140     if RemovePublisher is not None:
141     RemovePublisher(self)
142    
143     def Subscribe(self, channel, func, *args):
144     Connect(self, channel, func, args)
145    
146     def Unsubscribe(self, channel, func, *args):
147     Disconnect(self, channel, func, args)
148    
149     def issue(self, channel, *args):
150     apply(Issue, (self, channel,) + args)
151    
152     def Destroy(self):
153     RemovePublisher(self)
154 bh 1778
155    
156     class Conduit(Publisher):
157    
158     def _do_forward(self, *args, **kw):
159     self.issue(args[-1], *args[:-1], **kw)
160    
161     def subscribe_forwarding(self, channel, obj):
162     if obj is not None:
163     obj.Subscribe(channel, self._do_forward, channel)
164    
165     def unsubscribe_forwarding(self, channel, obj):
166     if obj is not None:
167     obj.Unsubscribe(channel, self._do_forward, channel)
168    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26