private static bool LoadConditionsFromCache(ConditionEntry[] defaultEntries, Dictionary <Model, ConditionEntry[]> extraConditionsByModel) { if (File.Exists(CompiledConditionsCacheFilePath)) { Game.LogTrivial("Conditions cache file exists"); CompiledConditionsCacheFile cacheFile = new CompiledConditionsCacheFile(); if (cacheFile.Read(CompiledConditionsCacheFilePath)) { if (cacheFile.CompareXmlFiles(CompiledConditionsCacheFile.GetCurrentXmlFiles())) { List <string> names = new List <string>(); if (defaultEntries != null) { foreach (ConditionEntry entry in defaultEntries) { string name = entry.Name; names.Add(name); } } if (extraConditionsByModel != null) { foreach (KeyValuePair <Model, ConditionEntry[]> extraEntriesPair in extraConditionsByModel) { foreach (ConditionEntry entry in extraEntriesPair.Value) { string name = GetMethodNameFor(extraEntriesPair.Key, entry.Name); names.Add(name); } } } Type type = cacheFile.LoadAssembly().GetType(ConditionCodeClassName); foreach (string name in names) { conditionsByName.Add(name, (ConditionDelegate)type.GetMethod(name).CreateDelegate(typeof(ConditionDelegate))); } Game.LogTrivial("Loaded conditions from cache"); return(true); } else { Game.LogTrivial("There has been changes to the XML files since the cache was made, deleting cache"); File.Delete(CompiledConditionsCacheFilePath); } } else { Game.LogTrivial("Failed to read cache, deleting cache"); File.Delete(CompiledConditionsCacheFilePath); } cacheFile = null; } return(false); }
private static void CompileConditions(ConditionEntry[] defaultEntries, Dictionary <Model, ConditionEntry[]> extraConditionsByModel) { Game.LogTrivial("Compiling conditions"); StringBuilder methods = new StringBuilder(); List <string> entriesNames = new List <string>(); if (defaultEntries != null) { foreach (ConditionEntry entry in defaultEntries) { string name = entry.Name; methods.AppendFormat(ConditionMethodCodeTemplate, entry.Name, entry.Code); entriesNames.Add(name); } } if (extraConditionsByModel != null) { foreach (KeyValuePair <Model, ConditionEntry[]> extraEntriesPair in extraConditionsByModel) { foreach (ConditionEntry entry in extraEntriesPair.Value) { string name = GetMethodNameFor(extraEntriesPair.Key, entry.Name); methods.AppendFormat(ConditionMethodCodeTemplate, name, entry.Code); entriesNames.Add(name); } } } string code = String.Format(ConditionBaseCodeTemplate, methods.ToString()); Game.LogTrivialDebug(code); CompilerParameters parameters = new CompilerParameters(); parameters.IncludeDebugInformation = false; parameters.GenerateInMemory = false; parameters.GenerateExecutable = false; parameters.CompilerOptions = "/optimize /platform:x64"; parameters.ReferencedAssemblies.AddRange(new[] { "mscorlib.dll", "System.dll", "System.Core.dll", "System.Dynamic.dll", "System.Windows.Forms.dll", "System.Drawing.dll", "Microsoft.CSharp.dll", typeof(Vehicle).Assembly.Location }); CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); if (results.Errors.HasErrors) { Game.LogTrivial(" Compilation failed"); Game.LogTrivial(" Errors:"); foreach (CompilerError e in results.Errors) { Game.LogTrivial(" " + e.ToString()); } } else { Type type = results.CompiledAssembly.GetType(ConditionCodeClassName); foreach (string name in entriesNames) { conditionsByName.Add(name, (ConditionDelegate)type.GetMethod(name).CreateDelegate(typeof(ConditionDelegate))); } Game.LogTrivial("Conditions compiled, saving to cache"); new CompiledConditionsCacheFile(CompiledConditionsCacheFile.GetCurrentXmlFiles(), results.CompiledAssembly).Write(CompiledConditionsCacheFilePath); } }