/// <summary> /// Executes the macro routine /// </summary> /// <param name="macro"></param> /// <param name="register"></param> /// <param name="cancellationToken"></param> /// <param name="pauseToken"></param> private void DoExecute(IMacroRoutine macro, IMacroMethodRegister register, CancellationToken cancellationToken, IPauseToken pauseToken) { if (this._depth > 25) throw new StackOverflowException("Recursive depth of the macro exceeded the limit"); var context = new ExecutionContext(this, register, cancellationToken, pauseToken); // Increase the executor depth to prevent recursion this._depth++; for (var repetition = 1; repetition <= macro.Repetitions; repetition++) { // Fire repetition started event if this is the top level if (this._depth == 1) { this.MacroRoutine_RepetitionStarted(context, repetition); } // Execute the actions foreach (var action in macro.Actions) { // Cancel if requested if (cancellationToken.IsCancellationRequested) { return; } // Pause if requested while (pauseToken.PauseRequested && !cancellationToken.IsCancellationRequested) { Thread.Sleep(500); } // Fire action started event if (this._depth == 1) { this.MacroRoutine_OnActionStarted(context, action); } // Execute the action action.Execute(this._actionExecutor, context); // Fire action ended event if (this._depth == 1) { this.MacroRoutine_OnActionEnded(context, action); } } // Fire repetition ended event if (this._depth == 1) { this.MacroRoutine_RepetitionEnded(context, repetition); } } // Reduce the executor depth this._depth--; }
/// <summary> /// Instantiates a new instance of the <see cref="MethodEditor"/> class /// </summary> /// <param name="parentManager"></param> /// <param name="specialCharacters"></param> /// <param name="help"></param> public MethodEditor(MacroManager parentManager, SpecialCharacters specialCharacters, Help help) { InitializeComponent(); this._macroManager = parentManager; this._specialCharacters = specialCharacters; this._help = help; this._methodRegister = new MacroMethodRegister(); }
/// <summary> /// Sets the methods in the form /// </summary> /// <param name="methods"></param> public void SetMethods(IList<IMacroMethod> methods) { this._methodRegister = new MacroMethodRegister(); foreach (var m in methods) { this._methodRegister.Register(m); } this.ClearForm(); this.lstStoredMethods.Items.Clear(); this.lstStoredMethods.Items.AddRange(methods.Select(m => (object) m).ToArray()); }
/// <summary> /// Executes the macro routine async /// </summary> /// <param name="macro"></param> /// <param name="register"></param> /// <param name="cancellationToken"></param> /// <param name="pauseToken"></param> /// <returns></returns> public async Task ExecuteAsync(IMacroRoutine macro, IMacroMethodRegister register, CancellationToken cancellationToken = new CancellationToken(), IPauseToken pauseToken = null) { await Task.Factory.StartNew(() => this.DoExecute(macro, register, cancellationToken, pauseToken), cancellationToken); }
/// <summary> /// Executes the macro routine /// </summary> /// <param name="macro"></param> /// <param name="register"></param> /// <param name="cancellationToken"></param> /// <param name="pauseToken"></param> public void Execute(IMacroRoutine macro, IMacroMethodRegister register, CancellationToken cancellationToken = new CancellationToken(), IPauseToken pauseToken = null) { this.DoExecute(macro, register, cancellationToken, pauseToken); }
/// <summary> /// Instantiates a new instance of the <see cref="MacroValidationContext"/> class /// </summary> /// <param name="macroValidator"></param> /// <param name="macroMethodRegister"></param> public MacroValidationContext(IMacroValidator macroValidator, IMacroMethodRegister macroMethodRegister) { this._macroValidator = macroValidator; this._macroMethodRegister = macroMethodRegister; }
/// <summary> /// Gets whether the macro is valid or not /// </summary> public bool Validate(IMacroMethodRegister methodRegister) { return this.Validate(this.GetMacroActions(), methodRegister); }
/// <summary> /// Gets whether the macro is valid or not /// </summary> /// <param name="actions"></param> /// <param name="methodRegister"></param> /// <returns></returns> public bool Validate(IList<IMacroAction> actions, IMacroMethodRegister methodRegister) { return new MacroValidator(new MacroActionValidator(), methodRegister).Validate(actions).Valid; }
/// <summary> /// Instantiates a new instance of the <see cref="MacroValidator"/> class /// </summary> /// <param name="actionValidator"></param> /// <param name="register"></param> public MacroValidator(IMacroActionValidator actionValidator, IMacroMethodRegister register) { this._actionValidator = actionValidator; this._register = register; this._depth = 0; }
/// <summary> /// Instantiates a new instance of the <see cref="ExecutionContext"/> class /// </summary> /// <param name="routineExecutor"></param> /// <param name="methodRegister"></param> /// <param name="cancellationToken"></param> public ExecutionContext(IMacroRoutineExecutor routineExecutor, IMacroMethodRegister methodRegister, CancellationToken cancellationToken, IPauseToken pauseToken) : this(routineExecutor, methodRegister) { this._cancellationToken = cancellationToken; this._pauseToken = pauseToken; }
/// <summary> /// Instantiates a new instance of the <see cref="ExecutionContext"/> class /// </summary> /// <param name="routineExecutor"></param> /// <param name="methodRegister"></param> public ExecutionContext(IMacroRoutineExecutor routineExecutor, IMacroMethodRegister methodRegister) { this._routineExecutor = routineExecutor; this._methodRegister = methodRegister; }
/// <summary> /// Runs the macro /// </summary> /// <param name="repetitions"></param> /// <param name="actions"></param> /// <param name="register"></param> public void RunMacro(int repetitions, IList<IMacroAction> actions, IMacroMethodRegister register) { if (this._macroExecution != null) { if (this._pauseToken != null && this._pauseToken.PauseRequested) { this.Pause(); } return; } // Return if we're not ready to run if (this._window == null || !this.MacroEditor.Validate(actions, register)) return; // Create the routine and executor var routine = new MacroRoutine(repetitions, actions); var executor = new MacroRoutineExecutor( this._testMode ? (IMacroActionExecutor)new ConsoleMacroActionExecutor() : (IMacroActionExecutor)new WindowMacroActionExecutor(this._window) ); // Wire-up callbacks executor.OnActionEnded += MacroExecution_OnActionEnded; executor.OnActionStarted += MacroExecution_OnActionStarted; executor.OnRepetitionEnded += MacroExecution_OnRepetitionEnded; executor.OnRepetitionStarted += MacroExecution_OnRepetitionStarted; // Create the cancellation and pause token this._cancellationToken = new CancellationTokenSource(); this._pauseToken = new PauseToken(); // Set the max value of progress prgIterationProgress.Minimum = 0; prgIterationProgress.Maximum = repetitions; // Start the execution this._macroExecution = executor.ExecuteAsync(routine, register, this._cancellationToken.Token, this._pauseToken) .ContinueWith(MacroExecution_OnTaskEnded); // Refresh the UI this.RefreshUi(); }