/**
  * @inheritDoc
  */
 public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
 {
     $onNext = function ($innerSource) use($observer, $scheduler) {
         $innerDisposable = new SingleAssignmentDisposable();
         $id = ++$this->latest;
         $this->hasLatest = true;
         $this->innerSubscription->setDisposable($innerDisposable);
         $innerCallbackObserver = new CallbackObserver(function ($x) use($id, $observer) {
             if ($this->latest === $id) {
                 $observer->onNext($x);
             }
         }, function ($e) use($id, $observer) {
             if ($this->latest === $id) {
                 $observer->onError($e);
             }
         }, function () use($id, $observer) {
             if ($this->latest === $id) {
                 $this->hasLatest = false;
                 if ($this->isStopped) {
                     $observer->onCompleted();
                 }
             }
         });
         $innerSubscription = $innerSource->subscribe($innerCallbackObserver, $scheduler);
         $innerDisposable->setDisposable($innerSubscription);
     };
     $callbackObserver = new CallbackObserver($onNext, [$observer, 'onError'], function () use($observer) {
         $this->isStopped = true;
         if (!$this->hasLatest) {
             $observer->onCompleted();
         }
     });
     $subscription = $observable->subscribe($callbackObserver, $scheduler);
     return new BinaryDisposable($subscription, $this->innerSubscription);
 }
Beispiel #2
0
 public function ensureActive()
 {
     $isOwner = false;
     if (!$this->hasFaulted && count($this->queue) > 0) {
         $isOwner = !$this->isAcquired;
         $this->isAcquired = true;
     }
     if (!$isOwner) {
         return;
     }
     $this->disposable->setDisposable($this->scheduler->scheduleRecursive(function ($recurse) {
         $parent = $this;
         if (count($parent->queue) > 0) {
             $work = array_shift($parent->queue);
         } else {
             $parent->isAcquired = false;
             return;
         }
         try {
             if (!is_callable($work)) {
                 throw new Exception("work is not callable");
             }
             $res = $work();
         } catch (Exception $e) {
             $res = $e;
         }
         if ($res instanceof Exception) {
             $parent->queue = [];
             $parent->hasFaulted = true;
             throw $res;
         }
         $recurse($parent);
     }));
 }
Beispiel #3
0
 /**
  * @inheritDoc
  */
 public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
 {
     if ($this->scheduler !== null) {
         $scheduler = $this->scheduler;
     }
     $innerDisp = new SerialDisposable();
     $disp = $observable->subscribe(new CallbackObserver(function ($x) use($innerDisp, $observer, $scheduler) {
         $now = $scheduler->now();
         if ($this->nextSend <= $now) {
             $innerDisp->setDisposable(new EmptyDisposable());
             $observer->onNext($x);
             $this->nextSend = $now + $this->throttleTime - 1;
             return;
         }
         $newDisp = Observable::just($x)->delay($this->nextSend - $now)->subscribe(new CallbackObserver(function ($x) use($observer, $scheduler) {
             $observer->onNext($x);
             $this->nextSend = $scheduler->now() + $this->throttleTime - 1;
             if ($this->completed) {
                 $observer->onCompleted();
             }
         }, [$observer, 'onError']), $scheduler);
         $innerDisp->setDisposable($newDisp);
     }, function (\Exception $e) use($observer, $innerDisp) {
         $innerDisp->dispose();
         $observer->onError($e);
     }, function () use($observer) {
         $this->completed = true;
         if ($this->nextSend === 0) {
             $observer->onCompleted();
         }
     }), $scheduler);
     return new CompositeDisposable([$disp, $innerDisp]);
 }
Beispiel #4
0
 /**
  * @inheritDoc
  */
 public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
 {
     $disposable = new SerialDisposable();
     $singleDisposable = new SingleAssignmentDisposable();
     $disposable->setDisposable($singleDisposable);
     $singleDisposable->setDisposable($this->scheduler->schedule(function () use($disposable, $observer, $observable, $scheduler) {
         $subscription = $observable->subscribe($observer, $scheduler);
         $disposable->setDisposable(new ScheduledDisposable($this->scheduler, $subscription));
     }));
     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)
 {
     $disposable = new SerialDisposable();
     $cbObserver = new CallbackObserver(function ($x) use($observer) {
         $this->passThrough = true;
         $observer->onNext($x);
     }, [$observer, 'onError'], function () use($observer, $disposable, $scheduler) {
         if (!$this->passThrough) {
             $disposable->setDisposable($this->observable->subscribe($observer, $scheduler));
             return;
         }
         $observer->onCompleted();
     });
     $subscription = $observable->subscribe($cbObserver, $scheduler);
     $disposable->setDisposable($subscription);
     return $disposable;
 }
 /**
  * @test
  */
 public function it_disposes_the_assigned_disposable_if_already_disposed()
 {
     $disposed1 = false;
     $disposed2 = false;
     $d1 = new CallbackDisposable(function () use(&$disposed1) {
         $disposed1 = true;
     });
     $d2 = new CallbackDisposable(function () use(&$disposed2) {
         $disposed2 = true;
     });
     $disposable = new SerialDisposable();
     $disposable->setDisposable($d1);
     $this->assertFalse($disposed1);
     $disposable->dispose();
     $disposable->setDisposable($d2);
     $this->assertTrue($disposed2);
 }
Beispiel #7
0
 /**
  * @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)
 {
     $disposable = new SerialDisposable();
     $getNewObserver = function () use($observable, $observer, $disposable, &$getNewObserver, $scheduler) {
         return new CallbackObserver([$observer, "onNext"], function ($error) use($observable, $observer, $disposable, &$getNewObserver, $scheduler) {
             $this->retryCount--;
             if ($this->retryCount === 0) {
                 $observer->onError($error);
                 return;
             }
             $subscription = $observable->subscribe($getNewObserver(), $scheduler);
             $disposable->setDisposable($subscription);
         }, function () use($observer) {
             $observer->onCompleted();
             $this->retryCount = 0;
         });
     };
     $subscription = $observable->subscribe($getNewObserver(), $scheduler);
     $disposable->setDisposable($subscription);
     return new CallbackDisposable(function () use(&$disposable) {
         $disposable->dispose();
     });
 }
Beispiel #8
0
 /**
  * @inheritDoc
  */
 public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
 {
     $completeCount = 0;
     $disposable = new SerialDisposable();
     $subscribe = function () use(&$disposable, $observable, $observer, &$completeCount, $scheduler, &$subscribe) {
         $disposable->setDisposable($observable->subscribe(new CallbackObserver([$observer, "onNext"], [$observer, "onError"], function () use(&$completeCount, $observable, $observer, &$disposable, &$subscribe, $scheduler) {
             $completeCount++;
             if ($this->repeatCount === -1 || $completeCount < $this->repeatCount) {
                 $subscribe();
             }
             if ($completeCount === $this->repeatCount) {
                 $observer->onCompleted();
                 return;
             }
         }), $scheduler));
     };
     $subscribe();
     return new CallbackDisposable(function () use(&$disposable) {
         $disposable->dispose();
     });
 }
Beispiel #9
0
 /**
  * @test
  */
 public function map_with_index_dispose_inside_selector()
 {
     $xs = $this->createHotObservable([onNext(100, 4), onNext(200, 3), onNext(500, 2), onNext(600, 1)]);
     $invoked = 0;
     $results = $this->scheduler->createObserver();
     $d = new SerialDisposable();
     $d->setDisposable($xs->mapWithIndex(function ($index, $x) use(&$invoked, $d) {
         $invoked++;
         if ($this->scheduler->getClock() > 400) {
             $d->dispose();
         }
         return $x + $index * 10;
     })->subscribe($results));
     $this->scheduler->scheduleAbsolute(TestScheduler::DISPOSED, function () use($d) {
         $d->dispose();
     });
     $this->scheduler->start();
     $this->assertMessages([onNext(100, 4), onNext(200, 13)], $results->getMessages());
     $this->assertSubscriptions([subscribe(0, 500)], $xs->getSubscriptions());
     $this->assertEquals(3, $invoked);
 }
Beispiel #10
0
 /**
  * @inheritDoc
  */
 public function schedulePeriodic(callable $action, $delay, $period)
 {
     $now = $this->now();
     $nextTime = $now + $delay;
     $disposable = new SerialDisposable();
     $doActionAndReschedule = function () use(&$nextTime, $period, $disposable, $action, &$doActionAndReschedule) {
         $action();
         $nextTime = $nextTime + $period;
         $delay = $nextTime - $this->now();
         if ($delay < 0) {
             $delay = 0;
         }
         $disposable->setDisposable($this->schedule($doActionAndReschedule, $delay));
     };
     $disposable->setDisposable($this->schedule($doActionAndReschedule, $delay));
     return $disposable;
 }