// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) 2014 OxyPlot contributors
//
// --------------------------------------------------------------------------------------------------------------------
namespace ExampleLibrary
{
using System;
using System.Collections.Generic;
using System.Reflection;
using ExampleLibrary.Utilities;
using OxyPlot;
///
/// Provides information about an example.
///
public class ExampleInfo
{
///
/// The method to invoke.
///
private readonly MethodInfo method;
///
/// Indicates whether this instance was already initialized.
///
private bool initialized;
///
/// The un-modified example.
///
private Example Example;
///
/// The examples for this example info.
///
private Dictionary examples;
///
/// The options supported by this example.
///
private ExampleFlags exampleSupport;
///
/// Initializes a new instance of the class.
///
/// The category.
/// The title.
/// The tags.
/// The method.
/// A value indiciating whether the example should be excluded from automated tests.
public ExampleInfo(string category, string title, string[] tags, MethodInfo method, bool excludeFromAutomatedTests)
{
this.Category = category;
this.Title = title;
this.Tags = tags;
this.method = method;
this.ExcludeFromAutomatedTests = excludeFromAutomatedTests;
}
///
/// Gets the category.
///
///
/// The category.
///
public string Category { get; }
///
/// Gets the code.
///
///
/// The code.
///
public string Code => this.PlotModel?.ToCode();
///
/// Gets a value indicating whether the plot model is reversible.
///
public bool IsReversible
{
get
{
this.EnsureInitialized();
return exampleSupport.HasFlag(ExampleFlags.Reverse);
}
}
///
/// Gets a value indicating whether the plot model is transposable.
///
public bool IsTransposable
{
get
{
this.EnsureInitialized();
return exampleSupport.HasFlag(ExampleFlags.Transpose);
}
}
///
/// Gets the code for the example with the given flags.
///
/// The flags for the example.
/// Code that produces the example.
/// Ignores unsupported flags.
public string GetCode(ExampleFlags flags)
{
return this.GetModel(flags)?.ToCode();
}
///
/// Gets the for the example with the given flags.
///
/// The flags for the example.
/// The .
/// Ignores unsupported flags.
public PlotModel GetModel(ExampleFlags flags)
{
return this.GetExample(flags).Model;
}
///
/// Gets the for the example with the given flags.
///
/// The flags for the example.
/// The .
/// Ignores unsupported flags.
public IPlotController GetController(ExampleFlags flags)
{
return this.GetExample(flags).Controller;
}
///
/// Gets the with the given flags.
///
/// The flags for the example.
/// The .
/// Ignores unsupported flags.
private Example GetExample(ExampleFlags flags)
{
this.EnsureInitialized();
// ignore flags we don't support
flags = FilterFlags(flags);
if (!examples.TryGetValue(flags, out var example))
{
example = GetDefaultExample();
if (flags.HasFlag(ExampleFlags.Transpose))
{
example.Model.Transpose();
}
if (flags.HasFlag(ExampleFlags.Reverse))
{
example.Model.ReverseAllAxes();
}
examples[flags] = example;
}
return example;
}
///
/// Gets the plot controller for the default example.
///
///
/// The plot controller.
///
public IPlotController PlotController
{
get
{
this.EnsureInitialized();
return this.Example.Controller;
}
}
///
/// Gets the plot model for the default example.
///
///
/// The plot model.
///
public PlotModel PlotModel
{
get
{
this.EnsureInitialized();
return this.Example.Model;
}
}
///
/// Gets the tags.
///
///
/// The tags.
///
public string[] Tags { get; }
///
/// Gets a value indiciating whether this example should be excluded from automated tests.
///
///
/// true if the example should be excluded from automated tests, otherwise false.
///
public bool ExcludeFromAutomatedTests { get; }
///
/// Gets the title.
///
///
/// The title.
///
public string Title { get; }
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
public override string ToString()
{
return this.Title;
}
///
/// Prepares from the given parameters.
///
/// Whether to set the flag.
/// Whether to set the flag.
/// The .
public static ExampleFlags PrepareFlags(bool transpose, bool reverse)
{
var flags = (ExampleFlags)0;
if (transpose)
{
flags |= ExampleFlags.Transpose;
}
if (reverse)
{
flags |= ExampleFlags.Reverse;
}
return flags;
}
///
/// Initializes this instance if it is not already initialized.
///
private void EnsureInitialized()
{
if (this.initialized)
{
return;
}
this.initialized = true;
this.examples = new Dictionary();
this.Example = GetDefaultExample();
this.exampleSupport = PrepareFlags(this.Example.Model?.IsTransposable() == true, this.Example.Model?.IsReversible() == true);
// remember the 'default' model: loads the transposed/reversed ones as we need them
this.examples.Add(PrepareFlags(false, false), this.Example);
}
///
/// Gets a new instance of the default example.
///
/// An .
private Example GetDefaultExample()
{
var result = this.method.Invoke(null, null);
if (result is null)
{
return new Example(null, null);
}
if (result is PlotModel plotModel)
{
return new Example(plotModel, null);
}
else if (result is Example example)
{
return example;
}
throw new Exception($"Unsupport type returned by example method for example {Category} > {Title}: {result.GetType().FullName}.");
}
///
/// Filters unsupported flags from the given flags.
///
/// The original set of flags.
/// The filtered flags.
private ExampleFlags FilterFlags(ExampleFlags flags)
{
return flags & exampleSupport;
}
}
}