/// <summary> /// Returns an action to continue when done /// </summary> /// <param name="e"></param> /// <param name="condition"></param> /// <returns></returns> public static Action <Action> While(this Action <Action> e, Func <bool> condition) { var c = new FutureStream(); var r = new Future(); var MoveNext = default(Action <Action>); MoveNext = SignalNext => { if (condition()) { // when SignalNext is called MoveNext is called too... c.Continue(MoveNext); e(SignalNext); } else { // we need to signal r to indicate we are done r.Signal(); } }; // we could just return s so the caller can initiate the loop on its own sometime later // yet for now we just start it here c.Continue(MoveNext)(); return(r.Continue); }
public static Action <Action> ForEach <T>(this IEnumerable <T> source, Action <Action> ready, Action <T, int, Action> handler, Action done) { var c = new FutureStream(); var e = default(IEnumerator <T>); var i = -1; var r = new Future(); var MoveNext = default(Action <Action>); //Console.WriteLine("ForEach"); MoveNext = SignalNext => { if (e.MoveNext()) { //Console.WriteLine("ForEach handler"); i++; c.Continue(MoveNext); //Console.WriteLine("ForEach handler invoke"); handler(e.Current, i, SignalNext); } else { //Console.WriteLine("ForEach done"); e.Dispose(); e = null; c = null; MoveNext = null; if (done != null) { done(); } r.Signal(); } }; var SignalFirst = c.Continue( SignalNext => { //Console.WriteLine("ForEach SignalFirst"); e = source.AsEnumerable().GetEnumerator(); MoveNext(SignalNext); } ); if (ready != null) { ready(SignalFirst); } else { SignalFirst(); } return(r.Continue); }