public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null) { $singleDisposable = new SingleAssignmentDisposable(); $disposable = new CompositeDisposable(); $disposable->add($singleDisposable); $callbackObserver = new CallbackObserver(function (Observable $x) use($disposable, $scheduler, $observer) { if ($this->hasCurrent) { return; } $this->hasCurrent = true; $inner = new SingleAssignmentDisposable(); $disposable->add($inner); $innerSub = $x->subscribe(new CallbackObserver([$observer, "onNext"], [$observer, "onError"], function () use($disposable, $inner, $observer) { $disposable->remove($inner); $this->hasCurrent = false; if ($this->isStopped && $disposable->count() === 1) { $observer->onCompleted(); } }), $scheduler); $inner->setDisposable($innerSub); }, [$observer, 'onError'], function () use($disposable, $observer) { $this->isStopped = true; if (!$this->hasCurrent && $disposable->count() === 1) { $observer->onCompleted(); } }); $singleDisposable->setDisposable($observable->subscribe($callbackObserver, $scheduler)); return $disposable; }
/** * @param \Rx\ObservableInterface $observable * @param \Rx\ObserverInterface $observer * @param \Rx\SchedulerInterface $scheduler * @return \Rx\DisposableInterface */ public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null) { $group = new CompositeDisposable(); $isStopped = false; $sourceSubscription = new SingleAssignmentDisposable(); $group->add($sourceSubscription); $callbackObserver = new CallbackObserver(function (ObservableInterface $innerSource) use(&$group, &$isStopped, $observer, &$scheduler) { $innerSubscription = new SingleAssignmentDisposable(); $group->add($innerSubscription); $innerSubscription->setDisposable($innerSource->subscribe(new CallbackObserver(function ($nextValue) use($observer) { $observer->onNext($nextValue); }, function ($error) use($observer) { $observer->onError($error); }, function () use(&$group, &$innerSubscription, &$isStopped, $observer) { $group->remove($innerSubscription); if ($isStopped && $group->count() === 1) { $observer->onCompleted(); } }), $scheduler)); }, [$observer, 'onError'], function () use(&$group, &$isStopped, $observer) { $isStopped = true; if ($group->count() === 1) { $observer->onCompleted(); } }); $subscription = $this->sources->subscribe($callbackObserver, $scheduler); $sourceSubscription->setDisposable($subscription); return $group; }
/** * @test */ public function a_disposable_can_be_added_after_creation() { $d1 = new CallbackDisposable(function () { }); $d2 = new CallbackDisposable(function () { }); $disposable = new CompositeDisposable(array($d1)); $this->assertEquals(1, $disposable->count()); $this->assertFalse($disposable->contains($d2)); $disposable->add($d2); $this->assertEquals(2, $disposable->count()); $this->assertTrue($disposable->contains($d2)); }
/** * Merges an observable sequence of observables into an observable sequence. * * @param ObservableInterface $observables * * @return ObserverInterface */ public static function mergeAll(ObservableInterface $sources) { // todo: add scheduler return new AnonymousObservable(function ($observer, $scheduler) use($sources) { $group = new CompositeDisposable(); $isStopped = false; $sourceSubscription = new SingleAssignmentDisposable(); $group->add($sourceSubscription); $sourceSubscription->setDisposable($sources->subscribeCallback(function ($innerSource) use(&$group, &$isStopped, $observer, &$scheduler) { $innerSubscription = new SingleAssignmentDisposable(); $group->add($innerSubscription); $innerSubscription->setDisposable($innerSource->subscribeCallback(function ($nextValue) use($observer) { $observer->onNext($nextValue); }, function ($error) use($observer) { $observer->onError($error); }, function () use(&$group, &$innerSubscription, &$isStopped, $observer) { $group->remove($innerSubscription); if ($isStopped && $group->count() === 1) { $observer->onCompleted(); } }, $scheduler)); }, function ($error) use($observer) { $observer->onError($error); }, function () use(&$group, &$isStopped, $observer) { $isStopped = true; if ($group->count() === 1) { $observer->onCompleted(); } }, $scheduler)); return $group; }); }