using System; using Azimuth; namespace Glass.PerformanceTests { /// /// A text layout implementation under comparison. Each operation returns a fingerprint of its answer, so a run /// shows where engines disagree. /// public sealed class Engine { public readonly string Name; public readonly Func MeasureWidth; public readonly Func CalculateSize; public readonly Func PlaceGlyphs; /// /// Ignores the operation and every constraint, so scenarios sharing a font and text are the same work. /// public readonly bool ReadsOnlyFontAndText; public Engine(string name, Func measureWidth, Func calculateSize, Func placeGlyphs, bool readsOnlyFontAndText = false) { Name = name; MeasureWidth = measureWidth; CalculateSize = calculateSize; PlaceGlyphs = placeGlyphs; ReadsOnlyFontAndText = readsOnlyFontAndText; } /// /// A single stage of layout, run the same way whatever the operation or constraints. /// public static Engine ForStage(string name, Func run) { return new Engine(name, run, run, run, readsOnlyFontAndText: true); } public Func For(Operation operation) { switch (operation) { case Operation.MeasureWidth: return MeasureWidth; case Operation.CalculateSize: return CalculateSize; case Operation.PlaceGlyphs: return PlaceGlyphs; default: throw new ArgumentOutOfRangeException(nameof(operation), operation, null); } } /// /// Whether this engine does the same work on both scenarios, so measuring one measures the other. /// public bool DoesSameWork(Scenario first, Scenario second) { if (ReadsOnlyFontAndText) { return first.Workload.Font == second.Workload.Font && first.Workload.Text == second.Workload.Text; } return first == second; } } }