Source code for samuroi.maskset
from .util.event import Event
from collections import MutableSet
from cached_property import cached_property
[docs]class MaskSet(MutableSet):
"""
This class inherits from: :py:class:`collections.MutableSet`
uses generic mixin functions and therefore only needs to reimplement the following functions:
- `__contains__`
- `__iter__`
- `__len__`
- `add()`
- `discard()`
"""
def __init__(self, iterable=[]):
self.__items = dict()
for i in iterable:
self.add(i)
@cached_property
def added(self):
"""A signal that will be triggered when an item was added to the set."""
return Event()
@cached_property
def preremove(self):
"""A signal that will be triggered when an item is about to be removed from the set."""
return Event()
@cached_property
def removed(self):
"""A signal that will be triggered when an item was removed from the set."""
return Event()
def __len__(self):
return sum(len(value) for value in self.__items.itervalues())
def __contains__(self, elem):
if type(elem) not in self.__items:
return False
return elem in self.__items[type(elem)]
def __iter__(self):
for val in self.__items.itervalues():
for i in val:
yield i
# loop over children if the mask has children:)
# fixme actually this requires recursion...
for child in getattr(i, "children", []):
yield child
def __getitem__(self, type):
return self.__items[type]
[docs] def add(self, elem):
"""
Add given mask to the set if it is not already included.
Will trigger the :py:attr:`samuroi.maskset.MaskSet.added` event in case it is added.
:param elem: The mask to add.
"""
_set = self.__items.setdefault(type(elem), set())
emit = elem not in _set
_set.add(elem)
if emit:
self.added(elem)
[docs] def discard(self, elem):
"""
Remove the given mask from the set. If the mask is not in the set do nothing.
If a mask gets removed this will trigger :py:attr:`samuroi.maskset.MaskSet.preremove` and
:py:attr:`samuroi.maskset.MaskSet.removed`
:param elem: the mask to be removed.
"""
emit = elem in self.__items[type(elem)]
if emit:
self.preremove(elem)
self.__items[type(elem)].discard(elem)
if emit:
self.removed(elem)
[docs] def types(self):
"""
Get the set of different types of masks which are in the maskset.
:return: An iterable object of types.
"""
return self.__items.keys()