104 lines
2.8 KiB
Python
104 lines
2.8 KiB
Python
from threading import RLock
|
|
from typing import Any, List
|
|
|
|
from reactivex import abc
|
|
|
|
|
|
class CompositeDisposable(abc.DisposableBase):
|
|
"""Represents a group of disposable resources that are disposed
|
|
together"""
|
|
|
|
def __init__(self, *args: Any):
|
|
if args and isinstance(args[0], list):
|
|
self.disposable: List[abc.DisposableBase] = args[0]
|
|
else:
|
|
self.disposable = list(args)
|
|
|
|
self.is_disposed = False
|
|
self.lock = RLock()
|
|
super(CompositeDisposable, self).__init__()
|
|
|
|
def add(self, item: abc.DisposableBase) -> None:
|
|
"""Adds a disposable to the CompositeDisposable or disposes the
|
|
disposable if the CompositeDisposable is disposed
|
|
|
|
Args:
|
|
item: Disposable to add."""
|
|
|
|
should_dispose = False
|
|
with self.lock:
|
|
if self.is_disposed:
|
|
should_dispose = True
|
|
else:
|
|
self.disposable.append(item)
|
|
|
|
if should_dispose:
|
|
item.dispose()
|
|
|
|
def remove(self, item: abc.DisposableBase) -> bool:
|
|
"""Removes and disposes the first occurrence of a disposable
|
|
from the CompositeDisposable."""
|
|
|
|
if self.is_disposed:
|
|
return False
|
|
|
|
should_dispose = False
|
|
with self.lock:
|
|
if item in self.disposable:
|
|
self.disposable.remove(item)
|
|
should_dispose = True
|
|
|
|
if should_dispose:
|
|
item.dispose()
|
|
|
|
return should_dispose
|
|
|
|
def dispose(self) -> None:
|
|
"""Disposes all disposable in the group and removes them from
|
|
the group."""
|
|
|
|
if self.is_disposed:
|
|
return
|
|
|
|
with self.lock:
|
|
self.is_disposed = True
|
|
current_disposable = self.disposable
|
|
self.disposable = []
|
|
|
|
for disp in current_disposable:
|
|
disp.dispose()
|
|
|
|
def clear(self) -> None:
|
|
"""Removes and disposes all disposable from the
|
|
CompositeDisposable, but does not dispose the
|
|
CompositeDisposable."""
|
|
|
|
with self.lock:
|
|
current_disposable = self.disposable
|
|
self.disposable = []
|
|
|
|
for disposable in current_disposable:
|
|
disposable.dispose()
|
|
|
|
def contains(self, item: abc.DisposableBase) -> bool:
|
|
"""Determines whether the CompositeDisposable contains a specific
|
|
disposable.
|
|
|
|
Args:
|
|
item: Disposable to search for
|
|
|
|
Returns:
|
|
True if the disposable was found; otherwise, False"""
|
|
|
|
return item in self.disposable
|
|
|
|
def to_list(self) -> List[abc.DisposableBase]:
|
|
return self.disposable[:]
|
|
|
|
def __len__(self) -> int:
|
|
return len(self.disposable)
|
|
|
|
@property
|
|
def length(self) -> int:
|
|
return len(self.disposable)
|