예제 #1
0
 public static IReactionDisposable Reaction(Action expression, Action effect, IReactionOptions <object> options = null)
 {
     return(Reaction((reaction) =>
     {
         expression();
         return Null;
     }, (value, reaction) =>
     {
         effect();
     }, new ReactionOptions <object>()
     {
         Comparer = new LambdaComparer <object>((a, b) => false)
     }));
 }
예제 #2
0
        public static IReactionDisposable Reaction <T>(Func <IReactionPublic, T> expression, Action <T, IReactionPublic> effect, IReactionOptions <T> options = null)
        {
            var name      = options?.Name ?? $"Reaction@{States.NextId}";
            var runSync   = options == null || options.Scheduler != null && options.Delay == 0;
            var scheduler = CreateScheduler(options);

            var firstTime   = true;
            var isScheduled = false;
            T   value       = default(T);

            var comparer = options?.Comparer ?? EqualityComparer <T> .Default;

            var _reaction = new Reaction(
                name,
                (reaction) =>
            {
                if (firstTime || runSync)
                {
                    reactionRunner(reaction);
                }
                else if (!isScheduled)
                {
                    isScheduled = true;
                    scheduler(() => reactionRunner(reaction));
                }
            },
                options?.OnError
                );

            void reactionRunner(Reaction reaction)
            {
                isScheduled = false; // Q: move into reaction runner?
                if (reaction.IsDisposed)
                {
                    return;
                }
                var changed = false;

                reaction.Track(() =>
                {
                    var nextValue = expression(reaction);
                    changed       = firstTime || !comparer.Equals(value, nextValue) || Null == (object)nextValue;
                    value         = nextValue;
                    return(value);
                });
                var firImmediately = options?.FireImmediately;

                if (firstTime && firImmediately.HasValue && firImmediately.Value)
                {
                    effect(value, reaction);
                }
                if (!firstTime && changed)
                {
                    effect(value, reaction);
                }
                if (firstTime)
                {
                    firstTime = false;
                }
            }

            _reaction.Schedule();

            return(_reaction.GetDisposable());
        }