예제 #1
0
        Stream <E> asyncExpand <E>(Func <T, Stream <E> > convert)
        {
            _StreamControllerBase <E> controller   = null;
            StreamSubscription <T>    subscription = null;

            void onListen()
            {
                D.assert(controller is _StreamController <E> ||
                         controller is _BroadcastStreamController <E>);
                subscription = listen((T evt) => {
                    Stream <E> newStream;
                    try {
                        newStream = convert(evt);
                    }
                    catch (Exception e) {
                        controller.addError(e, e.StackTrace);
                        return;
                    }

                    if (newStream != null)
                    {
                        subscription.pause();
                        controller.addStream(newStream).whenComplete(subscription.resume);
                    }
                },
                                      onError: controller._addError, // Avoid Zone error replacement.
                                      onDone: () => controller.close());
            }

            if (isBroadcast)
            {
                controller = (_StreamControllerBase <E>) StreamController <E> .broadcast(
                    onListen : () => onListen(),
                    onCancel : () => { subscription.cancel(); },
                    sync : true);
            }
            else
            {
                controller = (_StreamControllerBase <E>) StreamController <E> .create(
                    onListen : () => onListen(),
                    onPause : () => { subscription.pause(); },
                    onResume : () => { subscription.resume(); },
                    onCancel : () => subscription.cancel(),
                    sync : true);
            }

            return(controller.stream);
        }
예제 #2
0
        public Stream <E> asyncMap <E>(Func <T, FutureOr> convert)
        {
            _StreamControllerBase <E> controller   = null;
            StreamSubscription <T>    subscription = null;

            void onListen()
            {
                var add = new Action <E>(controller.add);

                D.assert(controller is _StreamController <E> ||
                         controller is _BroadcastStreamController <E>);
                var addError = new Action <object, string>(controller._addError);

                subscription = listen((T evt) => {
                    FutureOr newValue;
                    try {
                        newValue = convert(evt);
                    }
                    catch (Exception e) {
                        controller.addError(e, e.StackTrace);
                        return;
                    }

                    if (newValue.f is Future <E> newFuture)
                    {
                        // siyao: this if different from dart
                        subscription.pause();
                        newFuture
                        .then(d => add((E)d), onError: (e) => {
                            addError(e, e.StackTrace);
                            return(FutureOr.nil);
                        })
                        .whenComplete(subscription.resume);
                    }
                    else
                    {
                        // Siyao: This works as if this is csharpt
                        controller.add((E)newValue.v);
                    }
                }, onError: addError, onDone: () => controller.close());
            }

            if (isBroadcast)
            {
                controller = (_StreamControllerBase <E>) StreamController <E> .broadcast(
                    onListen : () => onListen(),
                    onCancel : () => { subscription.cancel(); },
                    sync : true);
            }
            else
            {
                controller = (_StreamControllerBase <E>) StreamController <E> .create(
                    onListen : onListen,
                    onPause : () => { subscription.pause(); },
                    onResume : () => { subscription.resume(); },
                    onCancel : () => subscription.cancel(),
                    sync : true);
            }

            return(controller.stream);
        }
예제 #3
0
        public static Stream <T> periodic(TimeSpan period,
                                          Func <int, T> computation = null)
        {
            Timer timer                     = default;
            int   computationCount          = 0;
            StreamController <T> controller = null;
            // Counts the time that the Stream was running (and not paused).
            Stopwatch watch = new Stopwatch();

            Action sendEvent = () => {
                watch.reset();
                T data = default;
                if (computation != null)
                {
                    try {
                        data = computation(computationCount++);
                    }
                    catch (Exception e) {
                        controller.addError(e, e.StackTrace);
                        return;
                    }
                }

                controller.add(data);
            };

            Action startPeriodicTimer = () => {
                D.assert(timer == null);
                timer = Timer.periodic(period, (object timer1) => {
                    sendEvent();
                    return(null);
                });
            };

            // the original code new an abstract class
            controller = StreamController <T> .create(
                sync : true,
                onListen : () => {
                watch.start();
                startPeriodicTimer();
            },
                onPause : () => {
                timer.cancel();
                timer = null;
                watch.stop();
            },
                onResume : () => {
                D.assert(timer == null);
                TimeSpan elapsed = watch.elapsed;
                watch.start();
                timer = Timer.create(period - elapsed, () => {
                    timer = null;
                    startPeriodicTimer();
                    sendEvent();
                });
            },
                onCancel : () => {
                if (timer != null)
                {
                    timer.cancel();
                }
                timer = null;
                return(Future._nullFuture);
            });

            return(controller.stream);
        }