Rx\Operator\GroupByUntilOperator::__invoke PHP Method

__invoke() public method

public __invoke ( Rx\ObservableInterface $observable, Rx\ObserverInterface $observer, Rx\SchedulerInterface $scheduler = null ) : Rx\DisposableInterface
$observable Rx\ObservableInterface
$observer Rx\ObserverInterface
$scheduler Rx\SchedulerInterface
return Rx\DisposableInterface
    public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
    {
        $map = [];
        $groupDisposable = new CompositeDisposable();
        $refCountDisposable = new RefCountDisposable($groupDisposable);
        $keySelector = $this->keySelector;
        $elementSelector = $this->elementSelector;
        $durationSelector = $this->durationSelector;
        $keySerializer = $this->keySerializer;
        $sourceEmits = true;
        $callbackObserver = new CallbackObserver(function ($value) use(&$map, $keySelector, $elementSelector, $durationSelector, $observer, $keySerializer, $groupDisposable, $refCountDisposable, $scheduler, &$sourceEmits) {
            try {
                $key = $keySelector($value);
                $serializedKey = $keySerializer($key);
            } catch (Exception $e) {
                foreach ($map as $groupObserver) {
                    $groupObserver->onError($e);
                }
                $observer->onError($e);
                return;
            }
            $fireNewMapEntry = false;
            try {
                if (!isset($map[$serializedKey])) {
                    $map[$serializedKey] = new Subject();
                    $fireNewMapEntry = true;
                }
                $writer = $map[$serializedKey];
            } catch (Exception $e) {
                foreach ($map as $groupObserver) {
                    $groupObserver->onError($e);
                }
                $observer->onError($e);
                return;
            }
            if ($fireNewMapEntry) {
                $group = new GroupedObservable($key, $writer, $refCountDisposable);
                $durationGroup = new GroupedObservable($key, $writer);
                try {
                    $duration = $durationSelector($durationGroup);
                } catch (\Exception $e) {
                    foreach ($map as $groupObserver) {
                        $groupObserver->onError($e);
                    }
                    $observer->onError($e);
                    return;
                }
                if ($sourceEmits) {
                    $observer->onNext($group);
                }
                $md = new SingleAssignmentDisposable();
                $groupDisposable->add($md);
                $expire = function () use(&$map, &$md, $serializedKey, &$writer, &$groupDisposable) {
                    if (isset($map[$serializedKey])) {
                        unset($map[$serializedKey]);
                        $writer->onCompleted();
                    }
                    $groupDisposable->remove($md);
                };
                $callbackObserver = new CallbackObserver(function () {
                }, function (Exception $exception) use($map, $observer) {
                    foreach ($map as $writer) {
                        $writer->onError($exception);
                    }
                    $observer->onError($exception);
                }, function () use($expire) {
                    $expire();
                });
                $subscription = $duration->take(1)->subscribe($callbackObserver, $scheduler);
                $md->setDisposable($subscription);
            }
            try {
                $element = $elementSelector($value);
            } catch (Exception $exception) {
                foreach ($map as $writer) {
                    $writer->onError($exception);
                }
                $observer->onError($exception);
                return;
            }
            $writer->onNext($element);
        }, function (Exception $error) use(&$map, $observer) {
            foreach ($map as $writer) {
                $writer->onError($error);
            }
            $observer->onError($error);
        }, function () use(&$map, $observer) {
            foreach ($map as $writer) {
                $writer->onCompleted();
            }
            $observer->onCompleted();
        });
        $subscription = $observable->subscribe($callbackObserver, $scheduler);
        $groupDisposable->add($subscription);
        $sourceDisposable = new CallbackDisposable(function () use($refCountDisposable, &$sourceEmits) {
            $sourceEmits = false;
            $refCountDisposable->dispose();
        });
        return $sourceDisposable;
    }
GroupByUntilOperator