using System.Collections.Generic; using UnityEngine; namespace TMPro { public class MaterialReferenceManager { private static MaterialReferenceManager s_Instance; // Dictionaries used to track Asset references. private Dictionary m_FontMaterialReferenceLookup = new Dictionary(); private Dictionary m_FontAssetReferenceLookup = new Dictionary(); private Dictionary m_SpriteAssetReferenceLookup = new Dictionary(); private Dictionary m_ColorGradientReferenceLookup = new Dictionary(); /// /// Get a singleton instance of the registry /// public static MaterialReferenceManager instance { get { if (MaterialReferenceManager.s_Instance == null) MaterialReferenceManager.s_Instance = new MaterialReferenceManager(); return MaterialReferenceManager.s_Instance; } } /// /// Add new font asset reference to dictionary. /// /// public static void AddFontAsset(TMP_FontAsset fontAsset) { MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset); } /// /// Add new Font Asset reference to dictionary. /// /// private void AddFontAssetInternal(TMP_FontAsset fontAsset) { if (m_FontAssetReferenceLookup.ContainsKey(fontAsset.hashCode)) return; // Add reference to the font asset. m_FontAssetReferenceLookup.Add(fontAsset.hashCode, fontAsset); // Add reference to the font material. m_FontMaterialReferenceLookup.Add(fontAsset.materialHashCode, fontAsset.material); } /// /// Add new Sprite Asset to dictionary. /// /// /// public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset) { MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset); } /// /// Internal method to add a new sprite asset to the dictionary. /// /// /// private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset) { if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return; // Add reference to sprite asset. m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset); // Adding reference to the sprite asset material as well m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material); } /// /// Add new Sprite Asset to dictionary. /// /// /// public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset) { MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset); } /// /// Internal method to add a new sprite asset to the dictionary. /// /// /// private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset) { if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return; // Add reference to Sprite Asset. m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset); // Add reference to Sprite Asset using the asset hashcode. m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material); // Compatibility check if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode; } /// /// Add new Material reference to dictionary. /// /// /// public static void AddFontMaterial(int hashCode, Material material) { MaterialReferenceManager.instance.AddFontMaterialInternal(hashCode, material); } /// /// Add new material reference to dictionary. /// /// /// private void AddFontMaterialInternal(int hashCode, Material material) { // Since this function is called after checking if the material is // contained in the dictionary, there is no need to check again. m_FontMaterialReferenceLookup.Add(hashCode, material); } /// /// Add new Color Gradient Preset to dictionary. /// /// /// public static void AddColorGradientPreset(int hashCode, TMP_ColorGradient spriteAsset) { MaterialReferenceManager.instance.AddColorGradientPreset_Internal(hashCode, spriteAsset); } /// /// Internal method to add a new Color Gradient Preset to the dictionary. /// /// /// private void AddColorGradientPreset_Internal(int hashCode, TMP_ColorGradient spriteAsset) { if (m_ColorGradientReferenceLookup.ContainsKey(hashCode)) return; // Add reference to Color Gradient Preset Asset. m_ColorGradientReferenceLookup.Add(hashCode, spriteAsset); } /// /// Add new material reference and return the index of this new reference in the materialReferences array. /// /// /// /// //public int AddMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // int index = m_MaterialReferenceLookup.Count; // materialReferences[index].fontAsset = fontAsset; // materialReferences[index].material = material; // materialReferences[index].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false; // materialReferences[index].index = index; // materialReferences[index].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = index; // // Compute Padding value and store it // // TODO // int fontAssetHashCode = fontAsset.hashCode; // if (!m_FontAssetReferenceLookup.ContainsKey(fontAssetHashCode)) // m_FontAssetReferenceLookup.Add(fontAssetHashCode, fontAsset); // m_countInternal += 1; // return index; // } // else // { // return m_MaterialReferenceLookup[materialHashCode]; // } //} /// /// Add new material reference and return the index of this new reference in the materialReferences array. /// /// /// /// /// //public int AddMaterial(Material material, int materialHashCode, TMP_SpriteAsset spriteAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // int index = m_MaterialReferenceLookup.Count; // materialReferences[index].fontAsset = materialReferences[0].fontAsset; // materialReferences[index].spriteAsset = spriteAsset; // materialReferences[index].material = material; // materialReferences[index].isDefaultMaterial = true; // materialReferences[index].index = index; // materialReferences[index].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = index; // int spriteAssetHashCode = spriteAsset.hashCode; // if (!m_SpriteAssetReferenceLookup.ContainsKey(spriteAssetHashCode)) // m_SpriteAssetReferenceLookup.Add(spriteAssetHashCode, spriteAsset); // m_countInternal += 1; // return index; // } // else // { // return m_MaterialReferenceLookup[materialHashCode]; // } //} /// /// Function to check if the font asset is already referenced. /// /// /// public bool Contains(TMP_FontAsset font) { return m_FontAssetReferenceLookup.ContainsKey(font.hashCode); } /// /// Function to check if the sprite asset is already referenced. /// /// /// public bool Contains(TMP_SpriteAsset sprite) { return m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode); } /// /// Function returning the Font Asset corresponding to the provided hash code. /// /// /// /// public static bool TryGetFontAsset(int hashCode, out TMP_FontAsset fontAsset) { return MaterialReferenceManager.instance.TryGetFontAssetInternal(hashCode, out fontAsset); } /// /// Internal Function returning the Font Asset corresponding to the provided hash code. /// /// /// /// private bool TryGetFontAssetInternal(int hashCode, out TMP_FontAsset fontAsset) { fontAsset = null; return m_FontAssetReferenceLookup.TryGetValue(hashCode, out fontAsset); } /// /// Function returning the Sprite Asset corresponding to the provided hash code. /// /// /// /// public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset) { return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset); } /// /// Internal function returning the Sprite Asset corresponding to the provided hash code. /// /// /// /// private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset) { spriteAsset = null; return m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset); } /// /// Function returning the Color Gradient Preset corresponding to the provided hash code. /// /// /// /// public static bool TryGetColorGradientPreset(int hashCode, out TMP_ColorGradient gradientPreset) { return MaterialReferenceManager.instance.TryGetColorGradientPresetInternal(hashCode, out gradientPreset); } /// /// Internal function returning the Color Gradient Preset corresponding to the provided hash code. /// /// /// /// private bool TryGetColorGradientPresetInternal(int hashCode, out TMP_ColorGradient gradientPreset) { gradientPreset = null; return m_ColorGradientReferenceLookup.TryGetValue(hashCode, out gradientPreset); } /// /// Function returning the Font Material corresponding to the provided hash code. /// /// /// /// public static bool TryGetMaterial(int hashCode, out Material material) { return MaterialReferenceManager.instance.TryGetMaterialInternal(hashCode, out material); } /// /// Internal function returning the Font Material corresponding to the provided hash code. /// /// /// /// private bool TryGetMaterialInternal(int hashCode, out Material material) { material = null; return m_FontMaterialReferenceLookup.TryGetValue(hashCode, out material); } /// /// Function to lookup a material based on hash code and returning the MaterialReference containing this material. /// /// /// /// //public bool TryGetMaterial(int hashCode, out MaterialReference materialReference) //{ // int materialIndex = -1; // if (m_MaterialReferenceLookup.TryGetValue(hashCode, out materialIndex)) // { // materialReference = materialReferences[materialIndex]; // return true; // } // materialReference = new MaterialReference(); // return false; //} /// /// /// /// /// //public int GetMaterialIndex(TMP_FontAsset fontAsset) //{ // if (m_MaterialReferenceLookup.ContainsKey(fontAsset.materialHashCode)) // return m_MaterialReferenceLookup[fontAsset.materialHashCode]; // return -1; //} /// /// /// /// /// //public TMP_FontAsset GetFontAsset(int index) //{ // if (index >= 0 && index < materialReferences.Length) // return materialReferences[index].fontAsset; // return null; //} /// /// /// /// /// /// //public void SetDefaultMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset) //{ // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode)) // { // materialReferences[0].fontAsset = fontAsset; // materialReferences[0].material = material; // materialReferences[0].index = 0; // materialReferences[0].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false; // materialReferences[0].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = 0; // // Compute Padding value and store it // // TODO // int fontHashCode = fontAsset.hashCode; // if (!m_FontAssetReferenceLookup.ContainsKey(fontHashCode)) // m_FontAssetReferenceLookup.Add(fontHashCode, fontAsset); // } // else // { // materialReferences[0].fontAsset = fontAsset; // materialReferences[0].material = material; // materialReferences[0].index = 0; // materialReferences[0].referenceCount = 0; // m_MaterialReferenceLookup[materialHashCode] = 0; // } // // Compute padding // // TODO // m_countInternal = 1; //} /// /// /// //public void Clear() //{ // //m_currentIndex = 0; // m_MaterialReferenceLookup.Clear(); // m_SpriteAssetReferenceLookup.Clear(); // m_FontAssetReferenceLookup.Clear(); //} /// /// Function to clear the reference count for each of the material references. /// //public void ClearReferenceCount() //{ // m_countInternal = 0; // for (int i = 0; i < materialReferences.Length; i++) // { // if (materialReferences[i].fontAsset == null) // return; // materialReferences[i].referenceCount = 0; // } //} } public struct TMP_MaterialReference { public Material material; public int referenceCount; } public struct MaterialReference { public int index; public TMP_FontAsset fontAsset; public TMP_SpriteAsset spriteAsset; public Material material; public bool isDefaultMaterial; public bool isFallbackMaterial; public Material fallbackMaterial; public float padding; public int referenceCount; /// /// Constructor for new Material Reference. /// /// /// /// /// /// public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding) { this.index = index; this.fontAsset = fontAsset; this.spriteAsset = spriteAsset; this.material = material; this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID(); this.isFallbackMaterial = false; this.fallbackMaterial = null; this.padding = padding; this.referenceCount = 0; } /// /// Function to check if a certain font asset is contained in the material reference array. /// /// /// /// public static bool Contains(MaterialReference[] materialReferences, TMP_FontAsset fontAsset) { int id = fontAsset.GetInstanceID(); for (int i = 0; i < materialReferences.Length && materialReferences[i].fontAsset != null; i++) { if (materialReferences[i].fontAsset.GetInstanceID() == id) return true; } return false; } /// /// Function to add a new material reference and returning its index in the material reference array. /// /// /// /// /// /// public static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, ref MaterialReference[] materialReferences, Dictionary materialReferenceIndexLookup) { int materialID = material.GetInstanceID(); int index; if (materialReferenceIndexLookup.TryGetValue(materialID, out index)) return index; index = materialReferenceIndexLookup.Count; // Add new reference index materialReferenceIndexLookup[materialID] = index; if (index >= materialReferences.Length) System.Array.Resize(ref materialReferences, Mathf.NextPowerOfTwo(index + 1)); materialReferences[index].index = index; materialReferences[index].fontAsset = fontAsset; materialReferences[index].spriteAsset = null; materialReferences[index].material = material; materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID(); materialReferences[index].referenceCount = 0; return index; } /// /// /// /// /// /// /// /// public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, ref MaterialReference[] materialReferences, Dictionary materialReferenceIndexLookup) { int materialID = material.GetInstanceID(); int index; if (materialReferenceIndexLookup.TryGetValue(materialID, out index)) return index; index = materialReferenceIndexLookup.Count; // Add new reference index materialReferenceIndexLookup[materialID] = index; if (index >= materialReferences.Length) System.Array.Resize(ref materialReferences, Mathf.NextPowerOfTwo(index + 1)); materialReferences[index].index = index; materialReferences[index].fontAsset = materialReferences[0].fontAsset; materialReferences[index].spriteAsset = spriteAsset; materialReferences[index].material = material; materialReferences[index].isDefaultMaterial = true; materialReferences[index].referenceCount = 0; return index; } } }