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;
}
}
}