internal static Behavior <TResult> LiftBehaviorsImpl <T, T2, TResult>( this IReadOnlyCollection <T2> b, Func <IReadOnlyList <T>, TResult> f) where T2 : Behavior <T> { return(TransactionInternal.Apply( (trans1, _) => { Stream <Action <T[]> > @out = new Stream <Action <T[]> >( new FanOutKeepListenersAlive(b.Select(behavior => behavior.KeepListenersAlive))); Lazy <TResult> initialValue = new Lazy <TResult>(() => f(b.Select(behavior => behavior.SampleNoTransaction()).ToArray())); IReadOnlyList <IListener> listeners = b.Select( (behavior, i) => behavior.Updates() .Listen( @out.Node, trans1, (trans2, v) => @out.Send(trans2, vv => vv[i] = v), false)) .ToArray(); return @out.Coalesce(trans1, (x, y) => x + y) .MapImpl( a => { T[] values = b.Select(behavior => behavior.SampleNoTransaction()).ToArray(); a(values); return f(values); }) .UnsafeAttachListener(ListenerInternal.CreateCompositeImpl(listeners)) .HoldLazyInternal(trans1, initialValue); }, false)); }
internal static Action <TransactionInternal, T> Create <T>(Func <T, T, T> f, Stream <T> @out) { bool accumValid = false; T accum = default(T); return((trans1, a) => { if (accumValid) { accum = f(accum, a); } else { accum = a; accumValid = true; trans1.Prioritized( @out.Node, trans2 => { // ReSharper disable once AccessToModifiedClosure @out.Send(trans2, accum); accumValid = false; accum = default(T); }); } }); }
internal Stream <TResult> SnapshotImpl <T1, TResult>(Behavior <T1> b, Func <T, T1, TResult> f) { Stream <TResult> @out = new Stream <TResult>(this.KeepListenersAlive); IListener l = this.Listen(@out.Node, (trans2, a) => @out.Send(trans2, f(a, b.SampleNoTransaction()))); return(@out.UnsafeAttachListener(l)); }
internal Stream <TResult> MapImpl <TResult>(Func <T, TResult> f) { Stream <TResult> @out = new Stream <TResult>(this.KeepListenersAlive); IListener l = this.Listen(@out.Node, (trans2, a) => @out.Send(trans2, f(a))); return(@out.UnsafeAttachListener(l)); }
internal static Stream <T> FilterMaybeImpl <T, TMaybe>(this Stream <TMaybe> s, Action <TMaybe, Action <T> > matchSome) { Stream <T> @out = new Stream <T>(s.KeepListenersAlive); IListener l = s.Listen( @out.Node, (trans2, a) => matchSome(a, v => @out.Send(trans2, v))); return(@out.UnsafeAttachListener(l)); }
internal Stream <T> FilterImpl(Func <T, bool> predicate) { Stream <T> @out = new Stream <T>(this.KeepListenersAlive); IListener l = this.Listen( @out.Node, (trans2, a) => { if (predicate(a)) { @out.Send(trans2, a); } }); return(@out.UnsafeAttachListener(l)); }
internal static Stream <T> SplitImpl <T, TCollection>(Stream <TCollection> s) where TCollection : IEnumerable <T> { Stream <T> @out = new Stream <T>(s.KeepListenersAlive); IListener l1 = s.Listen( new Node <T>(), (trans, aa) => { int childIx = 0; foreach (T a in aa) { trans.Split(childIx, trans1 => @out.Send(trans1, a)); childIx++; } }); return(@out.UnsafeAttachListener(l1)); }
internal Stream <TResult> SnapshotImpl <T1, T2, T3, T4, TResult>( Behavior <T1> b1, Behavior <T2> b2, Behavior <T3> b3, Behavior <T4> b4, Func <T, T1, T2, T3, T4, TResult> f) { Stream <TResult> @out = new Stream <TResult>(this.KeepListenersAlive); IListener l = this.Listen( @out.Node, (trans2, a) => @out.Send( trans2, f( a, b1.SampleNoTransaction(), b2.SampleNoTransaction(), b3.SampleNoTransaction(), b4.SampleNoTransaction()))); return(@out.UnsafeAttachListener(l)); }