public void Run() { int totalRulesToRun = rules.SelectMany(p => p.Value).Count(); if (totalRulesToRun == 0) { Log.Warning("No rules loaded, nothing to do."); return; } using (var progress = Display.StartProgress("Executing rules")) { int run = 0; foreach (var pluginFileName in rules.Keys) { foreach (var rule in rules[pluginFileName]) { Log.Info("Executing rule {0}", rule); progress.Update(run++, totalRulesToRun, "{0}", rule); // Run rule var runner = new RuleRunner(this, rule); try { runner.Run(); } #if !DEBUG catch (Exception ex) { if (ex is CompiledRuleAssertException) { Log.Error("Assertion failed while executing rule {0} with message: {1}", rule, ex.Message); } else { Log.Error("Error occured while executing rule {0} with message: {1}", rule, ex.Message); } Log.Fine(ex.ToString()); // Determine were the exception occured var stackTrace = new StackTrace(ex, true); var frame = stackTrace.GetFrames().Where(f => f.GetMethod().DeclaringType.Namespace == "Patcher.Rules.Compiled.Generated").FirstOrDefault(); if (frame != null) { Display.ShowProblems("Runtime Error", ex.ToString(), new Problem() { Message = string.Format("{0}: {1}", ex.GetType().FullName, ex.Message), File = DataFile.GetRelativePath(frame.GetFileName()), Line = frame.GetFileLineNumber(), Solution = RuleRunner.GetRuntimeErrorHint(ex) }); } var choice = Display.Choice("Continue executing rules?", ChoiceOption.Ok, ChoiceOption.Cancel); if (choice == ChoiceOption.Cancel) { Log.Warning("Rule execution has been aborted."); throw new UserAbortException("Rule execution has been aborted by the user."); } else { Log.Warning("The last rule has not been fully applied."); continue; } } #endif finally { Display.ClearProblems(); } Log.Info("Rule completed with {0} updates and {1} inserts", runner.Updated, runner.Created); } // After all rules of a plugin were run // Clear tags Tags.Clear(); } } }