public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList(); var modifier = ModifierUtility.CreateModifier(node, target); UnityEngine.Assertions.Assert.IsNotNull(modifier); bool isAnyAssetModified = false; foreach(var asset in incomingAssets) { var loadedAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(asset.importFrom); if(modifier.IsModified(loadedAsset)) { modifier.Modify(loadedAsset); isAnyAssetModified = true; } } if(isAnyAssetModified) { // apply asset setting changes to AssetDatabase. AssetDatabase.Refresh(); } // Modifier does not add, filter or change structure of group, so just pass given group of assets Output(connectionToOutput, inputGroupAssets, null); }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target); UnityEngine.Assertions.Assert.IsNotNull(builder); var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(target, node); Dictionary<string, List<Asset>> output = new Dictionary<string, List<Asset>>(); foreach(var key in inputGroupAssets.Keys) { var allAssets = LoadAllAssets(inputGroupAssets[key]); var prefabFileName = builder.CanCreatePrefab(key, allAssets); UnityEngine.GameObject obj = builder.CreatePrefab(key, allAssets); if(obj == null) { throw new AssetBundleGraphException(string.Format("{0} :PrefabBuilder {1} returned null in CreatePrefab() [groupKey:{2}]", node.Name, builder.GetType().FullName, key)); } var prefabSavePath = FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab"); PrefabUtility.CreatePrefab(prefabSavePath, obj, ReplacePrefabOptions.Default); output[key] = new List<Asset> () { Asset.CreateAssetWithImportPath(prefabSavePath) }; GameObject.DestroyImmediate(obj); } Output(connectionToOutput, output, null); }
public ConnectionData(V1.ConnectionData v1) { m_id = v1.Id; m_fromNodeId = v1.FromNodeId; m_fromNodeConnectionPointId = v1.FromNodeConnectionPointId; m_toNodeId = v1.ToNodeId; m_toNodeConnectionPoiontId = v1.ToNodeConnectionPointId; m_label = v1.Label; }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { Export(target, node, inputPoint, connectionToOutput, inputGroupAssets, Output, true); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { ValidateBundleNameTemplate( node.BundleNameTemplate[target], () => { throw new NodeException(node.Name + ":Bundle Name Template is empty.", node.Id); } ); var variantNames = node.Variants.Select(v=>v.Name).ToList(); foreach(var variant in node.Variants) { ValidateVariantName(variant.Name, variantNames, () => { throw new NodeException(node.Name + ":Variant name is empty.", node.Id); }, () => { throw new NodeException(node.Name + ":Variant name cannot contain whitespace \"" + variant.Name + "\".", node.Id); }, () => { throw new NodeException(node.Name + ":Variant name already exists \"" + variant.Name + "\".", node.Id); }); } /* * Check if incoming asset has valid import path */ var invalids = new List<Asset>(); foreach (var groupKey in inputGroupAssets.Keys) { inputGroupAssets[groupKey].ForEach( a => { if (string.IsNullOrEmpty(a.importFrom)) invalids.Add(a); } ); } if (invalids.Any()) { throw new NodeException(node.Name + ": Invalid files are found. Following files need to be imported to put into asset bundle: " + string.Join(", ", invalids.Select(a =>a.absoluteAssetPath).ToArray()), node.Id ); } var output = new Dictionary<string, List<Asset>>(); var currentVariant = node.Variants.Find( v => v.ConnectionPoint == inputPoint ); var variantName = (currentVariant == null) ? null : currentVariant.Name; // set configured assets in bundle name foreach (var groupKey in inputGroupAssets.Keys) { var bundleName = GetBundleName(target, node, groupKey, variantName); output[bundleName] = ConfigureAssetBundleSettings(variantName, inputGroupAssets[groupKey]); } Output(connectionToOutput, output, null); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { node.ValidateOverlappingFilterCondition(true); Filter(node, inputGroupAssets, Output); }
private void GroupingOutput(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { ValidateGroupingKeyword( node.GroupingKeywords[target], () => { throw new NodeException("Grouping Keyword can not be empty.", node.Id); }, () => { throw new NodeException(String.Format("Grouping Keyword must contain {0} for numbering: currently {1}", AssetBundleGraphSettings.KEYWORD_WILDCARD, node.GroupingKeywords[target]), node.Id); } ); var outputDict = new Dictionary<string, List<Asset>>(); var mergedGroupedSources = new List<Asset>(); foreach (var groupKey in inputGroupAssets.Keys) { mergedGroupedSources.AddRange(inputGroupAssets[groupKey]); } var groupingKeyword = node.GroupingKeywords[target]; var split = groupingKeyword.Split(AssetBundleGraphSettings.KEYWORD_WILDCARD); var groupingKeywordPrefix = split[0]; var groupingKeywordPostfix = split[1]; foreach (var source in mergedGroupedSources) { var targetPath = source.GetAbsolutePathOrImportedPath(); var regex = new Regex(groupingKeywordPrefix + "(.*?)" + groupingKeywordPostfix); var match = regex.Match(targetPath); if (match.Success) { var newGroupingKey = match.Groups[1].Value; if (!outputDict.ContainsKey(newGroupingKey)) outputDict[newGroupingKey] = new List<Asset>(); outputDict[newGroupingKey].Add(source); } } Output(connectionToOutput, outputDict, null); }
void Load(BuildTarget target, NodeData node, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { // SOMEWHERE_FULLPATH/PROJECT_FOLDER/Assets/ var assetsFolderPath = Application.dataPath + AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR; var outputSource = new List<Asset>(); var targetFilePaths = FileUtility.GetAllFilePathsInFolder(node.GetLoaderFullLoadPath(target)); foreach (var targetFilePath in targetFilePaths) { if(targetFilePath.Contains(AssetBundleGraphSettings.ASSETBUNDLEGRAPH_PATH)) { continue; } // already contained into Assets/ folder. // imported path is Assets/SOMEWHERE_FILE_EXISTS. if (targetFilePath.StartsWith(assetsFolderPath)) { var relativePath = targetFilePath.Replace(assetsFolderPath, AssetBundleGraphSettings.ASSETS_PATH); var assetType = TypeUtility.GetTypeOfAsset(relativePath); if (assetType == typeof(object)) { continue; } outputSource.Add(Asset.CreateNewAssetFromLoader(targetFilePath, relativePath)); continue; } throw new NodeException(node.Name + ": Invalid Load Path. Path must start with Assets/", node.Name); } var outputDir = new Dictionary<string, List<Asset>> { {"0", outputSource} }; Output(connectionToOutput, outputDir, null); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { ValidateExportPath( node.ExporterExportPath[target], node.ExporterExportPath[target], () => { throw new NodeException(node.Name + ":Export Path is empty.", node.Id); }, () => { throw new NodeException(node.Name + ":Directory set to Export Path does not exist. Path:" + node.ExporterExportPath[target], node.Id); } ); Export(target, node, inputPoint, connectionToOutput, inputGroupAssets, Output, false); }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var output = new Dictionary<string, List<Asset>>(); var currentVariant = node.Variants.Find( v => v.ConnectionPoint == inputPoint ); var variantName = (currentVariant == null) ? null : currentVariant.Name; // set configured assets in bundle name foreach (var groupKey in inputGroupAssets.Keys) { var bundleName = GetBundleName(target, node, groupKey, variantName); output[bundleName] = ConfigureAssetBundleSettings(variantName, inputGroupAssets[groupKey]); } Output(connectionToOutput, output, null); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { ValidateLoadPath( node.LoaderLoadPath[target], node.GetLoaderFullLoadPath(target), () => { //can be empty //throw new NodeException(node.Name + ": Load Path is empty.", node.Id); }, () => { throw new NodeException(node.Name + ": Directory not found: " + node.GetLoaderFullLoadPath(target), node.Id); } ); Load(target, node, connectionToOutput, inputGroupAssets, Output); }
private void Export(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output, bool isRun) { var outputDict = new Dictionary<string, List<Asset>>(); outputDict["0"] = new List<Asset>(); var failedExports = new List<string>(); foreach (var groupKey in inputGroupAssets.Keys) { var exportedAssets = new List<Asset>(); var inputSources = inputGroupAssets[groupKey]; foreach (var source in inputSources) { if (isRun) { if (!Directory.Exists(node.ExporterExportPath[target])) { Directory.CreateDirectory(node.ExporterExportPath[target]); } } var destinationSourcePath = source.importFrom; // in bundleBulider, use platform-package folder for export destination. if (destinationSourcePath.StartsWith(AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE)) { var depth = AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR).Length + 1; var splitted = destinationSourcePath.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR); var reducedArray = new string[splitted.Length - depth]; Array.Copy(splitted, depth, reducedArray, 0, reducedArray.Length); var fromDepthToEnd = string.Join(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString(), reducedArray); destinationSourcePath = fromDepthToEnd; } var destination = FileUtility.PathCombine(node.ExporterExportPath[target], destinationSourcePath); var parentDir = Directory.GetParent(destination).ToString(); if (isRun) { if (!Directory.Exists(parentDir)) { Directory.CreateDirectory(parentDir); } if (File.Exists(destination)) { File.Delete(destination); } if (string.IsNullOrEmpty(source.importFrom)) { failedExports.Add(source.absoluteAssetPath); continue; } try { File.Copy(source.importFrom, destination); } catch(Exception e) { failedExports.Add(source.importFrom); Debug.LogError(node.Name + ": Error occured: " + e.Message); } } var exportedAsset = Asset.CreateAssetWithExportPath(destination); exportedAssets.Add(exportedAsset); } outputDict["0"].AddRange(exportedAssets); } if (failedExports.Any()) { Debug.LogError(node.Name + ": Failed to export files. All files must be imported before exporting: " + string.Join(", ", failedExports.ToArray())); } Output(connectionToOutput, outputDict, null); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList(); Action<Type, Type, Asset> multipleAssetTypeFound = (Type expectedType, Type foundType, Asset foundAsset) => { throw new NodeException(string.Format("{3} :ImportSetting expect {0}, but different type of incoming asset is found({1} {2})", expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id); }; Action<Type> unsupportedType = (Type unsupported) => { throw new NodeException(string.Format("{0} :Incoming asset type is not supported by ImportSetting (Incoming type:{1}). Perhaps you want to use Modifier instead?", node.Name, (unsupported != null)?unsupported.FullName:"null"), node.Id); }; Action<Type, Type> incomingTypeMismatch = (Type expected, Type incoming) => { throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this ImportSetting (Expected type:{1}, Incoming type:{2}).", node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id); }; Action<ConfigStatus> errorInConfig = (ConfigStatus _) => { // give a try first in sampling file if(incomingAssets.Any()) { SaveSampleFile(node, incomingAssets[0]); ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, (ConfigStatus eType) => { if(eType == ConfigStatus.NoSampleFound) { throw new NodeException(node.Name + " :ImportSetting has no sampling file. Please configure it from Inspector.", node.Id); } if(eType == ConfigStatus.TooManySamplesFound) { throw new NodeException(node.Name + " :ImportSetting has too many sampling file. Please fix it from Inspector.", node.Id); } }); } }; ValidateInputSetting(node, target, incomingAssets, multipleAssetTypeFound, unsupportedType, incomingTypeMismatch, errorInConfig); // ImportSettings does not add, filter or change structure of group, so just pass given group of assets Output(connectionToOutput, inputGroupAssets, null); }
private void Export(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary <string, List <Asset> > inputGroupAssets, Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output, bool isRun) { var outputDict = new Dictionary <string, List <Asset> >(); outputDict["0"] = new List <Asset>(); var exportPath = FileUtility.GetPathWithProjectPath(node.ExporterExportPath[target]); if (isRun) { if (node.ExporterExportOption[target] == (int)ExporterExportOption.DeleteAndRecreateExportDirectory) { if (Directory.Exists(exportPath)) { Directory.Delete(exportPath, true); } } if (node.ExporterExportOption[target] != (int)ExporterExportOption.ErrorIfNoExportDirectoryFound) { if (!Directory.Exists(exportPath)) { Directory.CreateDirectory(exportPath); } } } var failedExports = new List <string>(); foreach (var groupKey in inputGroupAssets.Keys) { var exportedAssets = new List <Asset>(); var inputSources = inputGroupAssets[groupKey]; foreach (var source in inputSources) { var destinationSourcePath = source.importFrom; // in bundleBulider, use platform-package folder for export destination. if (destinationSourcePath.StartsWith(AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE)) { var depth = AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR).Length + 1; var splitted = destinationSourcePath.Split(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR); var reducedArray = new string[splitted.Length - depth]; Array.Copy(splitted, depth, reducedArray, 0, reducedArray.Length); var fromDepthToEnd = string.Join(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString(), reducedArray); destinationSourcePath = fromDepthToEnd; } var destination = FileUtility.PathCombine(exportPath, destinationSourcePath); var parentDir = Directory.GetParent(destination).ToString(); if (isRun) { if (!Directory.Exists(parentDir)) { Directory.CreateDirectory(parentDir); } if (File.Exists(destination)) { File.Delete(destination); } if (string.IsNullOrEmpty(source.importFrom)) { failedExports.Add(source.absoluteAssetPath); continue; } try { File.Copy(source.importFrom, destination); } catch (Exception e) { failedExports.Add(source.importFrom); Debug.LogError(node.Name + ": Error occured: " + e.Message); } } var exportedAsset = Asset.CreateAssetWithExportPath(destination); exportedAssets.Add(exportedAsset); } outputDict["0"].AddRange(exportedAssets); } if (failedExports.Any()) { Debug.LogError(node.Name + ": Failed to export files. All files must be imported before exporting: " + string.Join(", ", failedExports.ToArray())); } Output(connectionToOutput, outputDict, null); }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary <string, List <Asset> > inputGroupAssets, List <string> alreadyCached, Action <ConnectionData, Dictionary <string, List <Asset> >, List <string> > Output) { var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node); var bundleNames = inputGroupAssets.Keys.ToList(); var bundleVariants = new Dictionary <string, List <string> >(); // get all variant name for bundles foreach (var name in bundleNames) { bundleVariants[name] = new List <string>(); var assets = inputGroupAssets[name]; foreach (var a in assets) { var variantName = a.variantName; if (!bundleVariants[name].Contains(variantName)) { bundleVariants[name].Add(variantName); } } } int validNames = 0; foreach (var name in bundleNames) { var assets = inputGroupAssets[name]; // we do not build bundle without any asset if (assets.Count > 0) { validNames += bundleVariants[name].Count; } } AssetBundleBuild[] bundleBuild = new AssetBundleBuild[validNames]; int bbIndex = 0; foreach (var name in bundleNames) { foreach (var v in bundleVariants[name]) { var bundleName = name; var assets = inputGroupAssets[name]; if (assets.Count <= 0) { continue; } bundleBuild[bbIndex].assetBundleName = bundleName; bundleBuild[bbIndex].assetBundleVariant = v; bundleBuild[bbIndex].assetNames = assets.Where(x => x.variantName == v).Select(x => x.importFrom).ToArray(); ++bbIndex; } } BuildPipeline.BuildAssetBundles(bundleOutputDir, bundleBuild, (BuildAssetBundleOptions)node.BundleBuilderBundleOptions[target], target); var output = new Dictionary <string, List <Asset> >(); output[key] = new List <Asset>(); var generatedFiles = FileUtility.GetAllFilePathsInFolder(bundleOutputDir); // add manifest file bundleNames.Add(BuildTargetUtility.TargetToAssetBundlePlatformName(target)); foreach (var path in generatedFiles) { var fileName = Path.GetFileName(path); if (IsFileIntendedItem(fileName, bundleNames)) { output[key].Add(Asset.CreateAssetWithImportPath(path)); } else { Debug.LogWarning(node.Name + ":Irrelevant file found in assetbundle cache folder:" + fileName); } } Output(connectionToOutput, output, alreadyCached); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { ValidatePrefabBuilder(node, target, inputGroupAssets, () => { throw new NodeException(node.Name + " :PrefabBuilder is not configured. Please configure from Inspector.", node.Id); }, () => { throw new NodeException(node.Name + " :Failed to create PrefabBuilder from settings. Please fix settings from Inspector.", node.Id); }, (string groupKey) => { throw new NodeException(string.Format("{0} :Can not create prefab with incoming assets for group {1}.", node.Name, groupKey), node.Id); }, (Asset badAsset) => { throw new NodeException(string.Format("{0} :Can not import incoming asset {1}.", node.Name, badAsset.fileNameAndExtension), node.Id); } ); var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target); UnityEngine.Assertions.Assert.IsNotNull(builder); var prefabOutputDir = FileUtility.EnsurePrefabBuilderCacheDirExists(target, node); Dictionary<string, List<Asset>> output = new Dictionary<string, List<Asset>>(); foreach(var key in inputGroupAssets.Keys) { var prefabFileName = builder.CanCreatePrefab(key, LoadAllAssets(inputGroupAssets[key])); output[key] = new List<Asset> () { Asset.CreateAssetWithImportPath(FileUtility.PathCombine(prefabOutputDir, prefabFileName + ".prefab")) }; } Output(connectionToOutput, output, null); }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList(); ApplyImportSetting(node, incomingAssets); Output(connectionToOutput, inputGroupAssets, null); }
public void Run(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node); var bundleNames = inputGroupAssets.Keys.ToList(); var bundleVariants = new Dictionary<string, List<string>>(); // get all variant name for bundles foreach (var name in bundleNames) { bundleVariants[name] = new List<string>(); var assets = inputGroupAssets[name]; foreach(var a in assets) { var variantName = a.variantName; if(!bundleVariants[name].Contains(variantName)) { bundleVariants[name].Add(variantName); } } } int validNames = 0; foreach (var name in bundleNames) { var assets = inputGroupAssets[name]; // we do not build bundle without any asset if( assets.Count > 0 ) { validNames += bundleVariants[name].Count; } } AssetBundleBuild[] bundleBuild = new AssetBundleBuild[validNames]; int bbIndex = 0; foreach(var name in bundleNames) { foreach(var v in bundleVariants[name]) { var bundleName = name; var assets = inputGroupAssets[name]; if(assets.Count <= 0) { continue; } bundleBuild[bbIndex].assetBundleName = bundleName; bundleBuild[bbIndex].assetBundleVariant = v; bundleBuild[bbIndex].assetNames = assets.Where(x => x.variantName == v).Select(x => x.importFrom).ToArray(); ++bbIndex; } } BuildPipeline.BuildAssetBundles(bundleOutputDir, bundleBuild, (BuildAssetBundleOptions)node.BundleBuilderBundleOptions[target], target); var output = new Dictionary<string, List<Asset>>(); output[key] = new List<Asset>(); var generatedFiles = FileUtility.GetAllFilePathsInFolder(bundleOutputDir); // add manifest file bundleNames.Add( BuildTargetUtility.TargetToAssetBundlePlatformName(target) ); foreach (var path in generatedFiles) { var fileName = Path.GetFileName(path); if( IsFileIntendedItem(fileName, bundleNames) ) { output[key].Add( Asset.CreateAssetWithImportPath(path) ); } else { Debug.LogWarning(node.Name + ":Irrelevant file found in assetbundle cache folder:" + fileName); } } Output(connectionToOutput, output, alreadyCached); }
/** 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<NodeException> errorHandler, Action<NodeData, float> updateHandler ) { 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, errorHandler, updateHandler); } } // if parent does not have input point, call with inputPoint==null else { DoNodeOperation(target, parentNode, null, c, saveData, resultDict, cachedDict, performedIds, isActualRun, errorHandler, 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, errorHandler); 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) { errorHandler(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); } }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList(); ValidateModifier(node, target, incomingAssets, (Type expectedType, Type foundType, Asset foundAsset) => { throw new NodeException(string.Format("{3} :Modifier expect {0}, but different type of incoming asset is found({1} {2})", expectedType.FullName, foundType.FullName, foundAsset.fileNameAndExtension, node.Name), node.Id); }, () => { throw new NodeException(node.Name + " :Modifier is not configured. Please configure from Inspector.", node.Id); }, () => { throw new NodeException(node.Name + " :Failed to create Modifier from settings. Please fix settings from Inspector.", node.Id); }, (Type expected, Type incoming) => { throw new NodeException(string.Format("{0} :Incoming asset type is does not match with this Modifier (Expected type:{1}, Incoming type:{2}).", node.Name, (expected != null)?expected.FullName:"null", (incoming != null)?incoming.FullName:"null"), node.Id); } ); // Modifier does not add, filter or change structure of group, so just pass given group of assets Output(connectionToOutput, inputGroupAssets, null); }
public void Setup(BuildTarget target, NodeData node, ConnectionPointData inputPoint, ConnectionData connectionToOutput, Dictionary<string, List<Asset>> inputGroupAssets, List<string> alreadyCached, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { var outputDict = new Dictionary<string, List<Asset>>(); outputDict[key] = new List<Asset>(); var bundleNames = inputGroupAssets.Keys.ToList(); var bundleVariants = new Dictionary<string, List<string>>(); // get all variant name for bundles foreach (var name in bundleNames) { bundleVariants[name] = new List<string>(); var assets = inputGroupAssets[name]; foreach(var a in assets) { var variantName = a.variantName; if(!bundleVariants[name].Contains(variantName)) { bundleVariants[name].Add(variantName); } } } // add manifest file var manifestName = BuildTargetUtility.TargetToAssetBundlePlatformName(target); bundleNames.Add( manifestName ); bundleVariants[manifestName] = new List<string>(); var bundleOutputDir = FileUtility.EnsureAssetBundleCacheDirExists(target, node); foreach (var name in bundleNames) { foreach(var v in bundleVariants[name]) { string bundleName = (string.IsNullOrEmpty(v))? name : name + "." + v; Asset bundle = Asset.CreateAssetWithImportPath( FileUtility.PathCombine(bundleOutputDir, bundleName) ); Asset manifest = Asset.CreateAssetWithImportPath( FileUtility.PathCombine(bundleOutputDir, bundleName + AssetBundleGraphSettings.MANIFEST_FOOTER) ); outputDict[key].Add(bundle); outputDict[key].Add(manifest); } } Output(connectionToOutput, outputDict, new List<string>()); }
/** * 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 <NodeException> errorHandler, Action <NodeData, float> updateHandler ) { 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, errorHandler, updateHandler); } } // if parent does not have input point, call with inputPoint==null else { DoNodeOperation(target, parentNode, null, c, saveData, resultDict, cachedDict, performedIds, isActualRun, errorHandler, 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, errorHandler); 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) { errorHandler(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); } }