root/trunk/RBJabber/RBJabber/SubjectObserver/AttributedSubject.py

Revision 253, 5.0 kB (checked in by sholloway, 6 years ago)

Changed to BSD License

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 """Subject-based Foundation.AttributedDict
23
24 Similar to Foundation.AttributedDict, except that every modification causes an
25 UpdateObservers call.
26
27 TODO: Look at doing this with metaclasses ala Aspect Oriented Programming?
28 """
29
30 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 #~ Imports
32 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
34 from Subject import Subject
35
36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 #~ Definitions
38 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39
40 class AttributedSubjectMixin(object):
41     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42     #~ Special
43     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
45     def __init__(self, *args, **kw):
46         super(AttributedSubjectMixin, self).__init__(*args, **kw)
47         self._attributes = {}
48
49     def __getattribute__(self, name):
50         if '_' != name[0]:
51             result = self._attributes.get(name, self)
52             if result is not self:
53                 return result
54         return super(AttributedSubjectMixin, self).__getattribute__(name)
55
56     def __setattr__(self, name, value):
57         if '_' != name[0]:
58             self._attributes[name] = value
59             self.UpdateObserversEx({name: value})
60         else:
61             return super(AttributedSubjectMixin, self).__setattr__(name, value)
62
63     def __delattr__(self, name):
64         if '_' != name[0]:
65             if name in self._attributes:
66                 del self._attributes[name]
67                 self.UpdateObserversEx({name: None})
68         else:
69             return super(AttributedSubjectMixin, self).__delattr__(name)
70
71     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72     #~ Dictonary Compatability
73     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74
75     def __contains__(self, obj):
76         return self._attributes.__contains__(obj)
77
78     def __iter__(self):
79         return self._attributes.__iter__()
80
81     def __str__(self):
82         return self._attributes.__str__()
83
84     def __repr__(self):
85         return self._attributes.__repr__()
86
87     def __getitem__(self, *args, **kw):
88         return self._attributes.__getitem__(*args, **kw)
89
90     def __setitem__(self, name, value):
91         result = self._attributes.__setitem__(name, value)
92         self.UpdateObserversEx({name: value})
93         return result
94
95     def __delitem__(self, name):
96         result = self._attributes.__delitem__(name)
97         self.UpdateObserversEx({name: None})
98         return result
99
100     def __hash__(self):
101         return  self._attributes.__hash__()
102
103     def clear(self):
104         UpdateDict = dict(map(None, self._attributes.keys(), tuple()))
105         result = self._attributes.clear()
106         self.UpdateObserversEx(UpdateDict)
107         return result
108
109     def copy(self):
110         return self._attributes.copy()
111
112     def get(self, *args, **kw):
113         return self._attributes.get(*args, **kw)
114
115     def has_key(self, *args, **kw):
116         return self._attributes.has_key(*args, **kw)
117
118     def popitem(self, *args, **kw):
119         result = self._attributes.popitem(*args, **kw)
120         self.UpdateObserversEx({name:None})
121         return result
122
123     def setdefault(self, name, default):
124         if name not in self._attributes:
125             result = self._attributes.setdefault(name, default)
126             self.UpdateObserversEx({name:default})
127         else:
128             result = self._attributes.get(name)
129         return result
130
131     def update(self, other):
132         result = self._attributes.update(other)
133         self.UpdateObserversEx(other)
134         return result
135
136     def keys(self):
137         return self._attributes.keys()
138
139     def values(self):
140         return self._attributes.values()
141
142     def items(self):
143         return self._attributes.items()
144
145     def iterkeys(self):
146         return self._attributes.iterkeys()
147
148     def itervalues(self):
149         return self._attributes.itervalues()
150
151     def iteritems(self):
152         return self._attributes.iteritems()
153
154
155 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156
157 class AttributedSubject(AttributedSubjectMixin, Subject):
158     """Couples AttributedSubjectMixin with a Subject propigation scheme."""
159     def AddObserver(self, observer, call=0, **kw):
160         Subject.AddObserver(self, observer, **kw)
161         if call: observer(self, **self._attributes)
162
Note: See TracBrowser for help on using the browser.