/[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 62 - (hide annotations)
Fri Sep 14 12:19:39 2001 UTC (23 years, 5 months ago) by bh
Original Path: trunk/thuban/Thuban/Lib/connector.py
File MIME type: text/x-python
File size: 6073 byte(s)
	* Thuban/Lib/connector.py (Connector.print_connections): Print the
	puiblisher's ids in hex to make it easier to compare them to the
	standard repr of python methods

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     # Copyright (C) 1997, 1998, 2000, 2001 by Bernhard Herzog
7     #
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     class ConnectorError(Exception):
32     pass
33    
34     class Connector:
35    
36     def __init__(self):
37     self.connections = {}
38    
39     def Connect(self, object, channel, function, args):
40     idx = id(object)
41     if self.connections.has_key(idx):
42     channels = self.connections[idx]
43     else:
44     channels = self.connections[idx] = {}
45    
46     if channels.has_key(channel):
47     receivers = channels[channel]
48     else:
49     receivers = channels[channel] = []
50    
51     info = (function, args)
52     try:
53     receivers.remove(info)
54     except ValueError:
55     pass
56     receivers.append(info)
57    
58     def Disconnect(self, object, channel, function, args):
59     try:
60     receivers = self.connections[id(object)][channel]
61     except KeyError:
62     raise ConnectorError, \
63     'no receivers for channel %s of %s' % (channel, object)
64     try:
65     receivers.remove((function, args))
66     except ValueError:
67     raise ConnectorError,\
68     'receiver %s%s is not connected to channel %s of %s' \
69     % (function, args, channel, object)
70    
71     if not receivers:
72     # the list of receivers is empty now, remove the channel
73     channels = self.connections[id(object)]
74     del channels[channel]
75     if not channels:
76     # the object has no more channels
77     del self.connections[id(object)]
78    
79     def Issue(self, object, channel, *args):
80     #print object, channel, args
81     try:
82     receivers = self.connections[id(object)][channel]
83     except KeyError:
84     return
85     for func, fargs in receivers:
86     try:
87     apply(func, args + fargs)
88     except:
89     sys.stderr.write("Warning: %s.%s: %s%s\n"
90     % (object, channel, func, fargs))
91     import traceback
92     traceback.print_exc()
93    
94     def RemovePublisher(self, object):
95     i = id(object)
96     if self.connections.has_key(i):
97     del self.connections[i]
98     # don't use try: del ... ; except KeyError here. That would create a
99     # new reference of object in a traceback object and this method should
100     # be callable from a __del__ method (at least for versions prior
101     # Python 1.5)
102    
103     def HasSubscribers(self, object):
104     return self.connections.has_key(id(object))
105    
106     def print_connections(self):
107     # for debugging
108     for id, channels in self.connections.items():
109     for name, subscribers in channels.items():
110 bh 62 print hex(id), name
111 bh 6 for func, args in subscribers:
112     if type(func) == MethodType:
113     print '\tmethod %s of %s' % (func.im_func.func_name,
114     func.im_self)
115     else:
116     print '\t', func
117    
118    
119    
120     _the_connector = Connector()
121    
122     Connect = _the_connector.Connect
123     Issue = _the_connector.Issue
124     RemovePublisher = _the_connector.RemovePublisher
125     Disconnect = _the_connector.Disconnect
126     def Subscribe(channel, function, *args):
127     return Connect(None, channel, function, args)
128    
129    
130     class Publisher:
131    
132     def __del__(self):
133     # the new finalization code in 1.5.1 might bind RemovePublisher
134     # to None before all objects derived from Publisher are deleted...
135     if RemovePublisher is not None:
136     RemovePublisher(self)
137    
138     def Subscribe(self, channel, func, *args):
139     Connect(self, channel, func, args)
140    
141     def Unsubscribe(self, channel, func, *args):
142     Disconnect(self, channel, func, args)
143    
144     def issue(self, channel, *args):
145     apply(Issue, (self, channel,) + args)
146    
147     def Destroy(self):
148     RemovePublisher(self)
149    
150    
151     class QueueingPublisher(Publisher):
152    
153     def __init__(self):
154     self.clear_message_queue()
155    
156     def queue_message(self, channel, *args):
157     # Put message in the queue. If it is already queued put it at
158     # the end. This is done to make certain that no channel gets
159     # called twice between two calls to flush_message_queue. If the
160     # order of channel invocation is important two or more queues
161     # should be used.
162     message = (channel, args)
163     if message not in self.message_queue:
164     self.message_queue.append(message)
165    
166     def flush_message_queue(self):
167     # Issue all queued messages and make the queue empty
168     #
169     # Issueing messages might result in new messages being queued.
170     # This does not happen in sketch yet (Jul 1997) but let's hope
171     # that we don't get infinite loops here...
172     while self.message_queue:
173     queue = self.message_queue
174     self.message_queue = []
175     for channel, args in queue:
176     apply(Issue, (self, channel) + args)
177    
178     def clear_message_queue(self):
179     self.message_queue = []
180    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26