1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#
# Copyright (c) 2004, 2005 Art Haas
#
# This file is part of PythonCAD.
#
# PythonCAD is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PythonCAD 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PythonCAD; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# A base class for objects that send messages
#
import types
import traceback
class Messenger(object):
__messages = {
'connected' : True,
'disconnected' : True
}
def __init__(self):
self.__connections = None
self.__mdict = None
self.__ignore = None
self.__muted = False
def finish(self):
if self.__connections is not None:
print "remaining connections for obj: " + `self`
for _message in self.__connections:
print "message: %s" % _message
for _method in self.__connections[_message]:
_obj = _method.im_self
print "connected to obj: " + `_obj`
def connect(self, message, method):
if not self.sendsMessage(message):
raise ValueError, "Unknown message : %s" % str(message)
if not isinstance(method, types.MethodType):
raise TypeError, "Invalid class method type: " + `type(method)`
if method.im_self is None:
raise ValueError, "Unbound method use invalid: %s" % str(method)
if self.__connections is None:
self.__connections = {}
_methods = self.__connections.setdefault(message, [])
_seen = False
for _m in _methods:
if _m is method:
_seen = True
break
if not _seen:
_methods.append(method)
self.sendMessage('connected', method)
def disconnect(self, obj, message=None):
if self.__connections is not None:
if message is None:
_messages = self.__connections.keys()
for _message in _messages:
_methods = self.__connections[_message]
for _method in _methods[:]:
_obj = _method.im_self
if _obj is obj:
_methods.remove(_method)
self.sendMessage('disconnected', obj)
if len(_methods) == 0:
del self.__connections[_message]
else:
if message in self.__connections:
_methods = self.__connections[message]
for _method in _methods[:]:
_obj = _method.im_self
if _obj is obj:
_methods.remove(_method)
self.sendMessage('disconnected', obj)
break
if len(_methods) == 0:
del self.__connections[message]
if len(self.__connections) == 0:
self.__connections = None
def sendsMessage(self, m):
return m in Messenger.__messages
def sendMessage(self, message, *args):
if not isinstance(message, str):
raise TypeError, "Invalid message type: " + `type(message)`
if not self.__muted and self.__connections is not None:
if self.__mdict is None or message not in self.__mdict:
if message in self.__connections:
_methods = self.__connections[message][:] # make a copy
for _method in _methods:
_obj = _method.im_self
if (isinstance(_obj, Messenger) and
_obj.ignores(message)):
continue
#
# "handle" the exception - notice the quotes ...
#
try:
_method(self, *args)
except:
traceback.print_exc()
def muteMessage(self, message):
if not isinstance(message, str):
raise TypeError, "Invalid message type: " + `type(message)`
if self.__mdict is None:
self.__mdict = {}
if message in self.__mdict:
raise ValueError, "Message '%s' already blocked." % message
self.__mdict[message] = True
def unmuteMessage(self, message):
if not isinstance(message, str):
raise TypeError, "Invalid message type: " + `type(message)`
if self.__mdict is not None:
if message in self.__mdict:
del self.__mdict[message]
if len(self.__mdict) == 0:
self.__mdict = None
def mute(self):
self.__muted = True
def unmute(self):
self.__muted = False
def isMuted(self):
return self.__muted is True
def ignore(self, message):
if not isinstance(message, str):
raise TypeError, "Invalid message type: " + `type(message)`
if self.__ignore is None:
self.__ignore = {}
if message in self.__ignore:
raise RuntimeError, "Message '%s' already ignored." % message
self.__ignore[message] = True
def receive(self, message):
if not isinstance(message, str):
raise TypeError, "Invalid message type: " + `type(message)`
if self.__ignore is not None:
if message in self.__ignore:
del self.__ignore[message]
if len(self.__ignore) == 0:
self.__ignore = None
def ignores(self, message):
return self.__ignore is not None and message in self.__ignore
def receives(self, message):
return self.__ignore is None or message not in self.__ignore
|