root/gaphor/tags/gaphor-0.3.0/uml2/element.py

Revision 196, 3.6 kB (checked in by arjanmol, 6 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/env python
2 # vim:sw=4:et
3 """Element:
4
5 Method names have changed on some places to emphasize that we deal
6 with a completely new data model here.
7
8 save()/load()/postload()
9     Load/save the element.
10
11 unlink()
12     Remove all references to the element. First of all the signal
13     '__unlink__' is send to all attached signals.
14
15 attach ('name', callback, *data) or
16 attach (('name', 'other_property'), callback, *data)
17     Connect 'callback' to recieve notifications if one of the properties
18     change (the latter being more memory efficient if you want to listen on
19     more properties). The listener will recieve the property name as
20     first argument, followed by *data.
21
22 detach (callback, *data)
23     Disconnect callback as listener.
24
25 notify (name)
26     Notify all listeners the property 'name' has changed.
27 """
28
29 import types
30
31 class Element(object):
32     """Base class for UML data classes."""
33
34     def __init__(self):
35         self._observers = dict()
36
37     def save(self, save_func):
38         """Save the state by calling save_func(name, value)."""
39         lst = dir(self.__class__)
40         for prop in map(isinstance, lst, [umlproperty] * len(lst)):
41                 prop.save(self, save_func)
42
43     def load(self, name, value):
44         """Loads value in name. Make sure that for every load postload()
45         should be called."""
46         try:
47             prop = getattr(self.__class__, name)
48         except AttributeError, e:
49             raise AttributeError, "'%s' has no property '%s'" % \
50                                         (self.__class__.__name__, name)
51         else:
52             prop.load(self, value)
53
54     def postload(self):
55         pass
56
57     def unlink(self):
58         self.notify('__unlink__')
59            
60     def attach(self, names, callback, *data):
61         """Attach 'callback' to a list of names. Names may also be a string."""
62         if type(names) is types.StringType:
63             names = (names,)
64         cb = (callback,) + data
65         for name in names:
66             try:
67                 o = self._observers[name]
68                 if not cb in o:
69                     o.append(cb)
70             except KeyError:
71                 # create new entry
72                 self._observers[name] = [cb]
73
74     def detach(self, callback, *data):
75         """Detach a callback identified by it's data."""
76         #print 'detach', callback, data
77         cb = (callback,) + data
78         for values in self._observers.values():
79             # Remove all occurences of 'cb' from values
80             # (if none is found ValueError is raised).
81             try:
82                 while True:
83                     values.remove(cb)
84             except ValueError:
85                 pass
86
87     def notify(self, name):
88         """Send notification to attached callbacks that a property
89         has changed."""
90         cb_list = self._observers.get(name) or ()
91         for cb_data in cb_list:
92             try:
93                 apply(cb_data[0], (name,) + cb_data[1:])
94             except:
95                 pass
96
97     # OCL methods: (from SMW by Ivan Porres (http://www.abo.fi/~iporres/smw))
98
99     def isKindOf(self,clazz):
100         """Returns true if the object is an instance of clazz."""
101         return isinstance(self, clazz)
102
103     def isTypeOf(self, other):
104         """Returns true if the object is of the same type as other."""
105         return type(self) == type(other)
106
107
108 if __name__ == '__main__':
109     a = Element()
110     b = Element()
111     def cb_func(name, *args):
112         print '  cb_func:', name, args
113
114     a.attach('ev1', cb_func, a)
115     a.attach('ev1', cb_func, a)
116     a.attach('ev2', cb_func, 'ev2', a)
117
118     print 'notify: ev1'
119     a.notify('ev1')
120     print 'notify: ev2'
121     a.notify('ev2')
122  
123     a.detach(cb_func, a)
124
125     print 'notify: ev1'
126     a.notify('ev1')
127     print 'notify: ev2'
128     a.notify('ev2')
129  
Note: See TracBrowser for help on using the browser.