public Task<BuildInstance> Start(string name, bool tempBuild = false)
{
// find best applicable rule
var best = rules
.Select(r => new { Node = r, Match = r.Match(name) })
.Where(m => m.Match.Success)
.GroupBy(m => m.Node.Priority)
.OrderBy(g => g.Key)
.FirstOrDefault();
if (best == null)
{
Log.Error("No applicable rule found for asset '{0}'.", name);
Interlocked.Increment(ref Stats.Failed);
return null;
}
else if (best.Count() != 1)
Log.Warning("More than one rule with the same priority matches asset '{0}' (rules on lines: {1})", name, string.Join(", ", best.Select(b => b.Node.LineNumber)));
// we've found the rule we will use. queue up the task to build the asset, or return the current one if it's already being built
var chosen = best.First();
var task = runningBuilds.GetOrAdd(name, new Lazy<Task<BuildInstance>>(() =>
{
var instance = new BuildInstance(this, chosen.Match, chosen.Node, tempBuild);
var job = Task.Run(() => InternalStart(name, chosen.Node, instance));
job.ContinueWith(t => runningBuilds.Remove(name));
return job;
})).Value;
// also register the task for any byproducts
foreach (var byproduct in chosen.Node.Byproducts)
{
var byproductName = chosen.Match.Result(byproduct);
runningBuilds.TryAdd(byproductName, new Lazy<Task<BuildInstance>>(() => task));
}
return task;
}