Example #1
0
        /// <summary>
        /// Ends an action using the specified <see cref="ActionRunInfo"/> instance.
        /// </summary>
        /// <param name="actionRunInfo">The run info about the action.</param>
        private static void EndAction(ActionRunInfo actionRunInfo)
        {
            if (actionRunInfo.SharedState.CurrentActionId != actionRunInfo.ActionId)
            {
                throw new InvalidOperationException(Resources.InvalidActionStack);
            }

            actionRunInfo.SharedState.CurrentActionId = actionRunInfo.ParentActionId;

            if (actionRunInfo.Exception != null)
            {
                actionRunInfo.SharedState.SuppressReactionErrors = true;
            }

            actionRunInfo.SharedState.EndAllowStateChanges(actionRunInfo.PreviousAllowStateChanges);
            actionRunInfo.SharedState.EndAllowStateReads(actionRunInfo.PreviousAllowStateReads);
            actionRunInfo.SharedState.EndBatch();
            actionRunInfo.SharedState.EndTracking(actionRunInfo.PreviousDerivation);

            if (actionRunInfo.NotifySpy)
            {
                actionRunInfo.SharedState.OnSpy(actionRunInfo, new ActionEndSpyEventArgs()
                {
                    ActionId = actionRunInfo.ActionId,
                    Name     = actionRunInfo.Name,
                    EndTime  = DateTime.UtcNow,
                });
            }

            actionRunInfo.SharedState.SuppressReactionErrors = false;
        }
Example #2
0
        /// <summary>
        /// Starts an action that changes state and recomputes the state tree.
        /// </summary>
        /// <param name="sharedState">The shared state instance to use.</param>
        /// <param name="actionName">The name of the action.</param>
        /// <param name="scope">The scope of the action.</param>
        /// <param name="arguments">The arguments to the action.</param>
        /// <returns>An <see cref="ActionRunInfo"/> instance containing the information on the currently running action.</returns>
        public static ActionRunInfo StartAction(ISharedState sharedState, string actionName, object scope, object[] arguments)
        {
            if (sharedState is null)
            {
                throw new ArgumentNullException(nameof(sharedState));
            }

            if (arguments is null)
            {
                arguments = Array.Empty <object>();
            }

            var notifySpy          = !string.IsNullOrEmpty(actionName);
            var previousDerivation = sharedState.StartUntracked();

            sharedState.StartBatch();
            var previousAllowStateChanges = sharedState.StartAllowStateChanges(true);
            var previousAllowStateReads   = sharedState.StartAllowStateReads(true);

            var actionRunInfo = new ActionRunInfo()
            {
                SharedState               = sharedState,
                Name                      = string.IsNullOrEmpty(actionName) ? $"Action@{sharedState.NextActionId}" : actionName,
                PreviousDerivation        = previousDerivation,
                PreviousAllowStateChanges = previousAllowStateChanges,
                PreviousAllowStateReads   = previousAllowStateReads,
                NotifySpy                 = notifySpy,
                StartDateTime             = DateTime.UtcNow,
                ActionId                  = sharedState.NextActionId++,
                ParentActionId            = sharedState.CurrentActionId,
            };

            if (notifySpy)
            {
                sharedState.OnSpy(actionRunInfo, new ActionStartSpyEventArgs()
                {
                    Name      = actionRunInfo.Name,
                    ActionId  = actionRunInfo.ActionId,
                    Context   = scope,
                    Arguments = arguments,
                    StartTime = actionRunInfo.StartDateTime,
                });
            }

            sharedState.CurrentActionId = actionRunInfo.ActionId;
            return(actionRunInfo);
        }
Example #3
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>
        /// <param name="arg1">Argument nr. 1.</param>
        /// <param name="arg2">Argument nr. 2.</param>
        internal static void ExecuteAction <T1, T2>(ISharedState sharedState, string actionName, object scope, Action <T1, T2> action, T1 arg1, T2 arg2)
        {
            ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, new object[] { arg1, arg2 });

            try
            {
                action.Invoke(arg1, arg2);
            }
            catch (Exception exception)
            {
                actionRunInfo.Exception = exception;
                throw;
            }
            finally
            {
                EndAction(actionRunInfo);
            }
        }
Example #4
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>
        /// <param name="arg1">Argument nr. 1.</param>
        /// <param name="arg2">Argument nr. 2.</param>
        /// <param name="arg3">Argument nr. 3.</param>
        /// <param name="arg4">Argument nr. 4.</param>
        /// <param name="arg5">Argument nr. 5.</param>
        /// <param name="arg6">Argument nr. 6.</param>
        /// <param name="arg7">Argument nr. 7.</param>
        /// <param name="arg8">Argument nr. 8.</param>
        /// <param name="arg9">Argument nr. 9.</param>
        /// <param name="arg10">Argument nr. 10.</param>
        /// <param name="arg11">Argument nr. 11.</param>
        /// <param name="arg12">Argument nr. 12.</param>
        /// <param name="arg13">Argument nr. 13.</param>
        /// <param name="arg14">Argument nr. 14.</param>
        /// <param name="arg15">Argument nr. 15.</param>
        /// <param name="arg16">Argument nr. 16.</param>
        internal static void ExecuteAction <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(ISharedState sharedState, string actionName, object scope, Action <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16)
        {
            ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16 });

            try
            {
                action.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
            }
            catch (Exception exception)
            {
                actionRunInfo.Exception = exception;
                throw;
            }
            finally
            {
                EndAction(actionRunInfo);
            }
        }
Example #5
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>

        internal static void ExecuteAction(ISharedState sharedState, string actionName, object scope, Action action)
        {
            ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, Array.Empty <object>());

            try
            {
                action.Invoke();
            }
            catch (Exception exception)
            {
                actionRunInfo.Exception = exception;
                throw;
            }
            finally
            {
                EndAction(actionRunInfo);
            }
        }
Example #6
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>
        /// <param name="arg1">Argument nr. 1.</param>
        /// <param name="arg2">Argument nr. 2.</param>
        /// <param name="arg3">Argument nr. 3.</param>
        /// <param name="arg4">Argument nr. 4.</param>
        /// <param name="arg5">Argument nr. 5.</param>
        /// <param name="arg6">Argument nr. 6.</param>
        /// <param name="arg7">Argument nr. 7.</param>
        internal static void ExecuteAction <T1, T2, T3, T4, T5, T6, T7>(ISharedState sharedState, string actionName, object scope, Action <T1, T2, T3, T4, T5, T6, T7> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
        {
            ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });

            try
            {
                action.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
            }
            catch (Exception exception)
            {
                actionRunInfo.Exception = exception;
                throw;
            }
            finally
            {
                EndAction(actionRunInfo);
            }
        }
Example #7
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>
        /// <param name="arg1">Argument nr. 1.</param>
        /// <param name="arg2">Argument nr. 2.</param>
        /// <param name="arg3">Argument nr. 3.</param>
        /// <param name="arg4">Argument nr. 4.</param>
        /// <param name="arg5">Argument nr. 5.</param>
        /// <param name="arg6">Argument nr. 6.</param>
        /// <param name="arg7">Argument nr. 7.</param>
        /// <param name="arg8">Argument nr. 8.</param>
        /// <param name="arg9">Argument nr. 9.</param>
        /// <param name="arg10">Argument nr. 10.</param>
        /// <param name="arg11">Argument nr. 11.</param>
        /// <param name="arg12">Argument nr. 12.</param>
        /// <param name="arg13">Argument nr. 13.</param>
        /// <param name="arg14">Argument nr. 14.</param>
        /// <param name="arg15">Argument nr. 15.</param>
        /// <param name="arg16">Argument nr. 16.</param>
        internal static void ExecuteAction <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(ISharedState sharedState, string actionName, object scope, Action <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16)
        {
            void innerAction()
            {
                ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16 });

                try
                {
                    action.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
                }
                catch (Exception exception)
                {
                    actionRunInfo.Exception = exception;
                    throw;
                }
                finally
                {
                    EndAction(actionRunInfo);
                }
            }

            if (sharedState.ShouldInvoke)
            {
                var taskScheduler = sharedState.GetTaskScheduler();
                Task.Factory.StartNew(
                    () =>
                {
                    innerAction();
                },
                    CancellationToken.None,
                    TaskCreationOptions.DenyChildAttach,
                    taskScheduler);
            }
            else
            {
                innerAction();
            }
        }
Example #8
0
        /// <summary>
        /// Executes an Action that triggers reaction in all observables in the shared state.
        /// </summary>
        /// <param name="sharedState">The <see cref="ISharedState"/> instance to use.</param>
        /// <param name="actionName">The name of this action.</param>
        /// <param name="scope">The scope of this action.</param>
        /// <param name="action">The action itself.</param>
        /// <param name="arg1">Argument nr. 1.</param>
        internal static void ExecuteAction <T1>(ISharedState sharedState, string actionName, object scope, Action <T1> action, T1 arg1)
        {
            void innerAction()
            {
                ActionRunInfo actionRunInfo = StartAction(sharedState, actionName, scope, new object[] { arg1 });

                try
                {
                    action.Invoke(arg1);
                }
                catch (Exception exception)
                {
                    actionRunInfo.Exception = exception;
                    throw;
                }
                finally
                {
                    EndAction(actionRunInfo);
                }
            }

            if (sharedState.ShouldInvoke)
            {
                var taskScheduler = sharedState.GetTaskScheduler();
                Task.Factory.StartNew(
                    () =>
                {
                    innerAction();
                },
                    CancellationToken.None,
                    TaskCreationOptions.DenyChildAttach,
                    taskScheduler);
            }
            else
            {
                innerAction();
            }
        }