예제 #1
0
        public static IFlowConnector <T> Connector <T>(this IFlowSource <T> source, T @default = default)
        {
            var connector = new FlowConnector <T>(@default);

            connector.ConnectTo(source);
            return(connector);
        }
예제 #2
0
        public static IFlowSource <T> FilterChanges <T>(this IFlowSource <T> source, IDisposer?disposer = null)
        {
            var filtered = new FlowVar <T>(source.Value, disposer);

            // FlowVar ignores assignments when new value is equal to old one (so - we filter the changes)
            source.AddSubscription(filtered, () => { filtered.Value = source.Value; });
            return(filtered);
        }
예제 #3
0
        /// <summary>
        ///     Create a FlowCache.
        /// </summary>
        /// <param name="source">Source to cache.</param>
        /// <param name="disposer">Disposer in case T is IArc (required).</param>
        /// <exception cref="Exception">
        ///     Throws Exception in case T is IArc and no disposer is supplied
        ///     or T is not IArc and disposer is supplied.
        /// </exception>
        public FlowCache(IFlowSource <T> source, IDisposer?disposer = null)
        {
            SubscribeTo(source);

            GetValue = () => {
                int lastChangeCount;

                lock (_lock) {
                    if (_isCached)
                    {
                        (_cachedValue as IArc)?.Acquire();
                        return(_cachedValue);
                    }

                    lastChangeCount = _changeCount;
                }

                // Calc may be lock, so is not locked to allow OnChange fire on another thread
                var newValue = source.Value;

                lock (_lock) {
                    // Can be changed during Calc() by OnChange method, we have to return the value even if the value will not be used as cached later
                    if (lastChangeCount != _changeCount)
                    {
                        return(newValue);
                    }

                    // Dispose previous value is necessary, this can not be done in OnChange methods, since some object need to be disposed in the same thread (like OpenGL)
                    (_cachedValue as IArc)?.Dispose();
                    _cachedValue = newValue;
                    _isCached    = true;

                    (newValue as IArc)?.Acquire();
                    return(newValue);
                }
            };

            if (Helpers.IsInheritedFrom <T, IArc>())
            {
                if (disposer == null)
                {
                    throw new Exception($"IArc type {typeof(T)} requires disposer");
                }

                disposer.Add(() => {
                    (_cachedValue as IArc)?.Dispose();
                    _cachedValue = default !;
예제 #4
0
        public void ConnectTo(IFlowSource <T>?source)
        {
            lock (_lock) {
                if (Equals(_source, source))
                {
                    return;
                }

                _subscription?.Dispose();
                _subscription = null;

                _source = source;

                if (_source != null)
                {
                    _subscription = DisposableSubscribeTo(_source);
                }

                OnChange();
            }
        }
예제 #5
0
 public static IFlowPathBuilder <TNext> Path <T, TNext>(this IFlowSource <T> root, Func <T, TNext> transition)
     where TNext : class, IFlowChangeable
 {
     return(new FlowBuilderBuilder <IFlowSource <T> >(root).Path(transition));
 }
예제 #6
0
 public static Action Action <T1>(this IFlowSource <T1> source, object owner, Action <T1> action)
 {
     return(Flow.Action(owner, source, action));
 }
예제 #7
0
 public static IFlowSource <T> Func <T1, T>(this IFlowSource <T1> source, Func <T1, T> func)
 {
     return(Flow.Func(source, func));
 }
예제 #8
0
 public static Action Action <T1, T2, T3, T4, T5, T6, T7, T8>(object owner, IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, IFlowSource <T4> source4, IFlowSource <T5> source5, IFlowSource <T6> source6, IFlowSource <T7> source7, IFlowSource <T8> source8, Action <T1, T2, T3, T4, T5, T6, T7, T8> action)
 {
     return(new FlowAction(owner, () => action(source1.Value, source2.Value, source3.Value, source4.Value, source5.Value, source6.Value, source7.Value, source8.Value), source1, source2, source3, source4, source5, source6, source7, source8));
 }
예제 #9
0
 public static Action Action <T1, T2, T3, T4, T5>(object owner, IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, IFlowSource <T4> source4, IFlowSource <T5> source5, Action <T1, T2, T3, T4, T5> action)
 {
     return(new FlowAction(owner, () => action(source1.Value, source2.Value, source3.Value, source4.Value, source5.Value), source1, source2, source3, source4, source5));
 }
예제 #10
0
 public static Action Action <T1, T2, T3>(object owner, IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, Action <T1, T2, T3> action)
 {
     return(new FlowAction(owner, () => action(source1.Value, source2.Value, source3.Value), source1, source2, source3));
 }
예제 #11
0
 public static Action Action <T1>(object owner, IFlowSource <T1> source, Action <T1> action)
 {
     return(new FlowAction(owner, () => action(source.Value), source));
 }
예제 #12
0
 public static IFlowSource <T> Func <T1, T2, T3, T4, T5, T6, T7, T8, T>(IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, IFlowSource <T4> source4, IFlowSource <T5> source5, IFlowSource <T6> source6, IFlowSource <T7> source7, IFlowSource <T8> source8, Func <T1, T2, T3, T4, T5, T6, T7, T8, T> func)
 {
     return(new FlowFunc <T>(() => func(source1.Value, source2.Value, source3.Value, source4.Value, source5.Value, source6.Value, source7.Value, source8.Value), source1, source2, source3, source4, source5, source6, source7, source8));
 }
예제 #13
0
 public static IFlowSource <T> Func <T1, T2, T3, T4, T5, T>(IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, IFlowSource <T4> source4, IFlowSource <T5> source5, Func <T1, T2, T3, T4, T5, T> func)
 {
     return(new FlowFunc <T>(() => func(source1.Value, source2.Value, source3.Value, source4.Value, source5.Value), source1, source2, source3, source4, source5));
 }
예제 #14
0
 public static IFlowSource <T> Func <T1, T2, T3, T>(IFlowSource <T1> source1, IFlowSource <T2> source2, IFlowSource <T3> source3, Func <T1, T2, T3, T> func)
 {
     return(new FlowFunc <T>(() => func(source1.Value, source2.Value, source3.Value), source1, source2, source3));
 }
예제 #15
0
 public static IFlowSource <T> Func <T1, T>(IFlowSource <T1> source, Func <T1, T> func)
 {
     return(new FlowFunc <T>(() => func(source.Value), source));
 }