public void DuplicatePropertyTest() { // public void AddGraphInput(ShaderInput input, int index = -1) // public void RemoveGraphInput(ShaderInput input) // public ShaderInput AddCopyOfShaderInput(ShaderInput source, int insertIndex = -1) var B = new Vector4ShaderProperty() { displayName = "B" }; // add it twice! m_Graph.AddGraphInput(B); var B2 = m_Graph.AddCopyOfShaderInput(B); var B3 = m_Graph.AddCopyOfShaderInput(B); // check that both names have been made unique Assert.IsTrue(B.displayName != B2.displayName); Assert.IsTrue(B.displayName != B3.displayName); Assert.IsTrue(B2.displayName != B3.displayName); Assert.IsTrue(B.referenceName != B2.referenceName); Assert.IsTrue(B.referenceName != B3.referenceName); Assert.IsTrue(B2.referenceName != B3.referenceName); // set overrides, so that B3 is now called "B" B.SetDisplayNameAndSanitizeForGraph(m_Graph, "Q"); // display name "Q" reference name default "Q" B3.SetDisplayNameAndSanitizeForGraph(m_Graph, "B"); // display name "B" reference name default "B" // since reference names should still be using default behavior of tracking display names, // B3 ref name should now be called "B" Assert.IsTrue(B.referenceName == "Q"); Assert.IsTrue(B3.referenceName == "B"); // now let's try overriding the reference names B3.SetReferenceNameAndSanitizeForGraph(m_Graph, "B3"); // display name "B" reference name "B3" B.SetReferenceNameAndSanitizeForGraph(m_Graph, "B"); // display name "Q" reference name "B" Assert.IsTrue(B.referenceName == "B"); Assert.IsTrue(B3.referenceName == "B3"); // now let's try resetting the reference name B3.ResetReferenceName(m_Graph); // display name "B", reference name default (can't be "B" because of collisions) Assert.IsTrue(B3.referenceName != "B"); // let's check everything is still unique Assert.IsTrue(B.displayName != B2.displayName); Assert.IsTrue(B.displayName != B3.displayName); Assert.IsTrue(B2.displayName != B3.displayName); Assert.IsTrue(B.referenceName != B2.referenceName); Assert.IsTrue(B.referenceName != B3.referenceName); Assert.IsTrue(B2.referenceName != B3.referenceName); }
void CopyShaderInput(GraphData graphData) { AssertHelpers.IsNotNull(graphData, "GraphData is null while carrying out CopyShaderInputAction"); AssertHelpers.IsNotNull(shaderInputToCopy, "ShaderInputToCopy is null while carrying out CopyShaderInputAction"); // Don't handle undo here as there are different contexts in which this action is used, that define the undo action namea // TODO: Perhaps a sign that each of those need to be made their own actions instead of conflating intent into a single action switch (shaderInputToCopy) { case AbstractShaderProperty property: var copiedProperty = (AbstractShaderProperty)graphData.AddCopyOfShaderInput(property, insertIndex); if (copiedProperty != null) // some property types cannot be duplicated (unknown types) { // Update the property nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is PropertyNode propertyNode) { propertyNode.owner = graphData; propertyNode.property = copiedProperty; } } } copiedShaderInput = copiedProperty; break; case ShaderKeyword shaderKeyword: // Don't duplicate built-in keywords within the same graph if (shaderKeyword.isBuiltIn && graphData.keywords.Any(p => p.referenceName == shaderInputToCopy.referenceName)) { return; } var copiedKeyword = (ShaderKeyword)graphData.AddCopyOfShaderInput(shaderKeyword, insertIndex); // Update the keyword nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is KeywordNode propertyNode) { propertyNode.owner = graphData; propertyNode.keyword = copiedKeyword; } } copiedShaderInput = copiedKeyword; break; default: throw new ArgumentOutOfRangeException(); } }
void AddBuiltinKeyword(GenericMenu gm, ShaderKeyword keyword) { if (m_Graph.keywords.Where(x => x.referenceName == keyword.referenceName).Any()) { gm.AddDisabledItem(new GUIContent($"Keyword/{keyword.displayName}")); } else { gm.AddItem(new GUIContent($"Keyword/{keyword.displayName}"), false, () => AddInputRow(m_Graph.AddCopyOfShaderInput(keyword))); } }
void CopyShaderInput(GraphData graphData) { AssertHelpers.IsNotNull(graphData, "GraphData is null while carrying out CopyShaderInputAction"); AssertHelpers.IsNotNull(shaderInputToCopy, "ShaderInputToCopy is null while carrying out CopyShaderInputAction"); // Don't handle undo here as there are different contexts in which this action is used, that define the undo action // TODO: Perhaps a sign that each of those need to be made their own actions instead of conflating intent into a single action switch (shaderInputToCopy) { case AbstractShaderProperty property: var copiedProperty = (AbstractShaderProperty)graphData.AddCopyOfShaderInput(property, insertIndex); if (copiedProperty != null) // some property types cannot be duplicated (unknown types) { // Update the property nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is PropertyNode propertyNode) { propertyNode.owner = graphData; propertyNode.property = copiedProperty; } } } copiedShaderInput = copiedProperty; break; case ShaderKeyword shaderKeyword: // Don't duplicate built-in keywords within the same graph if (shaderKeyword.isBuiltIn && graphData.keywords.Any(p => p.referenceName == shaderInputToCopy.referenceName)) { return; } var copiedKeyword = (ShaderKeyword)graphData.AddCopyOfShaderInput(shaderKeyword, insertIndex); // Update the keyword nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is KeywordNode propertyNode) { propertyNode.owner = graphData; propertyNode.keyword = copiedKeyword; } } copiedShaderInput = copiedKeyword; break; case ShaderDropdown shaderDropdown: var copiedDropdown = (ShaderDropdown)graphData.AddCopyOfShaderInput(shaderDropdown, insertIndex); // Update the dropdown nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is DropdownNode propertyNode) { propertyNode.owner = graphData; propertyNode.dropdown = copiedDropdown; } } copiedShaderInput = copiedDropdown; break; default: throw new ArgumentOutOfRangeException(); } if (copiedShaderInput != null) { // If specific category to copy to is provided, find and use it foreach (var category in graphData.categories) { if (category.categoryGuid == containingCategoryGuid) { graphData.InsertItemIntoCategory(category.objectId, copiedShaderInput, insertIndex); return; } } // Else, add to default category graphData.categories.First().InsertItemIntoCategory(copiedShaderInput); } }
void CopyShaderInput(GraphData graphData) { AssertHelpers.IsNotNull(graphData, "GraphData is null while carrying out CopyShaderInputAction"); AssertHelpers.IsNotNull(shaderInputToCopy, "ShaderInputToCopy is null while carrying out CopyShaderInputAction"); // Don't handle undo here as there are different contexts in which this action is used, that define the undo action // TODO: Perhaps a sign that each of those need to be made their own actions instead of conflating intent into a single action switch (shaderInputToCopy) { case AbstractShaderProperty property: insertIndex = Mathf.Clamp(insertIndex, -1, graphData.properties.Count() - 1); var copiedProperty = (AbstractShaderProperty)graphData.AddCopyOfShaderInput(property, insertIndex); if (copiedProperty != null) // some property types cannot be duplicated (unknown types) { // Update the property nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is PropertyNode propertyNode) { propertyNode.owner = graphData; propertyNode.property = copiedProperty; } } } copiedShaderInput = copiedProperty; break; case ShaderKeyword shaderKeyword: // InsertIndex gets passed in relative to the blackboard position of an item overall, // and not relative to the array sizes of the properties/keywords/dropdowns var keywordInsertIndex = insertIndex - graphData.properties.Count(); keywordInsertIndex = Mathf.Clamp(keywordInsertIndex, -1, graphData.keywords.Count() - 1); // Don't duplicate built-in keywords within the same graph if (shaderKeyword.isBuiltIn && graphData.keywords.Any(p => p.referenceName == shaderInputToCopy.referenceName)) { return; } var copiedKeyword = (ShaderKeyword)graphData.AddCopyOfShaderInput(shaderKeyword, keywordInsertIndex); // Update the keyword nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is KeywordNode propertyNode) { propertyNode.owner = graphData; propertyNode.keyword = copiedKeyword; } } copiedShaderInput = copiedKeyword; break; case ShaderDropdown shaderDropdown: // InsertIndex gets passed in relative to the blackboard position of an item overall, // and not relative to the array sizes of the properties/keywords/dropdowns var dropdownInsertIndex = insertIndex - graphData.properties.Count() - graphData.keywords.Count(); dropdownInsertIndex = Mathf.Clamp(dropdownInsertIndex, -1, graphData.dropdowns.Count() - 1); var copiedDropdown = (ShaderDropdown)graphData.AddCopyOfShaderInput(shaderDropdown, dropdownInsertIndex); // Update the dropdown nodes that depends on the copied node foreach (var node in dependentNodeList) { if (node is DropdownNode propertyNode) { propertyNode.owner = graphData; propertyNode.dropdown = copiedDropdown; } } copiedShaderInput = copiedDropdown; break; default: throw new ArgumentOutOfRangeException(); } if (copiedShaderInput != null) { // If specific category to copy to is provided, find and use it foreach (var category in graphData.categories) { if (category.categoryGuid == containingCategoryGuid) { // Ensures that the new item gets added after the item it was duplicated from insertIndex += 1; // If the source item was already the last item in list, just add to end of list if (insertIndex >= category.childCount) { insertIndex = -1; } graphData.InsertItemIntoCategory(category.objectId, copiedShaderInput, insertIndex); return; } } // Else, add to default category graphData.categories.First().InsertItemIntoCategory(copiedShaderInput); } }