Пример #1
0
        /// <summary>
        /// Creates an reaction that observes and runs the given predicate function
        /// until it returns true. Once that happens, the given effect function
        /// is executed and the reaction is deactivated.<br/>
        /// <br/>
        /// Returns a reaction, allowing you to cancel it manually.
        /// </summary>
        /// <param name="lifetime">Reaction lifetime.</param>
        /// <param name="data">An observed predicate function.</param>
        /// <param name="effect">An effect function.</param>
        /// <param name="exceptionHandler">A function that called when an exception is thrown while computing an reaction.</param>
        /// <param name="debugName">Debug name for this reaction.</param>
        /// <returns>Created reaction.</returns>
        /// <example>
        ///
        /// var counter = Atom.Value(1);
        ///
        /// var reaction = Atom.When(Lifetime,
        ///     () => counter.Value == 10,
        ///     () => Debug.Log("Counter value equals 10")
        /// );
        ///
        /// </example>
        public static Reaction When(
            Lifetime lifetime,
            Func <bool> data,
            Action effect,
            Action <Exception> exceptionHandler = null,
            string debugName = null)
        {
            var controller = lifetime.CreateNested();

            return(Reaction(controller.Lifetime, WhenInternal, debugName: debugName));

            void WhenInternal()
            {
                Exception exception = null;

                try
                {
                    if (!data())
                    {
                        return;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }

                if (exception != null && exceptionHandler == null)
                {
                    Debug.LogException(exception);
                    return;
                }

                using (NoWatch)
                {
                    if (exception != null)
                    {
                        exceptionHandler(exception);
                    }
                    else
                    {
                        effect();
                    }

                    controller.Dispose();
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Creates an reaction that observes and runs the given predicate function
        /// until it returns true. Once that happens, the returned task is completed
        /// and the reaction is deactivated.<br/>
        /// <br/>
        /// The task will fail if the predicate throws an exception.
        /// </summary>
        /// <param name="lifetime">Reaction lifetime.</param>
        /// <param name="data">An observed predicate function.</param>
        /// <param name="debugName">Debug name for this reaction.</param>
        /// <returns>Task that completes when the predicate returns true or predicate function throws exception.</returns>
        /// <example>
        ///
        /// var counter = Atom.Value(1);
        ///
        /// await Atom.When(Lifetime, () => counter.Value == 10);
        /// Debug.Log("Counter value equals 10");
        ///
        /// </example>
        public static Task When(
            Lifetime lifetime,
            Func <bool> data,
            string debugName = null)
        {
            var controller = lifetime.CreateNested();
            var tcs        = new TaskCompletionSource <object>();

            controller.Register(() => tcs.TrySetCanceled());

            Reaction(controller.Lifetime, WhenInternal, debugName: debugName);

            return(tcs.Task);

            void WhenInternal()
            {
                Exception exception = null;

                try
                {
                    if (!data())
                    {
                        return;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }

                using (NoWatch)
                {
                    if (exception != null)
                    {
                        tcs.TrySetException(exception);
                    }
                    else
                    {
                        tcs.TrySetResult(null);
                    }

                    controller.Dispose();
                }
            }
        }