Files
UnrealEngineUWP/Engine/Source/Programs/Shared/EpicGames.BuildGraph/BgNodeDef.cs
Ben Marsh c32dfb7acb BuildGraph: Move option classes alongside their underlying types, and fix up a lot of namespaces.
#preflight none

[CL 20819013 by Ben Marsh in ue5-main branch]
2022-06-24 19:08:20 -04:00

221 lines
7.2 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using System.Xml;
using EpicGames.Core;
using EpicGames.BuildGraph.Expressions;
namespace EpicGames.BuildGraph
{
/// <summary>
/// Reference to an output tag from a particular node
/// </summary>
public class BgNodeOutput
{
/// <summary>
/// The node which produces the given output
/// </summary>
public BgNodeDef ProducingNode { get; }
/// <summary>
/// Name of the tag
/// </summary>
public string TagName { get; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="inProducingNode">Node which produces the given output</param>
/// <param name="inTagName">Name of the tag</param>
public BgNodeOutput(BgNodeDef inProducingNode, string inTagName)
{
ProducingNode = inProducingNode;
TagName = inTagName;
}
/// <summary>
/// Returns a string representation of this output for debugging purposes
/// </summary>
/// <returns>The name of this output</returns>
public override string ToString()
{
return String.Format("{0} [{1}]", TagName, ProducingNode.Name);
}
}
/// <summary>
/// Defines a node, a container for tasks and the smallest unit of execution that can be run as part of a build graph.
/// </summary>
public class BgNodeDef
{
/// <summary>
/// The node's name
/// </summary>
public string Name { get; }
/// <summary>
/// Array of inputs which this node requires to run
/// </summary>
public IReadOnlyList<BgNodeOutput> Inputs { get; }
/// <summary>
/// Array of outputs produced by this node
/// </summary>
public IReadOnlyList<BgNodeOutput> Outputs { get; }
/// <summary>
/// Nodes which this node has input dependencies on
/// </summary>
public IReadOnlyList<BgNodeDef> InputDependencies { get; set; }
/// <summary>
/// Nodes which this node needs to run after
/// </summary>
public IReadOnlyList<BgNodeDef> OrderDependencies { get; set; }
/// <summary>
/// Tokens which must be acquired for this node to run
/// </summary>
public IReadOnlyList<FileReference> RequiredTokens { get; }
/// <summary>
/// List of email addresses to notify if this node fails.
/// </summary>
public HashSet<string> NotifyUsers { get; set; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
/// <summary>
/// If set, anyone that has submitted to one of the given paths will be notified on failure of this node
/// </summary>
public HashSet<string> NotifySubmitters { get; set; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
/// <summary>
/// Whether to start this node as soon as its dependencies are satisfied, rather than waiting for all of its agent's dependencies to be met.
/// </summary>
public bool RunEarly { get; set; } = false;
/// <summary>
/// Whether to ignore warnings produced by this node
/// </summary>
public bool NotifyOnWarnings { get; set; } = true;
/// <summary>
/// Custom annotations for this node
/// </summary>
public Dictionary<string, string> Annotations { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Diagnostics to output if executing this node
/// </summary>
public List<BgDiagnosticDef> Diagnostics { get; } = new List<BgDiagnosticDef>();
/// <summary>
/// Constructor
/// </summary>
/// <param name="name">The name of this node</param>
/// <param name="inputs">Inputs that this node depends on</param>
/// <param name="outputNames">Names of the outputs that this node produces</param>
/// <param name="inputDependencies">Nodes which this node is dependent on for its inputs</param>
/// <param name="orderDependencies">Nodes which this node needs to run after. Should include all input dependencies.</param>
/// <param name="requiredTokens">Optional tokens which must be required for this node to run</param>
public BgNodeDef(string name, IReadOnlyList<BgNodeOutput> inputs, IReadOnlyList<string> outputNames, IReadOnlyList<BgNodeDef> inputDependencies, IReadOnlyList<BgNodeDef> orderDependencies, IReadOnlyList<FileReference> requiredTokens)
{
Name = name;
Inputs = inputs;
List<BgNodeOutput> allOutputs = new List<BgNodeOutput>();
allOutputs.Add(new BgNodeOutput(this, "#" + Name));
allOutputs.AddRange(outputNames.Where(x => String.Compare(x, Name, StringComparison.InvariantCultureIgnoreCase) != 0).Select(x => new BgNodeOutput(this, x)));
Outputs = allOutputs.ToArray();
InputDependencies = inputDependencies;
OrderDependencies = orderDependencies;
RequiredTokens = requiredTokens;
}
/// <summary>
/// Returns the default output for this node, which includes all build products
/// </summary>
public BgNodeOutput DefaultOutput => Outputs[0];
/// <summary>
/// Determines the minimal set of direct input dependencies for this node to run
/// </summary>
/// <returns>Sequence of nodes that are direct inputs to this node</returns>
public IEnumerable<BgNodeDef> GetDirectInputDependencies()
{
HashSet<BgNodeDef> directDependencies = new HashSet<BgNodeDef>(InputDependencies);
foreach (BgNodeDef inputDependency in InputDependencies)
{
directDependencies.ExceptWith(inputDependency.InputDependencies);
}
return directDependencies;
}
/// <summary>
/// Determines the minimal set of direct order dependencies for this node to run
/// </summary>
/// <returns>Sequence of nodes that are direct order dependencies of this node</returns>
public IEnumerable<BgNodeDef> GetDirectOrderDependencies()
{
HashSet<BgNodeDef> directDependencies = new HashSet<BgNodeDef>(OrderDependencies);
foreach (BgNodeDef orderDependency in OrderDependencies)
{
directDependencies.ExceptWith(orderDependency.OrderDependencies);
}
return directDependencies;
}
/// <summary>
/// Returns the name of this node
/// </summary>
/// <returns>The name of this node</returns>
public override string ToString()
{
return Name;
}
}
/// <summary>
/// Node constructed from a bytecode expression
/// </summary>
public class BgExpressionNodeDef : BgNodeDef
{
/// <summary>
/// Agent declaring this node
/// </summary>
public BgAgentDef Agent { get; }
/// <summary>
/// Offset in the bytecode of this node. Used to lookup method calling information.
/// </summary>
public BgMethod Method { get; }
/// <summary>
/// Expression arguments to the method
/// </summary>
public IReadOnlyList<object> Arguments { get; }
/// <summary>
/// Labels to add this node to
/// </summary>
public IReadOnlyList<BgLabelDef> Labels { get; }
/// <summary>
/// Constructor
/// </summary>
public BgExpressionNodeDef(BgAgentDef agent, string name, BgMethod method, IReadOnlyList<object> arguments, IReadOnlyList<BgNodeOutput> inputs, IReadOnlyList<string> outputNames, IReadOnlyList<BgNodeDef> inputDependencies, IReadOnlyList<BgNodeDef> orderDependencies, IReadOnlyList<FileReference> requiredTokens, IReadOnlyList<BgLabelDef> labels)
: base(name, inputs, outputNames, inputDependencies, orderDependencies, requiredTokens)
{
Agent = agent;
Method = method;
Arguments = arguments;
Labels = labels;
}
}
}