private void DrawModsProfiler(Listing_Extended lister, Settings settings) { lister.LabelColored("Profile Mods", TitleLabelColor); Rect buttonRect1 = lister.GetRect(Text.LineHeight), buttonRect2 = buttonRect1; buttonRect2.width = buttonRect1.width /= 2; buttonRect2.x = buttonRect1.xMax; if (Widgets.ButtonText(buttonRect1, "Get mods")) { settings.profileMods = String.Join("\n", LoadedModManager.RunningModsListForReading.Select(x => Path.GetFileName(x.RootDir)).ToArray()); } if (!settings.profileMods.IsNullOrEmpty()) { lister.CheckboxLabeled("Allow Core assembly", ref settings.allowCoreAsm); if (Widgets.ButtonText(buttonRect2, $"Profile mods")) { PatchHandler.Initialize(); var mods = settings.profileMods.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); Profiler.Logger.LogOperation("ModsProfiling", () => Patcher.ProfileMods(mods.ToList())); } } settings.profileMods = lister.TextAreaFocusControl("ModsProfilerField", settings.profileMods, 5, ref modsScrollPos); lister.Gap(20f); }
private void DrawInstanceProfiler(Listing_Extended lister, Settings settings) { lister.LabelColored("Profile Harmony Instances", TitleLabelColor); Rect buttonRect1 = lister.GetRect(Text.LineHeight), buttonRect2 = buttonRect1, buttonRect3 = buttonRect1; buttonRect2.width = buttonRect3.width = buttonRect1.width = buttonRect1.width / 3; buttonRect2.x = buttonRect1.xMax; buttonRect3.x = buttonRect2.xMax; if (Widgets.ButtonText(buttonRect1, "Get instances")) { settings.profileInstances = String.Join("\n", HarmonyMain.GetAllHarmonyInstances().ToArray()); } if (!settings.profileInstances.IsNullOrEmpty()) { lister.CheckboxLabeled("Allow transpiled methods(slow patching)", ref settings.allowTranspiledMethods); if (Widgets.ButtonText(buttonRect2, $"Profile instances")) { PatchHandler.Initialize(); var instances = settings.profileInstances.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); Profiler.Logger.LogOperation("PatchesProfiling", () => Patcher.ProfileHarmonyPatches(instances, true, !settings.allowTranspiledMethods)); } if (Widgets.ButtonText(buttonRect3, "Unpatch instances")) { var instances = settings.profileInstances.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); Profiler.Logger.LogOperation("UnpatchInstances", () => Patcher.UnpatchInstances(instances)); } } settings.profileInstances = lister.TextAreaFocusControl("InstancesProfilerField", settings.profileInstances, 5, ref instancesScrollPos); lister.Gap(20f); }
private void DrawOther(Listing_Extended lister, Settings settings) { if (lister.ButtonText($"Results", Text.LineHeight)) { Find.WindowStack.Add(new FloatMenu(new List <FloatMenuOption> { new FloatMenuOption("Dump to SLK", () => { List <StopwatchRecord> result = PatchHandler.GetProfileRecordsSorted(); FS.WriteAllText($"Profiler_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.slk", result.DumpToSlk()); }), new FloatMenuOption("Dump to CSV", () => { List <StopwatchRecord> result = PatchHandler.GetProfileRecordsSorted(); FS.WriteAllText($"Profiler_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.csv", result.DumpToCsv()); }), new FloatMenuOption("Reset results", () => { PatchHandler.Reset(); }), })); } if (lister.ButtonText($"Tools / Other", Text.LineHeight)) { IEnumerable <FloatMenuOption> getOptions() { yield return(new FloatMenuOption($"Enable disabled methods: {PatchDisabler.DisabledCount}", () => { PatchDisabler.EnableAllDisabled(); })); yield return(new FloatMenuOption("Dump all harmony patches", () => { FS.WriteAllText("HarmonyPatches.txt", HarmonyMain.AllHarmonyPatchesDump()); FS.WriteAllText("HarmonyPatches-Conflicts.txt", HarmonyMain.CanConflictHarmonyPatchesDump()); })); // if (DubsProfilerReset.CanUnpatch()) // { // yield return new FloatMenuOption("Reset DubsPerfomanceAnalyzer patches", DubsProfilerReset.ResetProfiler); // } } Find.WindowStack.Add(new FloatMenu(new List <FloatMenuOption>(getOptions()))); } // Method resolver. Handle string >= 3 chars. Results show after 2 sec. when str not changed. Has filter AND, example: 'pawn tick' => Verse.Pawn:Tick { var prevStr = _methodResolver; Rect labelRect = lister.GetRect(Text.LineHeight), textEntyRect = labelRect; float width = labelRect.width; labelRect.width = width / 3; textEntyRect.width = 2 * width / 3; textEntyRect.x = labelRect.xMax; Widgets.Label(labelRect, $"Method resolver"); _methodResolver = Widgets.TextArea(textEntyRect, _methodResolver); if (!String.IsNullOrWhiteSpace(_methodResolver) && _methodResolver.Length >= 4) { if (!prevStr.Equals(_methodResolver)) { _methodResolverInputTimer = Stopwatch.StartNew(); } } else { _methodResolverInputTimer = null; } if (_methodResolverInputTimer != null && _methodResolverInputTimer.ElapsedMilliseconds > 1500) { var strLower = _methodResolver.ToLower(); var arrFilters = strLower.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); var allMethods = Utils.GetAllMethods(); IEnumerable <string> filterMethods() { if (_methodResolverCache == null) { _methodResolverCache = allMethods .OrderBy(x => x) .Select(x => (x, x.ToLower())) .ToList(); } foreach (var m in (from tuple in _methodResolverCache where arrFilters.All(x => tuple.nameLower.Contains(x)) select tuple)) { yield return(m.name); } } IEnumerable <FloatMenuOption> makeVariants(int maxResult) { foreach (var m in filterMethods().OrderBy(x => x)) { if (maxResult-- < 0) { break; } yield return(new FloatMenuOption(m, () => _methodResolver = m)); } } Find.WindowStack.Add(new FloatMenu(new List <FloatMenuOption>(makeVariants(20)))); _methodResolverInputTimer = null; } } lister.CheckboxLabeled("CRASH DEBUG", ref settings.debug); lister.Gap(20f); }
private void DrawCustomProfiler(Listing_Extended lister, Settings settings) { lister.LabelColored("Profile Custom(Methods,Classes,Namespaces)", TitleLabelColor); Rect buttonRect1 = lister.GetRect(Text.LineHeight), buttonRect2 = buttonRect1; buttonRect2.width = buttonRect1.width /= 2; buttonRect2.x = buttonRect1.xMax; if (Widgets.ButtonText(buttonRect1, "Profile all dlls")) { PatchHandler.Initialize(); var methods = new HashSet <string>(); var modDllNames = Utils.GetAllModsDll(); //File.WriteAllLines("dsdsd", modDllNames.ToArray()); foreach (var modDllName in modDllNames) { //Log.Warning($"[dll] {modDllName}"); foreach (var @class in Utils.GetClassesFromDll(modDllName)) { methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods); } } Profiler.Logger.LogOperation("DllProfiling", () => Patcher.ProfileMethods(methods.ToArray())); } //if (!settings.profileCustom.IsNullOrEmptyOrEqual(Settings.CustomExampleStr)) { lister.CheckboxLabeled("Allow Core assembly", ref settings.allowCoreAsm); lister.CheckboxLabeled("Allow class inherited methods", ref settings.allowInheritedMethods); if (Widgets.ButtonText(buttonRect2, $"Profile custom methods")) { PatchHandler.Initialize(); var methods = new HashSet <string>(); var list = settings.profileCustom.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var s in list) { // it's method if (s.Contains(":")) { methods.Add(s); } else if (s.EndsWith(".dll")) { string dllName = s.Replace(".dll", ""); foreach (var @class in Utils.GetClassesFromDll(dllName)) { methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods); } } else { Type type = AccessTools.TypeByName(s); // it's class if (type?.IsClass ?? false) { methods.AddDefMethodsAdvanced(type, settings.allowCoreAsm, !settings.allowInheritedMethods); } else // parse namespace { var classes = Utils.GetClassesFromNamespace(s); if (!classes.Any()) { Log.Error($"[HarmonyProfiler] Found 0 results for namespace:'{s}'"); } foreach (var @class in classes) { methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods); } } } } Profiler.Logger.LogOperation("CustomProfiling", () => Patcher.ProfileMethods(methods.ToArray())); } } settings.profileCustom = lister.TextAreaFocusControl("CustomProfilerField", settings.profileCustom, 5, ref customScrollPos); lister.Gap(20f); }