60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
from typing import Any, List, Optional, Tuple
|
|
|
|
from reactivex import Observable, abc
|
|
from reactivex.disposable import CompositeDisposable, SingleAssignmentDisposable
|
|
from reactivex.internal.utils import NotSet
|
|
|
|
|
|
def with_latest_from_(
|
|
parent: Observable[Any], *sources: Observable[Any]
|
|
) -> Observable[Tuple[Any, ...]]:
|
|
NO_VALUE = NotSet()
|
|
|
|
def subscribe(
|
|
observer: abc.ObserverBase[Any], scheduler: Optional[abc.SchedulerBase] = None
|
|
) -> abc.DisposableBase:
|
|
def subscribeall(
|
|
parent: Observable[Any], *children: Observable[Any]
|
|
) -> List[SingleAssignmentDisposable]:
|
|
|
|
values = [NO_VALUE for _ in children]
|
|
|
|
def subscribechild(
|
|
i: int, child: Observable[Any]
|
|
) -> SingleAssignmentDisposable:
|
|
subscription = SingleAssignmentDisposable()
|
|
|
|
def on_next(value: Any) -> None:
|
|
with parent.lock:
|
|
values[i] = value
|
|
|
|
subscription.disposable = child.subscribe(
|
|
on_next, observer.on_error, scheduler=scheduler
|
|
)
|
|
return subscription
|
|
|
|
parent_subscription = SingleAssignmentDisposable()
|
|
|
|
def on_next(value: Any) -> None:
|
|
with parent.lock:
|
|
if NO_VALUE not in values:
|
|
result = (value,) + tuple(values)
|
|
observer.on_next(result)
|
|
|
|
children_subscription = [
|
|
subscribechild(i, child) for i, child in enumerate(children)
|
|
]
|
|
disp = parent.subscribe(
|
|
on_next, observer.on_error, observer.on_completed, scheduler=scheduler
|
|
)
|
|
parent_subscription.disposable = disp
|
|
|
|
return [parent_subscription] + children_subscription
|
|
|
|
return CompositeDisposable(subscribeall(parent, *sources))
|
|
|
|
return Observable(subscribe)
|
|
|
|
|
|
__all__ = ["with_latest_from_"]
|