JD2022-TU1/main/tools/apps/Packager/Tasks/TaskIO.cs

201 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using JD.Core.ProjectManaging;
using Packager.BuildConfigurations;
using Packager.Parameters;
namespace Packager.Tasks
{
public enum IOCardinality
{
Single,
Multi
}
public enum IOType
{
File,
Directory,
GUID,
String,
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public sealed class OutputAttribute : Attribute
{
public readonly string Name;
public readonly IOType Type;
public OutputAttribute(string name, IOType type)
{
Name = name;
Type = type;
}
public override string ToString()
{
return Name;
}
}
[DataContract(Namespace = "")]
public class IORef
{
private string _refName;
[DataMember(EmitDefaultValue = false)]
public string Task { get; set; }
[DataMember]
public string RefName
{
get
{
if (_refName != null && _refName.StartsWith("$(DataRoot)"))
{
return DataPath.GetAbsolutePath(_refName.Substring("$(DataRoot)".Length));
}
return _refName;
}
set
{
string relative;
if (!string.IsNullOrEmpty(value) &&
(DataPath.ExtractRelativePath(value, out relative) ||
// To keep only during the transition to relative paths.
DataPath.ExtractRelativePath(ProjectManager.Instance.CurrentProject.DataPath, value, out relative)))
{
value = @"$(DataRoot)\" + relative;
}
_refName = value;
}
}
[DataMember(EmitDefaultValue = false)]
public bool Distributed { get; set; }
// We need a default constructor for the serialization
public IORef()
{
}
public IORef(string refFileName, bool distributed = false)
{
Task = null;
RefName = refFileName;
Distributed = distributed;
}
public IORef(string refName, string taskName, bool distributed = false)
{
Task = taskName;
RefName = refName;
Distributed = distributed;
}
private string ResolveMacro(BuildConfiguration profile, string name)
{
if (string.IsNullOrEmpty(name)) return name;
name = Regex.Replace(name, @"\$\(Platform\)", profile.PlatformList.First(), RegexOptions.IgnoreCase);
name = Regex.Replace(name, @"\$\(DataRoot\)", DataPath.Value, RegexOptions.IgnoreCase);
return name;
}
public string[] Resolve(BuildConfiguration profile, int step, out int total)
{
if (Task == null)
{
total = 1;
return new[] { ResolveMacro(profile, RefName) };
}
var refTask = profile.Tasks[Task];
var outputs = refTask.GetOutputs(RefName);
total = outputs.Length;
return Distributed && total > 1 ? new[] { outputs[step] } : outputs;
}
public bool IsValid(TaskList taskList, int maxIndex)
{
if (Task == null)
{
return !string.IsNullOrEmpty(RefName);
}
var refTask = taskList[Task];
if (refTask == null || refTask.OrderId >= maxIndex)
{
return false;
}
var outputs = refTask.GetOutputsDesc();
return outputs.Any(o => o.Name == RefName);
}
}
[Flags]
public enum InputFlags
{
None,
Optional
}
[AttributeUsage(AttributeTargets.Property)]
public sealed class InputAttribute : Attribute
{
public readonly string DisplayName;
public readonly IOCardinality Cardinality;
public readonly IOType Type;
public InputFlags Flags { get; set; }
public InputAttribute(string displayName, IOCardinality cardinality, IOType type)
{
DisplayName = displayName;
Cardinality = cardinality;
Type = type;
Flags = InputFlags.None;
}
}
public class InputDesc
{
public string DisplayName { get; private set; }
public IOCardinality Cardinality { get; private set; }
public IOType Type { get; private set; }
public InputFlags Flags { get; private set; }
public string Id { get; private set; }
public Reference Input { get; private set; }
public Task OwnerTask { get; private set; }
public InputDesc(Task owner, string id, InputAttribute attr, Reference input)
{
DisplayName = attr.DisplayName;
Cardinality = attr.Cardinality;
Type = attr.Type;
Flags = attr.Flags;
OwnerTask = owner;
Id = id;
Input = input;
}
}
public class TaskIO : Dictionary<string, List<string>>
{
}
}