Files
UnrealEngineUWP/Engine/Source/Programs/UnrealBuildTool/System/ConfigValueTracker.cs
Ben Marsh f143176607 UBT: Add missing copyright notice.
#rb none
#rnx

[CL 6915155 by Ben Marsh in Main branch]
2019-06-10 15:18:44 -04:00

210 lines
6.3 KiB
C#

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tools.DotNETCommon;
namespace UnrealBuildTool
{
/// <summary>
/// Identifier for a config file key, including information about the hierarchy used to read it
/// </summary>
[DebuggerDisplay("{Name}")]
class ConfigDependencyKey : IEquatable<ConfigDependencyKey>
{
/// <summary>
/// The config hierarchy type
/// </summary>
public ConfigHierarchyType Type;
/// <summary>
/// Project directory to read config files from
/// </summary>
public DirectoryReference ProjectDir;
/// <summary>
/// The platform being built
/// </summary>
public UnrealTargetPlatform Platform;
/// <summary>
/// The section name
/// </summary>
public string SectionName;
/// <summary>
/// The key name
/// </summary>
public string KeyName;
/// <summary>
/// Constructor
/// </summary>
/// <param name="Type">The config hierarchy type</param>
/// <param name="ProjectDir">Project directory to read config files from</param>
/// <param name="Platform">The platform being built</param>
/// <param name="SectionName">The section name</param>
/// <param name="KeyName">The key name</param>
public ConfigDependencyKey(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform, string SectionName, string KeyName)
{
this.Type = Type;
this.ProjectDir = ProjectDir;
this.Platform = Platform;
this.SectionName = SectionName;
this.KeyName = KeyName;
}
/// <summary>
/// Construct a key from an archive
/// </summary>
/// <param name="Reader">Archive to read from</param>
public ConfigDependencyKey(BinaryArchiveReader Reader)
{
Type = (ConfigHierarchyType)Reader.ReadInt();
ProjectDir = Reader.ReadDirectoryReference();
Platform = Reader.ReadUnrealTargetPlatform();
SectionName = Reader.ReadString();
KeyName = Reader.ReadString();
}
/// <summary>
/// Writes this key to an archive
/// </summary>
/// <param name="Writer">Archive to write to</param>
public void Write(BinaryArchiveWriter Writer)
{
Writer.WriteInt((int)Type);
Writer.WriteDirectoryReference(ProjectDir);
Writer.WriteUnrealTargetPlatform(Platform);
Writer.WriteString(SectionName);
Writer.WriteString(KeyName);
}
/// <summary>
/// Tests whether this key is equal to another object
/// </summary>
/// <param name="Other">The object to compare to</param>
/// <returns>True if the keys are equal, false otherwise</returns>
public override bool Equals(object Other)
{
return (Other is ConfigDependencyKey) && Equals((ConfigDependencyKey)Other);
}
/// <summary>
/// Tests whether this key is equal to another key
/// </summary>
/// <param name="Other">The key to compare to</param>
/// <returns>True if the keys are equal, false otherwise</returns>
public bool Equals(ConfigDependencyKey Other)
{
return Type == Other.Type && ProjectDir == Other.ProjectDir && Platform == Other.Platform && SectionName == Other.SectionName && KeyName == Other.KeyName;
}
/// <summary>
/// Gets a hash code for this object
/// </summary>
/// <returns>Hash code for the object</returns>
public override int GetHashCode()
{
int Hash = 17;
Hash = (Hash * 31) + Type.GetHashCode();
Hash = (Hash * 31) + ((ProjectDir == null) ? 0 : ProjectDir.GetHashCode());
Hash = (Hash * 31) + Platform.GetHashCode();
Hash = (Hash * 31) + SectionName.GetHashCode();
Hash = (Hash * 31) + KeyName.GetHashCode();
return Hash;
}
}
/// <summary>
/// Stores a list of config key/value pairs that have been read
/// </summary>
class ConfigValueTracker
{
/// <summary>
/// The dependencies list
/// </summary>
Dictionary<ConfigDependencyKey, IReadOnlyList<string>> Dependencies;
/// <summary>
/// Constructor
/// </summary>
public ConfigValueTracker()
{
Dependencies = new Dictionary<ConfigDependencyKey, IReadOnlyList<string>>();
}
/// <summary>
/// Construct an object from an archive on disk
/// </summary>
/// <param name="Reader">Archive to read from</param>
public ConfigValueTracker(BinaryArchiveReader Reader)
{
Dependencies = Reader.ReadDictionary(() => new ConfigDependencyKey(Reader), () => (IReadOnlyList<string>)Reader.ReadList(() => Reader.ReadString()));
}
/// <summary>
/// Write the dependencies object to disk
/// </summary>
/// <param name="Writer">Archive to write to</param>
public void Write(BinaryArchiveWriter Writer)
{
Writer.WriteDictionary(Dependencies, Key => Key.Write(Writer), Value => Writer.WriteList(Value, x => Writer.WriteString(x)));
}
/// <summary>
/// Adds a new configuration value
/// </summary>
/// <param name="Type">The config hierarchy type</param>
/// <param name="ProjectDir">The project directory</param>
/// <param name="Platform">The platform being built</param>
/// <param name="SectionName">Name of the config file section</param>
/// <param name="KeyName">Name of the config file key</param>
/// <param name="Values">Current values for this key</param>
public void Add(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform, string SectionName, string KeyName, IReadOnlyList<string> Values)
{
ConfigDependencyKey Key = new ConfigDependencyKey(Type, ProjectDir, Platform, SectionName, KeyName);
Dependencies[Key] = Values;
}
/// <summary>
/// Checks whether the list of dependencies is still valid
/// </summary>
/// <returns></returns>
public bool IsValid()
{
foreach(KeyValuePair<ConfigDependencyKey, IReadOnlyList<string>> Pair in Dependencies)
{
// Read the appropriate hierarchy
ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(Pair.Key.Type, Pair.Key.ProjectDir, Pair.Key.Platform);
// Get the value(s) associated with this key
IReadOnlyList<string> NewValues;
Hierarchy.TryGetValues(Pair.Key.SectionName, Pair.Key.KeyName, out NewValues);
// Check if they're different
if(Pair.Value == null)
{
if(NewValues != null)
{
return false;
}
}
else
{
if(NewValues == null || !Enumerable.SequenceEqual(Pair.Value, NewValues, StringComparer.Ordinal))
{
return false;
}
}
}
return true;
}
}
}