forked from ebroder/python-zephyr
/
zephyr.py
102 lines (74 loc) · 2.6 KB
/
zephyr.py
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
from functools import wraps
import _zephyr as _z
from _zephyr import receive, ZNotice, sender, realm, interrupt, getVariable, setVariable, unsetVariable
__all__ = ("receive", "ZNotice", "sender", "realm", "interrupt", "init", "Subscriptions", "getVariable", "setVariable", "unsetVariable")
__inited = False
def init():
global __inited
if not __inited:
_z.initialize()
_z.openPort()
_z.cancelSubs()
__inited = True
def req_init(func):
@wraps(func)
def do(*args, **kwargs):
init()
return func(*args, **kwargs)
return do
receive = req_init(receive)
sender = req_init(sender)
class Subscriptions(set):
"""
A set of <class, instance, recipient> tuples representing the
tuples that have been subbed to
Since subscriptions are shared across the entire process, this
class is a singleton
"""
def __new__(cls):
if not '_instance' in cls.__dict__:
cls._instance = super(Subscriptions, cls).__new__(cls)
init()
return cls._instance
def __init__(self):
super(Subscriptions, self).__init__(_z.getSubscriptions())
def __del__(self):
_z.cancelSubs()
super(Subscriptions, self).__del__()
def _fixTuple(self, item):
if len(item) != 3:
raise TypeError, 'item is not a zephyr subscription tuple'
item = list(item)
if item[2].startswith('*'):
item[2] = item[2][1:]
if '@' not in item[2]:
item[2] += '@%s' % _z.realm()
return tuple(item)
def add(self, item):
item = self._fixTuple(item)
if item in self:
return
_z.sub(*item)
super(Subscriptions, self).add(item)
def remove(self, item):
item = self._fixTuple(item)
if item not in self:
raise KeyError, item
_z.unsub(*item)
super(Subscriptions, self).remove(item)
def clear(self):
_z.cancelSubs()
super(Subscriptions, self).clear()
def update(self, items):
new_items = set(self._fixTuple(s) for s in items) - self
if not new_items:
return
_z.subAll(list(new_items))
super(Subscriptions, self).update(new_items)
def difference_update(self, items):
del_items = set(self._fixTuple(s) for s in items)
del_items.intersection_update(self)
if not del_items:
return
_z.unsubAll(list(del_items))
super(Subscriptions, self).difference_update(del_items)