You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

646 lines
23 KiB

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace TMPro
  5. {
  6. public class MaterialReferenceManager
  7. {
  8. private static MaterialReferenceManager s_Instance;
  9. // Dictionaries used to track Asset references.
  10. private Dictionary<int, Material> m_FontMaterialReferenceLookup = new Dictionary<int, Material>();
  11. private Dictionary<int, TMP_FontAsset> m_FontAssetReferenceLookup = new Dictionary<int, TMP_FontAsset>();
  12. private Dictionary<int, TMP_SpriteAsset> m_SpriteAssetReferenceLookup = new Dictionary<int, TMP_SpriteAsset>();
  13. private Dictionary<int, TMP_ColorGradient> m_ColorGradientReferenceLookup = new Dictionary<int, TMP_ColorGradient>();
  14. /// <summary>
  15. /// Get a singleton instance of the registry
  16. /// </summary>
  17. public static MaterialReferenceManager instance
  18. {
  19. get
  20. {
  21. if (MaterialReferenceManager.s_Instance == null)
  22. MaterialReferenceManager.s_Instance = new MaterialReferenceManager();
  23. return MaterialReferenceManager.s_Instance;
  24. }
  25. }
  26. /// <summary>
  27. /// Add new font asset reference to dictionary.
  28. /// </summary>
  29. /// <param name="fontAsset"></param>
  30. public static void AddFontAsset(TMP_FontAsset fontAsset)
  31. {
  32. MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset);
  33. }
  34. /// <summary>
  35. /// Add new Font Asset reference to dictionary.
  36. /// </summary>
  37. /// <param name="fontAsset"></param>
  38. private void AddFontAssetInternal(TMP_FontAsset fontAsset)
  39. {
  40. if (m_FontAssetReferenceLookup.ContainsKey(fontAsset.hashCode)) return;
  41. // Add reference to the font asset.
  42. m_FontAssetReferenceLookup.Add(fontAsset.hashCode, fontAsset);
  43. // Add reference to the font material.
  44. m_FontMaterialReferenceLookup.Add(fontAsset.materialHashCode, fontAsset.material);
  45. }
  46. /// <summary>
  47. /// Add new Sprite Asset to dictionary.
  48. /// </summary>
  49. /// <param name="hashCode"></param>
  50. /// <param name="spriteAsset"></param>
  51. public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
  52. {
  53. MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset);
  54. }
  55. /// <summary>
  56. /// Internal method to add a new sprite asset to the dictionary.
  57. /// </summary>
  58. /// <param name="hashCode"></param>
  59. /// <param name="spriteAsset"></param>
  60. private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset)
  61. {
  62. if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return;
  63. // Add reference to sprite asset.
  64. m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset);
  65. // Adding reference to the sprite asset material as well
  66. m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material);
  67. }
  68. /// <summary>
  69. /// Add new Sprite Asset to dictionary.
  70. /// </summary>
  71. /// <param name="hashCode"></param>
  72. /// <param name="spriteAsset"></param>
  73. public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
  74. {
  75. MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset);
  76. }
  77. /// <summary>
  78. /// Internal method to add a new sprite asset to the dictionary.
  79. /// </summary>
  80. /// <param name="hashCode"></param>
  81. /// <param name="spriteAsset"></param>
  82. private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset)
  83. {
  84. if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return;
  85. // Add reference to Sprite Asset.
  86. m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset);
  87. // Add reference to Sprite Asset using the asset hashcode.
  88. m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material);
  89. // Compatibility check
  90. if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode;
  91. }
  92. /// <summary>
  93. /// Add new Material reference to dictionary.
  94. /// </summary>
  95. /// <param name="hashCode"></param>
  96. /// <param name="material"></param>
  97. public static void AddFontMaterial(int hashCode, Material material)
  98. {
  99. MaterialReferenceManager.instance.AddFontMaterialInternal(hashCode, material);
  100. }
  101. /// <summary>
  102. /// Add new material reference to dictionary.
  103. /// </summary>
  104. /// <param name="hashCode"></param>
  105. /// <param name="material"></param>
  106. private void AddFontMaterialInternal(int hashCode, Material material)
  107. {
  108. // Since this function is called after checking if the material is
  109. // contained in the dictionary, there is no need to check again.
  110. m_FontMaterialReferenceLookup.Add(hashCode, material);
  111. }
  112. /// <summary>
  113. /// Add new Color Gradient Preset to dictionary.
  114. /// </summary>
  115. /// <param name="hashCode"></param>
  116. /// <param name="spriteAsset"></param>
  117. public static void AddColorGradientPreset(int hashCode, TMP_ColorGradient spriteAsset)
  118. {
  119. MaterialReferenceManager.instance.AddColorGradientPreset_Internal(hashCode, spriteAsset);
  120. }
  121. /// <summary>
  122. /// Internal method to add a new Color Gradient Preset to the dictionary.
  123. /// </summary>
  124. /// <param name="hashCode"></param>
  125. /// <param name="spriteAsset"></param>
  126. private void AddColorGradientPreset_Internal(int hashCode, TMP_ColorGradient spriteAsset)
  127. {
  128. if (m_ColorGradientReferenceLookup.ContainsKey(hashCode)) return;
  129. // Add reference to Color Gradient Preset Asset.
  130. m_ColorGradientReferenceLookup.Add(hashCode, spriteAsset);
  131. }
  132. /// <summary>
  133. /// Add new material reference and return the index of this new reference in the materialReferences array.
  134. /// </summary>
  135. /// <param name="material"></param>
  136. /// <param name="materialHashCode"></param>
  137. /// <param name="fontAsset"></param>
  138. //public int AddMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
  139. //{
  140. // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
  141. // {
  142. // int index = m_MaterialReferenceLookup.Count;
  143. // materialReferences[index].fontAsset = fontAsset;
  144. // materialReferences[index].material = material;
  145. // materialReferences[index].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
  146. // materialReferences[index].index = index;
  147. // materialReferences[index].referenceCount = 0;
  148. // m_MaterialReferenceLookup[materialHashCode] = index;
  149. // // Compute Padding value and store it
  150. // // TODO
  151. // int fontAssetHashCode = fontAsset.hashCode;
  152. // if (!m_FontAssetReferenceLookup.ContainsKey(fontAssetHashCode))
  153. // m_FontAssetReferenceLookup.Add(fontAssetHashCode, fontAsset);
  154. // m_countInternal += 1;
  155. // return index;
  156. // }
  157. // else
  158. // {
  159. // return m_MaterialReferenceLookup[materialHashCode];
  160. // }
  161. //}
  162. /// <summary>
  163. /// Add new material reference and return the index of this new reference in the materialReferences array.
  164. /// </summary>
  165. /// <param name="material"></param>
  166. /// <param name="materialHashCode"></param>
  167. /// <param name="spriteAsset"></param>
  168. /// <returns></returns>
  169. //public int AddMaterial(Material material, int materialHashCode, TMP_SpriteAsset spriteAsset)
  170. //{
  171. // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
  172. // {
  173. // int index = m_MaterialReferenceLookup.Count;
  174. // materialReferences[index].fontAsset = materialReferences[0].fontAsset;
  175. // materialReferences[index].spriteAsset = spriteAsset;
  176. // materialReferences[index].material = material;
  177. // materialReferences[index].isDefaultMaterial = true;
  178. // materialReferences[index].index = index;
  179. // materialReferences[index].referenceCount = 0;
  180. // m_MaterialReferenceLookup[materialHashCode] = index;
  181. // int spriteAssetHashCode = spriteAsset.hashCode;
  182. // if (!m_SpriteAssetReferenceLookup.ContainsKey(spriteAssetHashCode))
  183. // m_SpriteAssetReferenceLookup.Add(spriteAssetHashCode, spriteAsset);
  184. // m_countInternal += 1;
  185. // return index;
  186. // }
  187. // else
  188. // {
  189. // return m_MaterialReferenceLookup[materialHashCode];
  190. // }
  191. //}
  192. /// <summary>
  193. /// Function to check if the font asset is already referenced.
  194. /// </summary>
  195. /// <param name="font"></param>
  196. /// <returns></returns>
  197. public bool Contains(TMP_FontAsset font)
  198. {
  199. if (m_FontAssetReferenceLookup.ContainsKey(font.hashCode))
  200. return true;
  201. return false;
  202. }
  203. /// <summary>
  204. /// Function to check if the sprite asset is already referenced.
  205. /// </summary>
  206. /// <param name="font"></param>
  207. /// <returns></returns>
  208. public bool Contains(TMP_SpriteAsset sprite)
  209. {
  210. if (m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode))
  211. return true;
  212. return false;
  213. }
  214. /// <summary>
  215. /// Function returning the Font Asset corresponding to the provided hash code.
  216. /// </summary>
  217. /// <param name="hashCode"></param>
  218. /// <param name="fontAsset"></param>
  219. /// <returns></returns>
  220. public static bool TryGetFontAsset(int hashCode, out TMP_FontAsset fontAsset)
  221. {
  222. return MaterialReferenceManager.instance.TryGetFontAssetInternal(hashCode, out fontAsset);
  223. }
  224. /// <summary>
  225. /// Internal Function returning the Font Asset corresponding to the provided hash code.
  226. /// </summary>
  227. /// <param name="hashCode"></param>
  228. /// <param name="fontAsset"></param>
  229. /// <returns></returns>
  230. private bool TryGetFontAssetInternal(int hashCode, out TMP_FontAsset fontAsset)
  231. {
  232. fontAsset = null;
  233. if (m_FontAssetReferenceLookup.TryGetValue(hashCode, out fontAsset))
  234. {
  235. return true;
  236. }
  237. return false;
  238. }
  239. /// <summary>
  240. /// Function returning the Sprite Asset corresponding to the provided hash code.
  241. /// </summary>
  242. /// <param name="hashCode"></param>
  243. /// <param name="spriteAsset"></param>
  244. /// <returns></returns>
  245. public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
  246. {
  247. return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset);
  248. }
  249. /// <summary>
  250. /// Internal function returning the Sprite Asset corresponding to the provided hash code.
  251. /// </summary>
  252. /// <param name="hashCode"></param>
  253. /// <param name="fontAsset"></param>
  254. /// <returns></returns>
  255. private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset)
  256. {
  257. spriteAsset = null;
  258. if (m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset))
  259. {
  260. return true;
  261. }
  262. return false;
  263. }
  264. /// <summary>
  265. /// Function returning the Color Gradient Preset corresponding to the provided hash code.
  266. /// </summary>
  267. /// <param name="hashCode"></param>
  268. /// <param name="gradientPreset"></param>
  269. /// <returns></returns>
  270. public static bool TryGetColorGradientPreset(int hashCode, out TMP_ColorGradient gradientPreset)
  271. {
  272. return MaterialReferenceManager.instance.TryGetColorGradientPresetInternal(hashCode, out gradientPreset);
  273. }
  274. /// <summary>
  275. /// Internal function returning the Color Gradient Preset corresponding to the provided hash code.
  276. /// </summary>
  277. /// <param name="hashCode"></param>
  278. /// <param name="fontAsset"></param>
  279. /// <returns></returns>
  280. private bool TryGetColorGradientPresetInternal(int hashCode, out TMP_ColorGradient gradientPreset)
  281. {
  282. gradientPreset = null;
  283. if (m_ColorGradientReferenceLookup.TryGetValue(hashCode, out gradientPreset))
  284. {
  285. return true;
  286. }
  287. return false;
  288. }
  289. /// <summary>
  290. /// Function returning the Font Material corresponding to the provided hash code.
  291. /// </summary>
  292. /// <param name="hashCode"></param>
  293. /// <param name="material"></param>
  294. /// <returns></returns>
  295. public static bool TryGetMaterial(int hashCode, out Material material)
  296. {
  297. return MaterialReferenceManager.instance.TryGetMaterialInternal(hashCode, out material);
  298. }
  299. /// <summary>
  300. /// Internal function returning the Font Material corresponding to the provided hash code.
  301. /// </summary>
  302. /// <param name="hashCode"></param>
  303. /// <param name="material"></param>
  304. /// <returns></returns>
  305. private bool TryGetMaterialInternal(int hashCode, out Material material)
  306. {
  307. material = null;
  308. if (m_FontMaterialReferenceLookup.TryGetValue(hashCode, out material))
  309. {
  310. return true;
  311. }
  312. return false;
  313. }
  314. /// <summary>
  315. /// Function to lookup a material based on hash code and returning the MaterialReference containing this material.
  316. /// </summary>
  317. /// <param name="hashCode"></param>
  318. /// <param name="material"></param>
  319. /// <returns></returns>
  320. //public bool TryGetMaterial(int hashCode, out MaterialReference materialReference)
  321. //{
  322. // int materialIndex = -1;
  323. // if (m_MaterialReferenceLookup.TryGetValue(hashCode, out materialIndex))
  324. // {
  325. // materialReference = materialReferences[materialIndex];
  326. // return true;
  327. // }
  328. // materialReference = new MaterialReference();
  329. // return false;
  330. //}
  331. /// <summary>
  332. ///
  333. /// </summary>
  334. /// <param name="fontAsset"></param>
  335. /// <returns></returns>
  336. //public int GetMaterialIndex(TMP_FontAsset fontAsset)
  337. //{
  338. // if (m_MaterialReferenceLookup.ContainsKey(fontAsset.materialHashCode))
  339. // return m_MaterialReferenceLookup[fontAsset.materialHashCode];
  340. // return -1;
  341. //}
  342. /// <summary>
  343. ///
  344. /// </summary>
  345. /// <param name="index"></param>
  346. /// <returns></returns>
  347. //public TMP_FontAsset GetFontAsset(int index)
  348. //{
  349. // if (index >= 0 && index < materialReferences.Length)
  350. // return materialReferences[index].fontAsset;
  351. // return null;
  352. //}
  353. /// <summary>
  354. ///
  355. /// </summary>
  356. /// <param name="material"></param>
  357. /// <param name="materialHashCode"></param>
  358. /// <param name="fontAsset"></param>
  359. //public void SetDefaultMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
  360. //{
  361. // if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
  362. // {
  363. // materialReferences[0].fontAsset = fontAsset;
  364. // materialReferences[0].material = material;
  365. // materialReferences[0].index = 0;
  366. // materialReferences[0].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
  367. // materialReferences[0].referenceCount = 0;
  368. // m_MaterialReferenceLookup[materialHashCode] = 0;
  369. // // Compute Padding value and store it
  370. // // TODO
  371. // int fontHashCode = fontAsset.hashCode;
  372. // if (!m_FontAssetReferenceLookup.ContainsKey(fontHashCode))
  373. // m_FontAssetReferenceLookup.Add(fontHashCode, fontAsset);
  374. // }
  375. // else
  376. // {
  377. // materialReferences[0].fontAsset = fontAsset;
  378. // materialReferences[0].material = material;
  379. // materialReferences[0].index = 0;
  380. // materialReferences[0].referenceCount = 0;
  381. // m_MaterialReferenceLookup[materialHashCode] = 0;
  382. // }
  383. // // Compute padding
  384. // // TODO
  385. // m_countInternal = 1;
  386. //}
  387. /// <summary>
  388. ///
  389. /// </summary>
  390. //public void Clear()
  391. //{
  392. // //m_currentIndex = 0;
  393. // m_MaterialReferenceLookup.Clear();
  394. // m_SpriteAssetReferenceLookup.Clear();
  395. // m_FontAssetReferenceLookup.Clear();
  396. //}
  397. /// <summary>
  398. /// Function to clear the reference count for each of the material references.
  399. /// </summary>
  400. //public void ClearReferenceCount()
  401. //{
  402. // m_countInternal = 0;
  403. // for (int i = 0; i < materialReferences.Length; i++)
  404. // {
  405. // if (materialReferences[i].fontAsset == null)
  406. // return;
  407. // materialReferences[i].referenceCount = 0;
  408. // }
  409. //}
  410. }
  411. public struct MaterialReference
  412. {
  413. public int index;
  414. public TMP_FontAsset fontAsset;
  415. public TMP_SpriteAsset spriteAsset;
  416. public Material material;
  417. public bool isDefaultMaterial;
  418. public bool isFallbackMaterial;
  419. public Material fallbackMaterial;
  420. public float padding;
  421. public int referenceCount;
  422. /// <summary>
  423. /// Constructor for new Material Reference.
  424. /// </summary>
  425. /// <param name="index"></param>
  426. /// <param name="fontAsset"></param>
  427. /// <param name="spriteAsset"></param>
  428. /// <param name="material"></param>
  429. /// <param name="padding"></param>
  430. public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding)
  431. {
  432. this.index = index;
  433. this.fontAsset = fontAsset;
  434. this.spriteAsset = spriteAsset;
  435. this.material = material;
  436. this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
  437. this.isFallbackMaterial = false;
  438. this.fallbackMaterial = null;
  439. this.padding = padding;
  440. this.referenceCount = 0;
  441. }
  442. /// <summary>
  443. /// Function to check if a certain font asset is contained in the material reference array.
  444. /// </summary>
  445. /// <param name="materialReferences"></param>
  446. /// <param name="fontAsset"></param>
  447. /// <returns></returns>
  448. public static bool Contains(MaterialReference[] materialReferences, TMP_FontAsset fontAsset)
  449. {
  450. int id = fontAsset.GetInstanceID();
  451. for (int i = 0; i < materialReferences.Length && materialReferences[i].fontAsset != null; i++)
  452. {
  453. if (materialReferences[i].fontAsset.GetInstanceID() == id)
  454. return true;
  455. }
  456. return false;
  457. }
  458. /// <summary>
  459. /// Function to add a new material reference and returning its index in the material reference array.
  460. /// </summary>
  461. /// <param name="material"></param>
  462. /// <param name="fontAsset"></param>
  463. /// <param name="materialReferences"></param>
  464. /// <param name="materialReferenceIndexLookup"></param>
  465. /// <returns></returns>
  466. public static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
  467. {
  468. int materialID = material.GetInstanceID();
  469. int index = 0;
  470. if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
  471. {
  472. return index;
  473. }
  474. else
  475. {
  476. index = materialReferenceIndexLookup.Count;
  477. // Add new reference index
  478. materialReferenceIndexLookup[materialID] = index;
  479. materialReferences[index].index = index;
  480. materialReferences[index].fontAsset = fontAsset;
  481. materialReferences[index].spriteAsset = null;
  482. materialReferences[index].material = material;
  483. materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID() ? true : false;
  484. //materialReferences[index].padding = 0;
  485. materialReferences[index].referenceCount = 0;
  486. return index;
  487. }
  488. }
  489. /// <summary>
  490. ///
  491. /// </summary>
  492. /// <param name="material"></param>
  493. /// <param name="spriteAsset"></param>
  494. /// <param name="materialReferences"></param>
  495. /// <param name="materialReferenceIndexLookup"></param>
  496. /// <returns></returns>
  497. public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
  498. {
  499. int materialID = material.GetInstanceID();
  500. int index = 0;
  501. if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
  502. {
  503. return index;
  504. }
  505. else
  506. {
  507. index = materialReferenceIndexLookup.Count;
  508. // Add new reference index
  509. materialReferenceIndexLookup[materialID] = index;
  510. materialReferences[index].index = index;
  511. materialReferences[index].fontAsset = materialReferences[0].fontAsset;
  512. materialReferences[index].spriteAsset = spriteAsset;
  513. materialReferences[index].material = material;
  514. materialReferences[index].isDefaultMaterial = true;
  515. //materialReferences[index].padding = 0;
  516. materialReferences[index].referenceCount = 0;
  517. return index;
  518. }
  519. }
  520. }
  521. }