Beispiel #1
0
        /// <summary>
        /// Performs the code func inside an undoable period guarded by the command specified. Use this method if the code to run inside the
        /// undoable period is well known and can be wrapped inside a single func. The func codeToExecuteInPeriodFunc is executed once, all
        /// undo/redo logic is done by undo/redo-ing commands which were ran due to state changes caused by codeToExecuteInPeriodFunc.
        /// If you want to run a command again during redo, you should enqueue and run a normal command instead of using this method.
        /// To create an undoable period, you can also call BeginUndoablePeriod and EndUndoablePeriod.
        /// </summary>
        /// <param name="cmd">The CMD.</param>
        /// <param name="codeToExecuteInPeriodFunc">The code to execute in period func.</param>
        public void PerformUndoablePeriod(UndoablePeriodCommand cmd, Action codeToExecuteInPeriodFunc)
        {
            ArgumentVerifier.CantBeNull(cmd, "cmd");
            ArgumentVerifier.CantBeNull(codeToExecuteInPeriodFunc, "codeToExecuteInPeriod");
            // reset before/after do action as BeginUndoablePeriod will execute the command (which is empty) but will still perform the before/after actions
            // resetting them to null will avoid that
            Action beforeDoActionSafe = cmd.BeforeDoAction;
            Action afterDoActionSafe  = cmd.AfterDoAction;

            cmd.BeforeDoAction = null;
            cmd.AfterDoAction  = null;
            try
            {
                ThreadEnter();
                BeginUndoablePeriod(cmd);
                // set them back.
                cmd.BeforeDoAction = beforeDoActionSafe;
                cmd.AfterDoAction  = afterDoActionSafe;
                if (cmd.BeforeDoAction != null)
                {
                    cmd.BeforeDoAction();
                }
                codeToExecuteInPeriodFunc();
                if (cmd.AfterDoAction != null)
                {
                    cmd.AfterDoAction();
                }
                EndUndoablePeriod(cmd);
            }
            finally
            {
                ThreadExit();
            }
        }
Beispiel #2
0
 /// <summary>
 /// Sets the command manager in a special mode where all subsequential commands are tracked inside an UndoablePeriodCommand which, when undone/redone
 /// will not destroy its command queue during undo and won't accept new commands when redone, which is useful when you want to mark a method as an
 /// undoable piece of code and the method creates objects, which can be a problem with a normal command calling the method because the objects created
 /// inside the method are re-created (so you'll get new instances) when the command is redone. If follow up commands work on the instances, redoing these
 /// commands as well causes a problem as they'll work on objects which aren't there.
 /// </summary>
 /// <param name="cmd">The command to use for the undoableperiod.</param>
 public void BeginUndoablePeriod(UndoablePeriodCommand cmd)
 {
     try
     {
         ThreadEnter();
         ArgumentVerifier.CantBeNull(cmd, "cmd");
         EnqueueAndRunCommand(cmd);
     }
     finally
     {
         ThreadExit();
     }
 }
Beispiel #3
0
 /// <summary>
 /// Ends the undoable period started with BeginUndoablePeriod.
 /// </summary>
 /// <param name="cmd">The command used for the undoable period.</param>
 public void EndUndoablePeriod(UndoablePeriodCommand cmd)
 {
     try
     {
         ThreadEnter();
         ArgumentVerifier.CantBeNull(cmd, "cmd");
         // the period has ended, so we've to pop the queue of the period from the stack.
         cmd.PopCommandQueueFromActiveStackIfRequired();
     }
     finally
     {
         ThreadExit();
     }
 }
Beispiel #4
0
 /// <summary>
 /// Performs the code func inside an undoable period guarded by the command specified. Use this method if the code to run inside the
 /// undoable period is well known and can be wrapped inside a single func. The func codeToExecuteInPeriodFunc is executed once, all
 /// undo/redo logic is done by undo/redo-ing commands which were ran due to state changes caused by codeToExecuteInPeriodFunc.
 /// If you want to run a command again during redo, you should enqueue and run a normal command instead of using this method.
 /// To create an undoable period, you can also call BeginUndoablePeriod and EndUndoablePeriod.
 /// </summary>
 /// <param name="cmd">The CMD.</param>
 /// <param name="codeToExecuteInPeriodFunc">The code to execute in period func.</param>
 public void PerformUndoablePeriod(UndoablePeriodCommand cmd, Action codeToExecuteInPeriodFunc)
 {
     try
     {
         ThreadEnter();
         ArgumentVerifier.CantBeNull(cmd, "cmd");
         ArgumentVerifier.CantBeNull(codeToExecuteInPeriodFunc, "codeToExecuteInPeriod");
         BeginUndoablePeriod(cmd);
         if (cmd.BeforeDoAction != null)
         {
             cmd.BeforeDoAction();
         }
         codeToExecuteInPeriodFunc();
         if (cmd.AfterDoAction != null)
         {
             cmd.AfterDoAction();
         }
         EndUndoablePeriod(cmd);
     }
     finally
     {
         ThreadExit();
     }
 }