using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using bottlenoselabs.C2CS.Runtime; using static Tracy.PInvoke; public static class Profiler { // Plot names need to be cached for the lifetime of the program // seealso Tracy docs section 3.1 private static readonly Dictionary PlotNameCache = new Dictionary(); /// /// Begins a new and returns the handle to that zone. Time /// spent inside a zone is calculated by Tracy and shown in the profiler. A zone is /// ended when is called either automatically via /// disposal scope rules or by calling it manually. /// /// A custom name for this zone. /// Is the zone active. An inactive zone wont be shown in the profiler. /// An RRGGBB color code that Tracy will use to color the zone in the profiler. /// Arbitrary text associated with this zone. /// /// The source code line number that this zone begins at. /// If this param is not explicitly assigned the value will provided by . /// /// /// The source code file path that this zone begins at. /// If this param is not explicitly assigned the value will provided by . /// /// /// The source code member name that this zone begins at. /// If this param is not explicitly assigned the value will provided by . /// /// public static ProfilerZone BeginZone( string zoneName = null, bool active = true, uint color = 0, string text = null, [CallerLineNumber] uint lineNumber = 0, [CallerFilePath] string filePath = null, [CallerMemberName] string memberName = null) { using var filestr = GetCString(filePath, out var fileln); using var memberstr = GetCString(memberName, out var memberln); using var namestr = GetCString(zoneName, out var nameln); var srcLocId = TracyAllocSrclocName(lineNumber, filestr, fileln, memberstr, memberln, namestr, nameln, color); var context = TracyEmitZoneBeginAlloc(srcLocId, active ? 1 : 0); if (text != null) { using var textstr = GetCString(text, out var textln); TracyEmitZoneText(context, textstr, textln); } return new ProfilerZone(context); } /// /// Configure how Tracy will display plotted values. /// /// /// Name of the plot to configure. Each represents a unique plot. /// /// /// Changes how the values in the plot are presented by the profiler. /// /// /// Determines whether the plot will be displayed as a staircase or will smoothly change between plot points /// /// /// If the the area below the plot will not be filled with a solid color. /// /// /// An RRGGBB color code that Tracy will use to color the plot in the profiler. /// public static void PlotConfig(string name, PlotType type = PlotType.Number, bool step = false, bool fill = true, uint color = 0) { var namestr = GetPlotCString(name); TracyEmitPlotConfig(namestr, (int)type, step ? 1 : 0, fill ? 1 : 0, color); } /// /// Add a value to a plot. /// public static void Plot(string name, double val) { var namestr = GetPlotCString(name); TracyEmitPlot(namestr, val); } /// /// Add a value to a plot. /// public static void Plot(string name, int val) { var namestr = GetPlotCString(name); TracyEmitPlotInt(namestr, val); } /// /// Add a value to a plot. /// public static void Plot(string name, float val) { var namestr = GetPlotCString(name); TracyEmitPlotFloat(namestr, val); } private static CString GetPlotCString(string name) { if(!PlotNameCache.TryGetValue(name, out var plotCString)) { plotCString = CString.FromString(name); PlotNameCache.Add(name, plotCString); } return plotCString; } /// /// Emit a string that will be included along with the trace description. /// /// /// Viewable in the Info tab in the profiler. /// public static void AppInfo(string appInfo) { using var infostr = GetCString(appInfo, out var infoln); TracyEmitMessageAppinfo(infostr, infoln); } /// /// Emit the top-level frame marker. /// /// /// Tracy Cpp API and docs refer to this as the FrameMark macro. /// public static void EmitFrameMark() { TracyEmitFrameMark(null); } /// /// Is the app connected to the external profiler? /// /// public static bool IsConnected() { return TracyConnected() != 0; } /// /// Creates a for use by Tracy. Also returns the /// length of the string for interop convenience. /// public static CString GetCString(string fromString, out ulong clength) { if (fromString == null) { clength = 0; return new CString(""); } clength = (ulong)fromString.Length; return CString.FromString(fromString); } public enum PlotType { /// /// Values will be displayed as plain numbers. /// Number = 0, /// /// Treats the values as memory sizes. Will display kilobytes, megabytes, etc. /// Memory = 1, /// /// Values will be displayed as percentage (with value 100 being equal to 100%). /// Percentage = 2, } }