mirror of git://git.psyced.org/git/pypsyc
109 lines
2.9 KiB
Python
109 lines
2.9 KiB
Python
"""
|
|
pypsyc.client.observable
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
:copyright: 2010 by Manuel Jacob
|
|
:license: MIT
|
|
"""
|
|
from collections import MutableSequence, MutableMapping
|
|
|
|
from pypsyc.util import Event
|
|
|
|
|
|
class ObsAttr(object):
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __get__(self, instance, owner):
|
|
try:
|
|
return instance.__dict__[self.name]
|
|
except KeyError:
|
|
raise AttributeError
|
|
|
|
def __set__(self, instance, value):
|
|
old = instance.__dict__.get(self.name)
|
|
instance.__dict__[self.name] = value
|
|
if value != old:
|
|
instance.update_evt[self.name](old, value)
|
|
|
|
def __delete__(self, instance):
|
|
old = instance.__dict__.get(self.name)
|
|
try:
|
|
del instance.__dict__[self.name]
|
|
except KeyError:
|
|
raise AttributeError
|
|
instance.update_evt[self.name](old, None)
|
|
|
|
|
|
class ObsObj(object):
|
|
def __init__(self):
|
|
self.update_evt = dict((obs_attr.name, Event()) for obs_attr in
|
|
self.__class__.__dict__.itervalues()
|
|
if isinstance(obs_attr, ObsAttr))
|
|
|
|
|
|
class ObsList(list, MutableSequence):
|
|
def __init__(self, *args, **kwds):
|
|
list.__init__(self, *args, **kwds)
|
|
|
|
self.setitem_evt = Event()
|
|
self.delitem_evt = Event()
|
|
self.insert_evt = Event()
|
|
self.update_evt = Event()
|
|
|
|
def __setitem__(self, index, value):
|
|
old = self[index]
|
|
list.__setitem__(self, index, value)
|
|
if value != old:
|
|
self.setitem_evt(index, old, value)
|
|
|
|
def __delitem__(self, index):
|
|
if index < 0:
|
|
index = len(self) + index
|
|
old = self[index]
|
|
list.__delitem__(self, index)
|
|
self.delitem_evt(index, old)
|
|
|
|
def insert(self, index, value):
|
|
list.insert(self, index, value)
|
|
self.insert_evt(index, value)
|
|
|
|
append = MutableSequence.append
|
|
reverse = MutableSequence.reverse
|
|
extend = MutableSequence.extend
|
|
pop = MutableSequence.pop
|
|
remove = MutableSequence.remove
|
|
__iadd__ = MutableSequence.__iadd__
|
|
|
|
def updated_item(self, obj):
|
|
self.update_evt(self.index(obj), obj)
|
|
|
|
|
|
class ObsDict(dict, MutableMapping):
|
|
def __init__(self, *args, **kwds):
|
|
dict.__init__(self, *args, **kwds)
|
|
|
|
self.setitem_evt = Event()
|
|
self.delitem_evt = Event()
|
|
self.update_evt = Event()
|
|
|
|
def __setitem__(self, key, value):
|
|
old = self.get(key)
|
|
dict.__setitem__(self, key, value)
|
|
if value != old:
|
|
self.setitem_evt(key, old, value)
|
|
|
|
def __delitem__(self, key):
|
|
old = self.get(key)
|
|
dict.__delitem__(self, key)
|
|
self.delitem_evt(key, old)
|
|
|
|
pop = MutableMapping.pop
|
|
popitem = MutableMapping.popitem
|
|
clear = MutableMapping.clear
|
|
update = MutableMapping.update
|
|
setdefault = MutableMapping.setdefault
|
|
|
|
def updated_item(self, key):
|
|
self.update_evt(key, self[key])
|