/[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 1952 - (hide annotations)
Tue Nov 18 13:18:32 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/Thuban/Lib/connector.py
File MIME type: text/x-python
File size: 6109 byte(s)
(Publisher): Introdcue a new flag,
_was_destroyed, to indicate whether an publisher instance has
already been destroyed.
(Publisher.Unsubscribe): Only disconnect if the publisher has not
been destroyed yet.
(Publisher.Destroy): Set the _was_destroyed flag to true.

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 bh 1952 # Flag indicating whether the publisher instance was destroyed.
138     _was_destroyed = False
139    
140 bh 6 def __del__(self):
141     # the new finalization code in 1.5.1 might bind RemovePublisher
142     # to None before all objects derived from Publisher are deleted...
143     if RemovePublisher is not None:
144     RemovePublisher(self)
145    
146     def Subscribe(self, channel, func, *args):
147     Connect(self, channel, func, args)
148    
149     def Unsubscribe(self, channel, func, *args):
150 bh 1952 """Unsubscribe from the channel.
151 bh 6
152 bh 1952 If the publisher's Destroy method has been called already, do
153     nothing, because the subscriptions will already have been
154     removed in Destroy and trying to disconnect it here will lead to
155     exceptions.
156     """
157     if not self._was_destroyed:
158     Disconnect(self, channel, func, args)
159    
160 bh 6 def issue(self, channel, *args):
161     apply(Issue, (self, channel,) + args)
162    
163     def Destroy(self):
164 bh 1952 """Remove all subscriptions of messages sent by self."""
165 bh 6 RemovePublisher(self)
166 bh 1952 self._was_destroyed = True
167 bh 1778
168    
169     class Conduit(Publisher):
170    
171     def _do_forward(self, *args, **kw):
172     self.issue(args[-1], *args[:-1], **kw)
173    
174     def subscribe_forwarding(self, channel, obj):
175     if obj is not None:
176     obj.Subscribe(channel, self._do_forward, channel)
177    
178     def unsubscribe_forwarding(self, channel, obj):
179     if obj is not None:
180     obj.Unsubscribe(channel, self._do_forward, channel)
181    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26