3
# Copyright 2008 Free Software Foundation, Inc.
5
# This file is part of GNU Radio
7
# GNU Radio is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3, or (at your option)
12
# GNU Radio is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with GNU Radio; see the file COPYING. If not, write to
19
# the Free Software Foundation, Inc., 51 Franklin Street,
20
# Boston, MA 02110-1301, USA.
24
Abstract GNU Radio publisher/subscriber interface
26
This is a proof of concept implementation, will likely change significantly.
31
self._publishers = { }
32
self._subscribers = { }
35
def __missing__(self, key, value=None):
36
dict.__setitem__(self, key, value)
37
self._publishers[key] = None
38
self._subscribers[key] = []
39
self._proxies[key] = None
41
def __setitem__(self, key, val):
42
if not self.has_key(key):
43
self.__missing__(key, val)
44
elif self._proxies[key] is not None:
45
(p, pkey) = self._proxies[key]
48
dict.__setitem__(self, key, val)
49
for sub in self._subscribers[key]:
50
# Note this means subscribers will get called in the thread
51
# context of the 'set' caller.
54
def __getitem__(self, key):
55
if not self.has_key(key): self.__missing__(key)
56
if self._proxies[key] is not None:
57
(p, pkey) = self._proxies[key]
59
elif self._publishers[key] is not None:
60
return self._publishers[key]()
62
return dict.__getitem__(self, key)
64
def publish(self, key, publisher):
65
if not self.has_key(key): self.__missing__(key)
66
if self._proxies[key] is not None:
67
(p, pkey) = self._proxies[key]
68
p.publish(pkey, publisher)
70
self._publishers[key] = publisher
72
def subscribe(self, key, subscriber):
73
if not self.has_key(key): self.__missing__(key)
74
if self._proxies[key] is not None:
75
(p, pkey) = self._proxies[key]
76
p.subscribe(pkey, subscriber)
78
self._subscribers[key].append(subscriber)
80
def unpublish(self, key):
81
if self._proxies[key] is not None:
82
(p, pkey) = self._proxies[key]
85
self._publishers[key] = None
87
def unsubscribe(self, key, subscriber):
88
if self._proxies[key] is not None:
89
(p, pkey) = self._proxies[key]
90
p.unsubscribe(pkey, subscriber)
92
self._subscribers[key].remove(subscriber)
94
def proxy(self, key, p, pkey=None):
95
if not self.has_key(key): self.__missing__(key)
96
if pkey is None: pkey = key
97
self._proxies[key] = (p, pkey)
99
def unproxy(self, key):
100
self._proxies[key] = None
103
if __name__ == "__main__":
107
# Non-existent key gets auto-created with None value
108
print "Auto-created key 'foo' value:", o['foo']
110
# Add some subscribers
111
# First is a bare function
113
print "len=%i" % (len(x), )
114
o.subscribe('foo', print_len)
116
# The second is a class member function
117
class subber(object):
118
def __init__(self, param):
120
def printer(self, x):
121
print self._param, `x`
123
o.subscribe('foo', s.printer)
125
# The third is a lambda function
126
o.subscribe('foo', lambda x: sys.stdout.write('val='+`x`+'\n'))
128
# Update key 'foo', will notify subscribers
129
print "Updating 'foo' with three subscribers:"
132
# Remove first subscriber
133
o.unsubscribe('foo', print_len)
135
# Update now will only trigger second and third subscriber
136
print "Updating 'foo' after removing a subscriber:"
139
# Publish a key as a function, in this case, a lambda function
140
o.publish('baz', lambda : 42)
141
print "Published value of 'baz':", o['baz']
146
# This will return None, as there is no publisher
147
print "Value of 'baz' with no publisher:", o['baz']
149
# Set 'baz' key, it gets cached
152
# Now will return cached value, since no provider
153
print "Cached value of 'baz' after being set:", o['baz']