/**
* Collect build result: connectionId : < groupName : List<Asset> >
*/
// private static Dictionary<ConnectionData, Dictionary<string, List<Asset>>>
// CollectResult (Dictionary<ConnectionData, Dictionary<string, List<Asset>>> buildResult) {
//
// var finalResult = new Dictionary<ConnectionData, Dictionary<string, List<Asset>>>();
//
// foreach (var connection in buildResult.Keys) {
// var groupDict = buildResult[connection];
// var finalGroupDict = new Dictionary<string, List<Asset>>();
//
// foreach (var groupKey in groupDict.Keys) {
// var assets = groupDict[groupKey];
// var finalAssets = new List<Asset>();
//
// foreach (var assetData in assets) {
// var bundled = assetData.isBundled;
//
// if (!string.IsNullOrEmpty(assetData.importFrom)) {
// finalAssets.Add(new DepreacatedThroughputAsset(assetData.importFrom, bundled));
// continue;
// }
//
// if (!string.IsNullOrEmpty(assetData.absoluteAssetPath)) {
// var relativeAbsolutePath = assetData.absoluteAssetPath.Replace(FileUtility.ProjectPathWithSlash(), string.Empty);
// finalAssets.Add(new DepreacatedThroughputAsset(relativeAbsolutePath, bundled));
// continue;
// }
//
// if (!string.IsNullOrEmpty(assetData.exportTo)) {
// finalAssets.Add(new DepreacatedThroughputAsset(assetData.exportTo, bundled));
// continue;
// }
// }
// finalGroupDict[groupKey] = finalAssets;
// }
// finalResult[connection] = finalGroupDict;
// }
// return finalResult;
// }
/**
* Perform Run or Setup from parent of given terminal node recursively.
*/
private static void DoNodeOperation(
BuildTarget target,
NodeData currentNodeData,
ConnectionPointData currentInputPoint,
ConnectionData connectionToOutput,
SaveData saveData,
Dictionary <ConnectionData, Dictionary <string, List <Asset> > > resultDict,
Dictionary <NodeData, List <string> > cachedDict,
List <string> performedIds,
bool isActualRun,
Action <NodeData, float> updateHandler = null
)
{
if (performedIds.Contains(currentNodeData.Id) || (currentInputPoint != null && performedIds.Contains(currentInputPoint.Id)))
{
return;
}
/*
* Find connections coming into this node from parent node, and traverse recursively
*/
var connectionsToParents = saveData.Connections.FindAll(con => con.ToNodeId == currentNodeData.Id);
foreach (var c in connectionsToParents)
{
var parentNode = saveData.Nodes.Find(node => node.Id == c.FromNodeId);
UnityEngine.Assertions.Assert.IsNotNull(parentNode);
// check if nodes can connect together
ConnectionData.ValidateConnection(parentNode, currentNodeData);
if (parentNode.InputPoints.Count > 0)
{
// if node has multiple input, node is operated per input
foreach (var parentInputPoint in parentNode.InputPoints)
{
DoNodeOperation(target, parentNode, parentInputPoint, c, saveData, resultDict, cachedDict, performedIds, isActualRun, updateHandler);
}
}
// if parent does not have input point, call with inputPoint==null
else
{
DoNodeOperation(target, parentNode, null, c, saveData, resultDict, cachedDict, performedIds, isActualRun, updateHandler);
}
}
// mark this point as performed
if (currentInputPoint != null)
{
performedIds.Add(currentInputPoint.Id);
}
// Root node does not have input point, so we are storing node id instead.
else
{
performedIds.Add(currentNodeData.Id);
}
/*
* Perform node operation for this node
*/
if (updateHandler != null)
{
updateHandler(currentNodeData, 0f);
}
/*
* has next node, run first time.
*/
var alreadyCachedPaths = new List <string>();
if (cachedDict.ContainsKey(currentNodeData))
{
alreadyCachedPaths.AddRange(cachedDict[currentNodeData]);
}
// load already exist cache from node.
alreadyCachedPaths.AddRange(GetCachedDataByNode(target, currentNodeData));
// Grab incoming assets from result by refering connections to parents
var inputGroupAssets = new Dictionary <string, List <Asset> >();
if (currentInputPoint != null)
{
// aggregates all input assets coming from current inputPoint
var connToParentsFromCurrentInput = saveData.Connections.FindAll(con => con.ToNodeConnectionPointId == currentInputPoint.Id);
foreach (var rCon in connToParentsFromCurrentInput)
{
if (!resultDict.ContainsKey(rCon))
{
continue;
}
var result = resultDict[rCon];
foreach (var groupKey in result.Keys)
{
if (!inputGroupAssets.ContainsKey(groupKey))
{
inputGroupAssets[groupKey] = new List <Asset>();
}
inputGroupAssets[groupKey].AddRange(result[groupKey]);
}
}
}
/*
* the Action passes to NodeOperaitons.
* It stores result to resultDict.
*/
Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output =
(ConnectionData destinationConnection, Dictionary <string, List <Asset> > outputGroupAsset, List <string> cachedItems) =>
{
if (destinationConnection != null)
{
if (!resultDict.ContainsKey(destinationConnection))
{
resultDict[destinationConnection] = new Dictionary <string, List <Asset> >();
}
/*
* merge connection result by group key.
*/
foreach (var groupKey in outputGroupAsset.Keys)
{
if (!resultDict[destinationConnection].ContainsKey(groupKey))
{
resultDict[destinationConnection][groupKey] = new List <Asset>();
}
resultDict[destinationConnection][groupKey].AddRange(outputGroupAsset[groupKey]);
}
}
if (isActualRun)
{
if (!cachedDict.ContainsKey(currentNodeData))
{
cachedDict[currentNodeData] = new List <string>();
}
if (cachedItems != null)
{
cachedDict[currentNodeData].AddRange(cachedItems);
}
}
};
try {
INodeOperation executor = CreateOperation(saveData, currentNodeData);
if (executor != null)
{
if (isActualRun)
{
executor.Run(target, currentNodeData, currentInputPoint, connectionToOutput, inputGroupAssets, alreadyCachedPaths, Output);
}
else
{
executor.Setup(target, currentNodeData, currentInputPoint, connectionToOutput, inputGroupAssets, alreadyCachedPaths, Output);
}
}
} catch (NodeException e) {
AssetBundleGraphEditorWindow.AddNodeException(e);
// since error occured, this node should stop running for other inputpoints. Adding node id to stop.
if (!performedIds.Contains(currentNodeData.Id))
{
performedIds.Add(currentNodeData.Id);
}
}
if (updateHandler != null)
{
updateHandler(currentNodeData, 1f);
}
}