// Copyright Epic Games, Inc. All Rights Reserved. using CSVStats; using System; using System.Collections.Generic; using System.Xml.Linq; namespace PerfReportTool { class OptionalString { public OptionalString(string valueIn) { value = valueIn; isSet = true; } public OptionalString() { isSet = false; } public OptionalString(XElement element, string Name, bool IsElement = false, XmlVariableMappings vars = null ) { isSet = false; if (IsElement) { XElement child = element.Element(Name); if (child != null) { value = child.GetValue(vars); isSet = true; } } else { XAttribute child = element.Attribute(Name); if (child != null) { value = element.GetRequiredAttribute(vars, Name); isSet = true; } } } public void InheritFrom(OptionalString baseVersion) { if (!isSet) { isSet = baseVersion.isSet; value = baseVersion.value; } } public bool isSet; public string value; }; class Optional { public Optional(T valueIn) { value = valueIn; isSet = true; } public Optional() { isSet = false; } public Optional(XElement element, string AttributeName, XmlVariableMappings vars = null) { isSet = false; try { if (element.Attribute(AttributeName) != null) { value = element.GetRequiredAttribute(vars, AttributeName); isSet = true; } } catch { } } public void InheritFrom(Optional baseVersion) { if (!isSet) { isSet = baseVersion.isSet; value = baseVersion.value; } } public T value; public bool isSet; }; static class OptionalHelper { public static string GetDoubleSetting(Optional setting, string cmdline) { return (setting.isSet ? (cmdline + setting.value.ToString()) : ""); } public static string GetStringSetting(OptionalString setting, string cmdline) { return (setting.isSet ? (cmdline + setting.value) : ""); } }; class ReportGraph { public ReportGraph(XElement element, XmlVariableMappings vars) { title = element.GetRequiredAttribute(vars, "title"); budget = new Optional(element, "budget", vars); inSummary = element.GetSafeAttribute(vars, "inSummary", false); isInline = element.GetSafeAttribute(vars, "inline", false); parent = element.GetSafeAttribute(vars, "parent"); minFilterStatValue = new Optional(element, "minFilterStatValue", vars); if (!isInline && parent != null) { throw new Exception("Parent can only be specified for inline graphs (inline='1'): " + element.ToString()); } if (isInline) { // If this is an inline graph then just load the settings directly settings = new GraphSettings(element, vars); } } public bool ShouldShow(CsvStats stats) { bool bFoundStat = false; foreach (string statString in settings.statString.value.Split(',')) { List matchingStats = stats.GetStatsMatchingString(statString); if (matchingStats.Count > 0) { bFoundStat = true; break; } } if ( !bFoundStat ) { return false; } if (settings.requiredEvents.isSet) { string[] requiredEvents = settings.requiredEvents.value.Split(','); foreach (string requiredEvent in requiredEvents) { bool bFoundEvent = false; foreach (CsvEvent ev in stats.Events) { if (CsvStats.DoesSearchStringMatch(requiredEvent, ev.Name)) { bFoundEvent = true; break; } } if (!bFoundEvent) { return false; } } } return true; } public string title; public Optional budget; public bool inSummary; public Optional minFilterStatValue; public GraphSettings settings; public bool isInline; public string parent; }; class GraphSettings { public GraphSettings(XElement element, XmlVariableMappings vars = null) { smooth = new Optional(element, "smooth", vars); thickness = new Optional(element, "thickness", vars); minY = new Optional(element, "minY", vars); maxY = new Optional(element, "maxY", vars); // Back-compat support. Case was fixed in PRT 4.242.0 if ( !minY.isSet ) { minY = new Optional(element, "miny", vars); } if (!maxY.isSet) { maxY = new Optional(element, "maxy", vars); } maxAutoMaxY = new Optional(element, "maxAutoMaxY", vars); threshold = new Optional(element, "threshold", vars); averageThreshold = new Optional(element, "averageThreshold", vars); minFilterStatValue = new Optional(element, "minFilterStatValue", vars); minFilterStatName = new OptionalString(element, "minFilterStatName", false, vars); smoothKernelPercent = new Optional(element, "smoothKernelPercent", vars); smoothKernelSize = new Optional(element, "smoothKernelSize", vars); compression = new Optional(element, "compression", vars); width = new Optional(element, "width", vars); height = new Optional(element, "height", vars); stacked = new Optional(element, "stacked", vars); showAverages = new Optional(element, "showAverages", vars); filterOutZeros = new Optional(element, "filterOutZeros", vars); maxHierarchyDepth = new Optional(element, "maxHierarchyDepth", vars); hideStatPrefix = new OptionalString(element, "hideStatPrefix", false, vars); mainStat = new OptionalString(element, "mainStat", false, vars); showEvents = new OptionalString(element, "showEvents", false, vars); requiresDetailedStats = new Optional(element, "requiresDetailedStats", vars); ignoreStats = new OptionalString(element, "ignoreStats", false, vars); statString = new OptionalString(element, "statString", true, vars); //additionalArgs = new OptionalString(element, "additionalArgs", true, vars); statMultiplier = new (element, "statMultiplier", vars); legendAverageThreshold = new Optional(element, "legendAverageThreshold", vars); snapToPeaks = new Optional(element, "snapToPeaks", vars); lineDecimalPlaces = new Optional(element, "lineDecimalPlaces", vars); startEvent = new OptionalString(element, "startEvent", false, vars); startEventOffset = new Optional(element, "startEventOffset", vars); endEvent = new OptionalString(element, "endEvent", false, vars); endEventOffset = new Optional(element, "endEventOffset", vars); requiredEvents = new OptionalString(element, "requiredEvents", false, vars); } public void InheritFrom(GraphSettings baseSettings) { smooth.InheritFrom(baseSettings.smooth); statString.InheritFrom(baseSettings.statString); thickness.InheritFrom(baseSettings.thickness); minY.InheritFrom(baseSettings.minY); maxY.InheritFrom(baseSettings.maxY); maxAutoMaxY.InheritFrom(baseSettings.maxAutoMaxY); threshold.InheritFrom(baseSettings.threshold); averageThreshold.InheritFrom(baseSettings.averageThreshold); minFilterStatValue.InheritFrom(baseSettings.minFilterStatValue); minFilterStatName.InheritFrom(baseSettings.minFilterStatName); smoothKernelSize.InheritFrom(baseSettings.smoothKernelSize); smoothKernelPercent.InheritFrom(baseSettings.smoothKernelPercent); compression.InheritFrom(baseSettings.compression); width.InheritFrom(baseSettings.width); height.InheritFrom(baseSettings.height); //additionalArgs.InheritFrom(baseSettings.additionalArgs); stacked.InheritFrom(baseSettings.stacked); showAverages.InheritFrom(baseSettings.showAverages); filterOutZeros.InheritFrom(baseSettings.filterOutZeros); maxHierarchyDepth.InheritFrom(baseSettings.maxHierarchyDepth); hideStatPrefix.InheritFrom(baseSettings.hideStatPrefix); mainStat.InheritFrom(baseSettings.mainStat); showEvents.InheritFrom(baseSettings.showEvents); requiresDetailedStats.InheritFrom(baseSettings.requiresDetailedStats); statMultiplier.InheritFrom(baseSettings.statMultiplier); ignoreStats.InheritFrom(baseSettings.ignoreStats); legendAverageThreshold.InheritFrom(baseSettings.legendAverageThreshold); snapToPeaks.InheritFrom(baseSettings.snapToPeaks); lineDecimalPlaces.InheritFrom(baseSettings.lineDecimalPlaces); startEvent.InheritFrom(baseSettings.startEvent); startEventOffset.InheritFrom(baseSettings.startEventOffset); endEvent.InheritFrom(baseSettings.endEvent); endEventOffset.InheritFrom(baseSettings.endEventOffset); requiredEvents.InheritFrom(baseSettings.requiredEvents); } public Optional smooth; public OptionalString statString; public Optional thickness; public Optional minY; public Optional maxY; public Optional maxAutoMaxY; public Optional threshold; public Optional averageThreshold; public Optional minFilterStatValue; public OptionalString minFilterStatName; public Optional smoothKernelSize; public Optional smoothKernelPercent; public Optional compression; public Optional width; public Optional height; //public OptionalString additionalArgs; public Optional stacked; public Optional showAverages; public Optional filterOutZeros; public Optional maxHierarchyDepth; public OptionalString hideStatPrefix; public OptionalString mainStat; public OptionalString showEvents; public OptionalString ignoreStats; public Optional statMultiplier; public Optional legendAverageThreshold; public Optional requiresDetailedStats; public Optional snapToPeaks; public Optional lineDecimalPlaces; public OptionalString startEvent; public Optional startEventOffset; public OptionalString endEvent; public Optional endEventOffset; public OptionalString requiredEvents; }; }