File: message.py

package info (click to toggle)
pythoncad 0.1.35-4
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 3,536 kB
  • ctags: 4,286
  • sloc: python: 62,752; sh: 743; makefile: 39
file content (166 lines) | stat: -rw-r--r-- 6,300 bytes parent folder | download | duplicates (4)
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