// Unity C# reference source // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License using System; using System.Collections.Generic; using UnityEngine; namespace UnityEditor.Experimental.GraphView { [Serializable] internal struct DataBag { [SerializeField] private List customDataKeys; [SerializeField] private List customDataValues; [SerializeField] private List customDataKeyIndex; public DataBag(ref DataBag other) { customDataKeys = other.customDataKeys != null ? new List(other.customDataKeys) : null; customDataValues = other.customDataValues != null ? new List(other.customDataValues) : null; customDataKeyIndex = other.customDataKeyIndex != null ? new List(other.customDataKeyIndex) : null; } /// /// Add a custom data to the template. /// /// Key identifier for the data /// Value of the data public void AddCustomData(string key, string value) { customDataKeys ??= new List(); customDataValues ??= new List(); customDataKeyIndex ??= new List(); var keyIndex = customDataKeys.IndexOf(key); if (keyIndex < 0) { keyIndex = customDataKeys.Count; customDataKeys.Add(key); } customDataValues.Add(value); customDataKeyIndex.Add(keyIndex); } /// /// Remove all custom data associated with the specified key. /// /// Key of the custom data public void RemoveCustomData(string key) { var keyIndex = customDataKeys?.IndexOf(key) ?? -1; if (keyIndex >= 0) { var indexToRemove = new List(); for (var i = 0; i < customDataValues.Count; ++i) { if (customDataKeyIndex[i] == keyIndex) { indexToRemove.Add(i); } } foreach (var index in indexToRemove) { customDataValues.RemoveAt(index); customDataKeyIndex.RemoveAt(index); } customDataKeys.RemoveAt(keyIndex); } } /// /// Remove all custom data associated with the specified key. /// /// Key of the custom data /// Value of the custom data public void RemoveCustomData(string key, string value) { var keyIndex = customDataKeys?.IndexOf(key) ?? -1; if (keyIndex >= 0) { var indexToRemove = new List(); for (var i = 0; i < customDataValues.Count; ++i) { if (customDataKeyIndex[i] == keyIndex && customDataValues[i] == value) { indexToRemove.Add(i); } } foreach (var index in indexToRemove) { customDataValues.RemoveAt(index); customDataKeyIndex.RemoveAt(index); } // If there are no more values for this key, remove the key itself if (customDataKeyIndex.IndexOf(keyIndex) < 0) { customDataKeys.RemoveAt(keyIndex); } } } public Dictionary> GetCustomData(string keyPrefix) { var dictionary = new Dictionary>(); var count = customDataValues?.Count ?? 0; for (var i = 0; i < count; i++) { var keyIndex = customDataKeyIndex[i]; var key = keyPrefix + customDataKeys[keyIndex]; var value = customDataValues[i]; if (!dictionary.TryGetValue(key, out var values)) { dictionary[key] = new List { value }; } else { values.Add(value); } } return dictionary; } } /// /// This is a very basic interface to have a common type for template descriptors and template sections /// interface ITemplateDescriptor { string header { get; } } /// /// Template descriptor /// [Serializable] internal struct GraphViewTemplateDescriptor : ITemplateDescriptor, IComparable { /// /// Name of the template which will be displayed in the template window /// public string name = null; /// /// Category is used to group templates together in the template window /// public string category = null; /// /// Give some description to your template so that we know what it's doing /// public string description = null; /// /// This icon is displayed next to the name in the template window /// public Texture2D icon = null; /// /// Thumbnail is displayed with the description in the details panel of the template window /// public Texture2D thumbnail = null; /// /// Allow to sort templates in its category /// public int order = 0; [SerializeField] private string toolKey; /// /// Internal use only: make the bound with the asset /// [NonSerialized] internal string assetGuid = null; /// /// Internal use only: allow to sort built-in template category first /// [NonSerialized] internal int internalOrder = 0; /// /// Same as the name, inherited from the interface ITemplateDescriptor /// public string header => name; /// /// Lowercase tool key, used to prefix indexed data /// public string ToolKey => toolKey; /// /// Create a new GraphViewTemplateDescriptor with the specified tool key. /// /// Toolkey allows to identify to which tool this template belongs to public GraphViewTemplateDescriptor(string toolKey) { this.toolKey = toolKey.ToLowerInvariant(); } public int CompareTo(GraphViewTemplateDescriptor other) { return order.CompareTo(other.order); } internal DateTime GetModificationDate() { var filePath = AssetDatabase.GUIDToAssetPath(assetGuid); if (!string.IsNullOrEmpty(filePath)) { var fullPath = System.IO.Path.GetFullPath(filePath); var assetModificationTime = System.IO.File.GetLastWriteTimeUtc(fullPath); var metaModificationTime = System.IO.File.GetLastWriteTimeUtc(fullPath + ".meta"); return assetModificationTime > metaModificationTime ? assetModificationTime : metaModificationTime; } return DateTime.MinValue; } } }