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