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();
}
}
}