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)); }
public void Loop(Cell <T> c) => TransactionInternal.Apply( (trans, _) => { lock (this.isLoopedLock) { if (this.isLooped) { throw new InvalidOperationException("Loop was looped more than once."); } this.isLooped = true; } if (trans != this.transaction) { this.transaction = null; throw new InvalidOperationException( "Loop must be looped in the same transaction that it was created in."); } this.transaction = null; this.Loop(trans, c); return(UnitInternal.Value); }, false);
internal Behavior(Stream <T> stream, T initialValue) { this.stream = stream; this.valueProperty = initialValue; this.UsingInitialValue = true; this.streamListener = TransactionInternal.Apply( (trans1, _) => this.stream.Listen( Node <T> .Null, trans1, (trans2, a) => { this.valueUpdate.MatchNone( () => { trans2.Last( () => { this.valueUpdate.MatchSome(v => this.ValueProperty = v); this.valueUpdate = MaybeInternal.None; }); }); this.valueUpdate = MaybeInternal.Some(a); }, false), false); }
internal Cell(Behavior <T> behavior) { this.BehaviorImpl = behavior; this.updates = new Lazy <Stream <T> >(() => TransactionInternal.Apply( (trans, _) => this.BehaviorImpl.Updates().Coalesce(trans, (left, right) => right), false)); }
internal static Cell <T> ConstantLazyImpl <T>(Lazy <T> value) => TransactionInternal.Apply((trans, _) => new Cell <T>(StreamInternal.NeverImpl <T>().HoldLazyInternal(trans, value)), false);
internal IWeakListener ListenWeakImpl(Action <T> handler) => TransactionInternal.Apply( (trans, _) => this.BehaviorImpl.Value(trans).ListenWeakImpl(handler), false);
internal static Behavior <T> ConstantLazyImpl <T>(Lazy <T> value) => TransactionInternal.Apply((trans, _) => StreamInternal.NeverImpl <T>().HoldLazyInternal(trans, value), false);
internal static Stream <T> MergeImpl <T, T2>(this IEnumerable <T2> s, Func <T, T, T> f) where T2 : Stream <T> { IReadOnlyList <Stream <T> > v = s.ToArray(); return(TransactionInternal.Apply((trans, _) => Merge(trans, v, 0, v.Count, f), false)); }
internal static Stream <T> UpdatesImpl <T>(Behavior <T> b) => TransactionInternal.Apply( (trans, _) => b.Updates().Coalesce(trans, (left, right) => right), false);
internal static Stream <T> ValueImpl <T>(Behavior <T> b) => TransactionInternal.Apply((trans, _) => b.Value(trans), false);
internal Stream <T> MergeImpl(Stream <T> s, Func <T, T, T> f) => TransactionInternal.Apply((trans, _) => this.Merge(trans, s, f), false);
internal Cell <T> HoldLazyImpl(Lazy <T> initialValue) => TransactionInternal.Apply((trans, _) => new Cell <T>(this.HoldLazyInternal(trans, initialValue)), false);
internal IWeakListener Listen(Node target, Action <TransactionInternal, T> action) => TransactionInternal.Apply( (trans1, _) => this.Listen(target, trans1, action, false), false);