// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using EpicGames.BuildGraph.Expressions;
using Microsoft.Extensions.Logging;
namespace EpicGames.BuildGraph
{
///
/// Constant values for evaluating the graph
///
public interface IBgGraphConstants
{
///
/// The current stream
///
public BgString Stream { get; }
///
/// The changelist being built
///
public BgInt Change { get; }
///
/// Current code changelist
///
public BgInt CodeChange { get; }
///
/// The current engnine version
///
public (BgInt Major, BgInt Minor, BgInt Patch) EngineVersion { get; }
}
///
/// Specification for a graph in fluent syntax
///
public class BgGraphSpec
{
///
/// Constant properties for evaluating the graph
///
public IBgGraphConstants Constants { get; }
readonly List _options = new List();
readonly List _agentSpecs = new List();
readonly List _aggregateSpecs = new List();
readonly List _labelSpecs = new List();
BgList _diagnosticSpecs = new List();
///
/// Constructor
///
/// Constant values for use during graph evaluation
public BgGraphSpec(IBgGraphConstants constants)
{
Constants = constants;
}
///
/// Adds a boolean option
///
/// Name of the option. Must be unique.
/// Description for the option
/// Default value for the option.
/// Boolean expression
public BgBoolOption AddOption(string name, BgString description, BgBool defaultValue)
{
BgBoolOption option = new BgBoolOption(name, description, defaultValue);
_options.Add(option);
return option;
}
///
/// Adds an integer option
///
/// Name of the option. Must be unique.
/// Description for the option
/// Default value for the option.
/// Integer expression
public BgIntOption AddIntOption(string name, BgString description, BgInt defaultValue)
{
BgIntOption option = new BgIntOption(name, description, defaultValue);
_options.Add(option);
return option;
}
///
/// Adds a string option
///
/// Name of the option. Must be unique.
/// Description for the option
/// Default value for the option.
/// String expression
public BgStringOption AddOption(string name, BgString description, BgString defaultValue)
{
BgStringOption option = new BgStringOption(name, description, defaultValue);
_options.Add(option);
return option;
}
///
/// Adds an enum option
///
/// Type of enum value
/// Name of the option. Must be unique.
/// Description for the option
/// Default value for the option.
/// Enum option
public BgEnumOption AddOption(string name, BgString description, BgEnum defaultValue) where TEnum : struct
{
BgEnumOption option = new BgEnumOption(name, description, defaultValue);
_options.Add(option);
return option;
}
///
/// Adds an option which may be a list of enum values
///
/// Type of enum value
/// Name of the option. Must be unique.
/// Description for the option
/// Default value for the option.
///
public BgEnumListOption AddOption(string name, BgString description, BgList> defaultValue) where TEnum : struct
{
BgEnumListOption option = new BgEnumListOption(name, description, defaultValue);
_options.Add(option);
return option;
}
///
/// Adds a new agent to the graph
///
/// Name of the agent
/// Agent specification object
public BgAgentSpec AddAgent(BgString name)
{
BgAgentSpec agent = new BgAgentSpec(name);
_agentSpecs.Add(agent);
return agent;
}
///
/// Adds a new aggregate to the graph
///
/// Name of the agent
/// Initial set of tokens to include in the aggregate
/// Agent specification object
public BgAggregateSpec AddAggregate(BgString name, BgList outputs)
{
BgAggregateSpec aggregate = new BgAggregateSpec(name, outputs);
_aggregateSpecs.Add(aggregate);
return aggregate;
}
///
/// Adds a new aggregate to the graph
///
/// Name of the agent
/// Initial set of tokens to include in the aggregate
///
/// Agent specification object
public BgAggregateSpec AddAggregate(BgString name, BgList outputs, BgString label)
{
AddLabel(config =>
{
config.DashboardName = label;
config.RequiredNodes = config.RequiredNodes.Add(outputs).Distinct();
});
return AddAggregate(name, outputs);
}
///
/// Adds a new label to the graph
///
/// Callback for configuring the label
/// Label specification object
public BgLabelSpec AddLabel(Action configure)
{
BgLabelConfig config = new BgLabelConfig();
configure(config);
BgLabelSpec labelSpec = new BgLabelSpec(config);
_labelSpecs.Add(labelSpec);
return labelSpec;
}
///
/// Adds a diagnostic to the graph
///
/// Condition for adding the diagnostic to the graph
///
///
public void AddDiagnostic(BgBool condition, LogLevel level, BgString message)
{
BgDiagnosticSpec diagnostic = new BgDiagnosticSpec(level, message);
_diagnosticSpecs = _diagnosticSpecs.AddIf(condition, diagnostic);
}
///
/// Creates a concrete graph from the specifications
///
///
/// New graph instance
public BgGraph CreateGraph(Dictionary options)
{
BgExprContext context = new BgExprContext();
context.Options = options;
BgGraph graph = new BgGraph();
foreach (BgAgentSpec agentSpec in _agentSpecs)
{
agentSpec.AddToGraph(context, graph);
}
foreach (BgAggregateSpec aggregateSpec in _aggregateSpecs)
{
aggregateSpec.AddToGraph(context, graph);
}
foreach (BgDiagnosticSpec diagnosticSpec in _diagnosticSpecs.GetEnumerable(context))
{
diagnosticSpec.AddToGraph(context, graph, null, null);
}
foreach (BgLabelSpec labelSpec in _labelSpecs)
{
labelSpec.AddToGraph(context, graph);
}
return graph;
}
}
}