public void Import(V1.NodeData v1, Model.NodeData v2) { foreach (var f in v1.FilterConditions) { m_filter.Add(new FilterEntry(new FilterByNameAndType(f.FilterKeyword, f.FilterKeytype), v2.FindOutputPoint(f.ConnectionPointId))); } }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_groupingKeyword = new SerializableMultiTargetString(v1.GroupingKeywords); m_patternType = new SerializableMultiTargetInt((int)GroupingPatternType.WildCard); m_allowSlash = true; m_groupNameFormat = new SerializableMultiTargetString(); }
public static INodeOperation CreateOperation(SaveData saveData, NodeData currentNodeData, Action<NodeException> errorHandler) { INodeOperation executor = null; try { switch (currentNodeData.Kind) { case NodeKind.LOADER_GUI: { executor = new IntegratedGUILoader(); break; } case NodeKind.FILTER_GUI: { // Filter requires multiple output connections var connectionsToChild = saveData.Connections.FindAll(c => c.FromNodeId == currentNodeData.Id); executor = new IntegratedGUIFilter(connectionsToChild); break; } case NodeKind.IMPORTSETTING_GUI: { executor = new IntegratedGUIImportSetting(); break; } case NodeKind.MODIFIER_GUI: { executor = new IntegratedGUIModifier(); break; } case NodeKind.GROUPING_GUI: { executor = new IntegratedGUIGrouping(); break; } case NodeKind.PREFABBUILDER_GUI: { executor = new IntegratedPrefabBuilder(); break; } case NodeKind.BUNDLECONFIG_GUI: { executor = new IntegratedGUIBundleConfigurator(); break; } case NodeKind.BUNDLEBUILDER_GUI: { executor = new IntegratedGUIBundleBuilder(); break; } case NodeKind.EXPORTER_GUI: { executor = new IntegratedGUIExporter(); break; } default: { Debug.LogError(currentNodeData.Name + " is defined as unknown kind of node. value:" + currentNodeData.Kind); break; } } } catch (NodeException e) { errorHandler(e); } return executor; }
public NodeData(V1.NodeData v1) { //TODO: m_id = v1.Id; m_name = v1.Name; m_x = v1.X; m_y = v1.Y; m_nodeNeedsRevisit = false; m_inputPoints = new List <ConnectionPointData>(); m_outputPoints = new List <ConnectionPointData>(); foreach (var input in v1.InputPoints) { m_inputPoints.Add(new ConnectionPointData(input)); } foreach (var output in v1.OutputPoints) { m_outputPoints.Add(new ConnectionPointData(output)); } Node n = CreateNodeFromV1NodeData(v1, this); m_nodeInstance = new NodeInstance(n); }
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 Import(V1.NodeData v1, Model.NodeData v2) { m_enabledBundleOptions = new SerializableMultiTargetInt(v1.BundleBuilderBundleOptions); m_outputDir = new SerializableMultiTargetString(); m_outputOption = new SerializableMultiTargetInt((int)OutputOption.BuildInCacheDirectory); m_manifestName = new SerializableMultiTargetString(); }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_instance = new SerializableMultiTargetInstance(v1.ScriptClassName, v1.InstanceData); m_replacePrefabOptions = v1.ReplacePrefabOptions; m_outputDir = new SerializableMultiTargetString(); m_outputOption = new SerializableMultiTargetInt((int)OutputOption.CreateInCacheDirectory); }
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 ConnectionPointData(string label, NodeData parent, bool isInput) { this.id = Guid.NewGuid().ToString(); this.label = label; this.parentId = parent.Id; this.isInput = isInput; // this.orderPriority = pointGui.orderPriority; // this.showLabel = pointGui.showLabel; }
// private int orderPriority; // private bool showLabel; public ConnectionPointData(string id, string label, NodeData parent, bool isInput/*, int orderPriority, bool showLabel */) { this.id = id; this.label = label; this.parentId = parent.Id; this.isInput = isInput; // this.orderPriority = orderPriority; // this.showLabel = showLabel; }
public ConnectionPointData(Dictionary<string, object> dic, NodeData parent, bool isInput) { this.id = dic[ID] as string; this.label = dic[LABEL] as string; this.parentId = parent.Id; this.isInput = isInput; // this.orderPriority = pointGui.orderPriority; // this.showLabel = pointGui.showLabel; }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_bundleNameTemplate = new SerializableMultiTargetString(v1.BundleNameTemplate); m_useGroupAsVariants = v1.BundleConfigUseGroupAsVariants; foreach (var v in v1.Variants) { m_variants.Add(new Variant(v.Name, v2.FindInputPoint(v.ConnectionPointId))); } }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_loadPath = new SerializableMultiTargetString(v1.LoaderLoadPath); m_loadPathGuid = new SerializableMultiTargetString(); foreach (var v in m_loadPath.Values) { var loadPath = FileUtility.PathCombine(Model.Settings.Path.ASSETS_PATH, v.value); m_loadPathGuid [v.targetGroup] = AssetDatabase.AssetPathToGUID(loadPath); } }
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); }
public static void ValidateInputSetting( NodeData node, BuildTarget target, List<Asset> incomingAssets, Action<Type, Type, Asset> multipleAssetTypeFound, Action<Type> unsupportedType, Action<Type, Type> incomingTypeMismatch, Action<ConfigStatus> errorInConfig ) { Type expectedType = TypeUtility.FindIncomingAssetType(incomingAssets); if(multipleAssetTypeFound != null) { if(expectedType != null) { foreach(var a in incomingAssets) { Type assetType = TypeUtility.FindTypeOfAsset(a.importFrom); if(assetType != expectedType) { multipleAssetTypeFound(expectedType, assetType, a); } } } } if(unsupportedType != null) { if(expectedType != null) { if(expectedType == typeof(UnityEditor.TextureImporter) || expectedType == typeof(UnityEditor.ModelImporter) || expectedType == typeof(UnityEditor.AudioImporter) ) { // good. do nothing } else { unsupportedType(expectedType); } } } var status = GetConfigStatus(node); if(errorInConfig != null) { if(status != ConfigStatus.GoodSampleFound) { errorInConfig(status); } } if(incomingTypeMismatch != null) { // if there is no incoming assets, there is no way to check if // right type of asset is coming in - so we'll just skip the test if(incomingAssets.Any() && status == ConfigStatus.GoodSampleFound) { Type targetType = GetReferenceAssetImporter(node).GetType(); if( targetType != expectedType ) { incomingTypeMismatch(targetType, expectedType); } } } }
public static string EnsurePrefabBuilderCacheDirExists(BuildTarget t, NodeData node) { var cacheDir = FileUtility.PathCombine(AssetBundleGraphSettings.PREFABBUILDER_CACHE_PLACE, node.Id, SystemDataUtility.GetPathSafeTargetName(t)); if (!Directory.Exists(cacheDir)) { Directory.CreateDirectory(cacheDir); } if (!cacheDir.EndsWith(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString())) { cacheDir = cacheDir + AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString(); } return cacheDir; }
public static string EnsureAssetBundleCacheDirExists(BuildTarget t, NodeData node, bool remake = false) { var cacheDir = FileUtility.PathCombine(AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, node.Id, BuildTargetUtility.TargetToAssetBundlePlatformName(t)); if (!Directory.Exists(cacheDir)) { Directory.CreateDirectory(cacheDir); } else { if(remake) { RemakeDirectory(cacheDir); } } return cacheDir; }
public static AssetImporter GetReferenceAssetImporter(NodeData node) { var sampleFileDir = FileUtility.PathCombine(AssetBundleGraphSettings.IMPORTER_SETTINGS_PLACE, node.Id); UnityEngine.Assertions.Assert.IsTrue(Directory.Exists(sampleFileDir)); var sampleFiles = FileUtility.GetFilePathsInFolder(sampleFileDir) .Where(path => !path.EndsWith(AssetBundleGraphSettings.UNITY_METAFILE_EXTENSION)) .ToList(); UnityEngine.Assertions.Assert.IsTrue(sampleFiles.Count == 1); return AssetImporter.GetAtPath(sampleFiles[0]); }
public NodeGUI(NodeData data) { this.m_nodeInsp = ScriptableObject.CreateInstance<NodeGUIInspectorHelper>(); this.m_nodeInsp.hideFlags = HideFlags.DontSave; this.m_nodeWindowId = 0; this.m_data = data; this.m_baseRect = new Rect(m_data.X, m_data.Y, AssetBundleGraphGUISettings.NODE_BASE_WIDTH, AssetBundleGraphGUISettings.NODE_BASE_HEIGHT); this.m_nodeSyle = NodeGUIUtility.UnselectedStyle[m_data.Kind]; UpdateNodeRect(); }
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); }
private void Filter(NodeData node, Dictionary<string, List<Asset>> inputGroupAssets, Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output) { foreach(var connToChild in connectionsToChild) { var filter = node.FilterConditions.Find(fc => fc.ConnectionPoint.Id == connToChild.FromNodeConnectionPointId); UnityEngine.Assertions.Assert.IsNotNull(filter); var output = new Dictionary<string, List<Asset>>(); foreach(var groupKey in inputGroupAssets.Keys) { var assets = inputGroupAssets[groupKey]; var filteringAssets = new List<FilterableAsset>(); assets.ForEach(a => filteringAssets.Add(new FilterableAsset(a))); // filter by keyword first List<FilterableAsset> keywordContainsAssets = filteringAssets.Where( assetData => !assetData.isFiltered && Regex.IsMatch(assetData.asset.importFrom, filter.FilterKeyword, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace) ).ToList(); List<FilterableAsset> finalFilteredAsset = new List<FilterableAsset>(); // then, filter by type foreach (var a in keywordContainsAssets) { if (filter.FilterKeytype != AssetBundleGraphSettings.DEFAULT_FILTER_KEYTYPE) { var assumedType = TypeUtility.FindTypeOfAsset(a.asset.importFrom); if (assumedType == null || filter.FilterKeytype != assumedType.ToString()) { continue; } } finalFilteredAsset.Add(a); } // mark assets as exhausted. foreach (var a in finalFilteredAsset) { a.isFiltered = true; } output[groupKey] = finalFilteredAsset.Select(v => v.asset).ToList(); } Output(connToChild, output, 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 static void ValidatePrefabBuilder( NodeData node, BuildTarget target, Dictionary<string, List<Asset>> inputGroupAssets, Action noBuilderData, Action failedToCreateBuilder, Action<string> canNotCreatePrefab, Action<Asset> canNotImportAsset ) { if(string.IsNullOrEmpty(node.InstanceData[target])) { noBuilderData(); } var builder = PrefabBuilderUtility.CreatePrefabBuilder(node, target); if(null == builder ) { failedToCreateBuilder(); } if(null != builder) { foreach(var key in inputGroupAssets.Keys) { var assets = inputGroupAssets[key]; if(assets.Any()) { bool isAllGoodAssets = true; foreach(var a in assets) { if(string.IsNullOrEmpty(a.importFrom)) { canNotImportAsset(a); isAllGoodAssets = false; } } if(isAllGoodAssets) { // do not call LoadAllAssets() unless all assets have importFrom if(string.IsNullOrEmpty(builder.CanCreatePrefab(key, LoadAllAssets(assets)))) { canNotCreatePrefab(key); } } } } } }
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 static ConfigStatus GetConfigStatus(NodeData node) { var sampleFileDir = FileUtility.PathCombine(AssetBundleGraphSettings.IMPORTER_SETTINGS_PLACE, node.Id); if(!Directory.Exists(sampleFileDir)) { return ConfigStatus.NoSampleFound; } var sampleFiles = FileUtility.GetFilePathsInFolder(sampleFileDir) .Where(path => !path.EndsWith(AssetBundleGraphSettings.UNITY_METAFILE_EXTENSION)) .ToList(); if(sampleFiles.Count == 0) { return ConfigStatus.NoSampleFound; } if(sampleFiles.Count == 1) { return ConfigStatus.GoodSampleFound; } return ConfigStatus.TooManySamplesFound; }
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); }
public static void ValidateModifier( NodeData node, BuildTarget target, List<Asset> incomingAssets, Action<Type, Type, Asset> multipleAssetTypeFound, Action noModiferData, Action failedToCreateModifier, Action<Type, Type> incomingTypeMismatch ) { Type expectedType = TypeUtility.FindIncomingAssetType(incomingAssets); if(expectedType != null) { foreach(var a in incomingAssets) { Type assetType = TypeUtility.FindTypeOfAsset(a.importFrom); if(assetType != expectedType) { multipleAssetTypeFound(expectedType, assetType, a); } } } if(string.IsNullOrEmpty(node.InstanceData[target])) { noModiferData(); } var modifier = ModifierUtility.CreateModifier(node, target); if(null == modifier ) { failedToCreateModifier(); } // if there is no incoming assets, there is no way to check if // right type of asset is coming in - so we'll just skip the test if(incomingAssets.Any()) { var targetType = ModifierUtility.GetModifierTargetType(modifier); if( targetType != expectedType ) { incomingTypeMismatch(targetType, expectedType); } } }
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 Import(V1.NodeData v1, Model.NodeData v2) { m_loadPath = new SerializableMultiTargetString(v1.LoaderLoadPath); }
public static bool CanConnect(NodeData from, NodeData to) { switch (from.Kind) { case NodeKind.GROUPING_GUI: { switch (to.Kind) { case NodeKind.GROUPING_GUI: case NodeKind.PREFABBUILDER_GUI: case NodeKind.BUNDLECONFIG_GUI: return(true); } return(false); } case NodeKind.LOADER_GUI: case NodeKind.FILTER_GUI: case NodeKind.IMPORTSETTING_GUI: case NodeKind.MODIFIER_GUI: case NodeKind.PREFABBUILDER_GUI: { switch (to.Kind) { case NodeKind.BUNDLEBUILDER_GUI: return(false); } return(true); } case NodeKind.EXPORTER_GUI: { // there is no output from exporter return(false); } case NodeKind.BUNDLEBUILDER_GUI: { switch (to.Kind) { case NodeKind.FILTER_GUI: case NodeKind.GROUPING_GUI: case NodeKind.EXPORTER_GUI: case NodeKind.BUNDLECONFIG_GUI: return(true); } return(false); } case NodeKind.BUNDLECONFIG_GUI: { switch (to.Kind) { case NodeKind.BUNDLEBUILDER_GUI: return(true); } return(false); } } return(true); }
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 static string GetBundleName(BuildTarget target, NodeData node, string groupKey, string variantName) { var bundleName = node.BundleNameTemplate[target]; return bundleName.Replace(AssetBundleGraphSettings.KEYWORD_WILDCARD.ToString(), groupKey); }
/** * Build from commandline - entrypoint. */ public static void BuildFromCommandline() { try { var arguments = new List <string>(System.Environment.GetCommandLineArgs()); Application.stackTraceLogType = StackTraceLogType.None; BuildTarget target = EditorUserBuildSettings.activeBuildTarget; int targetIndex = arguments.FindIndex(a => a == "-target"); if (targetIndex >= 0) { var targetStr = arguments[targetIndex + 1]; LogUtility.Logger.Log("Target specified:" + targetStr); var newTarget = BuildTargetUtility.BuildTargetFromString(arguments[targetIndex + 1]); if (!BuildTargetUtility.IsBuildTargetSupported(newTarget)) { throw new AssetBundleGraphException(newTarget + " is not supported to build with this Unity. Please install platform support with installer(s)."); } if (newTarget != target) { #if UNITY_5_6 EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetUtility.TargetToGroup(newTarget), newTarget); #else EditorUserBuildSettings.SwitchActiveBuildTarget(newTarget); #endif target = newTarget; } } LogUtility.Logger.Log("AssetReference bundle building for:" + BuildTargetUtility.TargetToHumaneString(target)); if (!SaveData.IsSaveDataAvailableAtDisk()) { LogUtility.Logger.Log("AssetBundleGraph save data not found. Aborting..."); return; } // load data from file. AssetBundleGraphController c = new AssetBundleGraphController(); // perform setup. Fails if any exception raises. c.Perform(target, false, true, null); // if there is error reported, then run if (c.IsAnyIssueFound) { LogUtility.Logger.Log("Build terminated because following error found during Setup phase. Please fix issues by opening editor before building."); c.Issues.ForEach(e => LogUtility.Logger.LogError(LogUtility.kTag, e)); return; } NodeData lastNodeData = null; float lastProgress = 0.0f; Action <NodeData, string, float> updateHandler = (NodeData node, string message, float progress) => { if (node != null && lastNodeData != node) { lastNodeData = node; lastProgress = progress; LogUtility.Logger.LogFormat(LogType.Log, "Processing {0}", node.Name); } if (progress > lastProgress) { if (progress <= 1.0f) { LogUtility.Logger.LogFormat(LogType.Log, "{0} Complete.", node.Name); } else if ((progress - lastProgress) > 0.2f) { LogUtility.Logger.LogFormat(LogType.Log, "{0}: {1} % : {2}", node.Name, (int)progress * 100f, message); } lastProgress = progress; } }; // run datas. c.Perform(target, true, true, updateHandler); AssetDatabase.Refresh(); } catch (Exception e) { LogUtility.Logger.LogError(LogUtility.kTag, e); LogUtility.Logger.LogError(LogUtility.kTag, "Building asset bundles terminated due to unexpected error."); } finally { LogUtility.Logger.Log("End of build."); } }
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 Import(V1.NodeData v1, Model.NodeData v2) { m_instance = new SerializableMultiTargetInstance(v1.ScriptClassName, v1.InstanceData); }
public static INodeOperation CreateOperation(SaveData saveData, NodeData currentNodeData, Action <NodeException> errorHandler) { INodeOperation executor = null; try { switch (currentNodeData.Kind) { case NodeKind.LOADER_GUI: { executor = new IntegratedGUILoader(); break; } case NodeKind.FILTER_GUI: { // Filter requires multiple output connections var connectionsToChild = saveData.Connections.FindAll(c => c.FromNodeId == currentNodeData.Id); executor = new IntegratedGUIFilter(connectionsToChild); break; } case NodeKind.IMPORTSETTING_GUI: { executor = new IntegratedGUIImportSetting(); break; } case NodeKind.MODIFIER_GUI: { executor = new IntegratedGUIModifier(); break; } case NodeKind.GROUPING_GUI: { executor = new IntegratedGUIGrouping(); break; } case NodeKind.PREFABBUILDER_GUI: { executor = new IntegratedPrefabBuilder(); break; } case NodeKind.BUNDLECONFIG_GUI: { executor = new IntegratedGUIBundleConfigurator(); break; } case NodeKind.BUNDLEBUILDER_GUI: { executor = new IntegratedGUIBundleBuilder(); break; } case NodeKind.EXPORTER_GUI: { executor = new IntegratedGUIExporter(); break; } default: { Debug.LogError(currentNodeData.Name + " is defined as unknown kind of node. value:" + currentNodeData.Kind); break; } } } catch (NodeException e) { errorHandler(e); } return(executor); }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_exportPath = new SerializableMultiTargetString(v1.ExporterExportPath); m_exportOption = new SerializableMultiTargetInt(v1.ExporterExportOption); m_flattenDir = new SerializableMultiTargetInt(); }
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>()); }
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 Import(V1.NodeData v1, Model.NodeData v2) { m_instance = new SerializableMultiTargetInstance(v1.ScriptClassName, v1.InstanceData); m_modifierType = string.Empty; }
public static bool CanConnect(NodeData from, NodeData to) { switch (from.Kind) { case NodeKind.GROUPING_GUI: { switch (to.Kind) { case NodeKind.GROUPING_GUI: case NodeKind.PREFABBUILDER_GUI: case NodeKind.BUNDLECONFIG_GUI: return true; } return false; } case NodeKind.LOADER_GUI: case NodeKind.FILTER_GUI: case NodeKind.IMPORTSETTING_GUI: case NodeKind.MODIFIER_GUI: case NodeKind.PREFABBUILDER_GUI: { switch (to.Kind) { case NodeKind.BUNDLEBUILDER_GUI: return false; } return true; } case NodeKind.EXPORTER_GUI: { // there is no output from exporter return false; } case NodeKind.BUNDLEBUILDER_GUI: { switch (to.Kind) { case NodeKind.FILTER_GUI: case NodeKind.GROUPING_GUI: case NodeKind.EXPORTER_GUI: case NodeKind.BUNDLECONFIG_GUI: return true; } return false; } case NodeKind.BUNDLECONFIG_GUI: { switch (to.Kind) { case NodeKind.BUNDLEBUILDER_GUI: return true; } return false; } } return true; }
public static List <string> GetCachedDataByNode(BuildTarget t, NodeData node) { switch (node.Kind) { case NodeKind.IMPORTSETTING_GUI: { // no cache file exists for importSetting. return(new List <string>()); } case NodeKind.MODIFIER_GUI: { // no cache file exists for modifier. return(new List <string>()); } case NodeKind.PREFABBUILDER_GUI: { var cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.PREFABBUILDER_CACHE_PLACE, node.Id, SystemDataUtility.GetPathSafeTargetName(t) ); // no cache folder, no cache. if (!Directory.Exists(cachedPathBase)) { // search default platform + package cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.PREFABBUILDER_CACHE_PLACE, node.Id, SystemDataUtility.GetPathSafeDefaultTargetName() ); if (!Directory.Exists(cachedPathBase)) { return(new List <string>()); } } return(FileUtility.GetFilePathsInFolder(cachedPathBase)); } case NodeKind.BUNDLECONFIG_GUI: { // do nothing. break; } case NodeKind.BUNDLEBUILDER_GUI: { var cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, node.Id, SystemDataUtility.GetPathSafeTargetName(t) ); // no cache folder, no cache. if (!Directory.Exists(cachedPathBase)) { // search default platform + package cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, node.Id, SystemDataUtility.GetPathSafeDefaultTargetName() ); if (!Directory.Exists(cachedPathBase)) { return(new List <string>()); } } return(FileUtility.GetFilePathsInFolder(cachedPathBase)); } default: { // nothing to do. break; } } return(new List <string>()); }
public void Import(V1.NodeData v1, Model.NodeData v2) { // do nothing }
public static void ValidateConnection(NodeData from, NodeData to) { if(!CanConnect(from, to)) { throw new AssetBundleGraphException(to.Kind + " does not accept connection from " + from.Kind); } }
public void Import(V1.NodeData v1, Model.NodeData v2) { m_instance = new SerializableMultiTargetInstance(v1.ScriptClassName, v1.InstanceData); m_replacePrefabOptions = v1.ReplacePrefabOptions; }
/** * Duplicate this node with new guid. */ public NodeData Duplicate() { var newData = new NodeData(m_name, m_kind, m_x, m_y); switch(m_kind) { case NodeKind.IMPORTSETTING_GUI: break; case NodeKind.PREFABBUILDER_GUI: case NodeKind.MODIFIER_GUI: newData.m_scriptClassName = m_scriptClassName; newData.m_scriptInstanceData = new SerializableMultiTargetString(m_scriptInstanceData); break; case NodeKind.FILTER_GUI: foreach(var f in m_filter) { newData.AddFilterCondition(f.FilterKeyword, f.FilterKeytype); } break; case NodeKind.LOADER_GUI: newData.m_loaderLoadPath = new SerializableMultiTargetString(m_loaderLoadPath); break; case NodeKind.GROUPING_GUI: newData.m_groupingKeyword = new SerializableMultiTargetString(m_groupingKeyword); break; case NodeKind.BUNDLECONFIG_GUI: foreach(var v in m_variants) { newData.AddVariant(v.Name); } break; case NodeKind.BUNDLEBUILDER_GUI: newData.m_bundleBuilderEnabledBundleOptions = new SerializableMultiTargetInt(m_bundleBuilderEnabledBundleOptions); break; case NodeKind.EXPORTER_GUI: newData.m_exporterExportPath = new SerializableMultiTargetString(m_exporterExportPath); break; default: throw new AssetBundleGraphException("[FATAL]Unhandled nodekind. unimplmented:"+ m_kind); } return newData; }
public static Node CreateNodeFromV1NodeData(V1.NodeData v1, NodeData data) { NodeDataImporter imp = null; Node n = null; switch (v1.Kind) { case V1.NodeKind.LOADER_GUI: { var v = new Loader(); imp = v; n = v; } break; case V1.NodeKind.FILTER_GUI: { var v = new Filter(); imp = v; n = v; } break; case V1.NodeKind.IMPORTSETTING_GUI: { var v = new ImportSetting(); imp = v; n = v; } break; case V1.NodeKind.MODIFIER_GUI: { var v = new Modifier(); imp = v; n = v; } break; case V1.NodeKind.GROUPING_GUI: { var v = new Grouping(); imp = v; n = v; } break; case V1.NodeKind.PREFABBUILDER_GUI: { var v = new PrefabBuilder(); imp = v; n = v; } break; case V1.NodeKind.BUNDLECONFIG_GUI: { var v = new BundleConfigurator(); imp = v; n = v; } break; case V1.NodeKind.BUNDLEBUILDER_GUI: { var v = new BundleBuilder(); imp = v; n = v; } break; case V1.NodeKind.EXPORTER_GUI: { var v = new Exporter(); imp = v; n = v; } break; } n.Initialize(data); imp.Import(v1, data); return(n); }
/** * 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); } }