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); }
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); }
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); }