MaterialReferenceManager.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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. if (materialReferenceIndexLookup.TryGetValue(materialID, out int index))
  470. {
  471. return index;
  472. }
  473. else
  474. {
  475. index = materialReferenceIndexLookup.Count;
  476. // Add new reference index
  477. materialReferenceIndexLookup[materialID] = index;
  478. materialReferences[index].index = index;
  479. materialReferences[index].fontAsset = fontAsset;
  480. materialReferences[index].spriteAsset = null;
  481. materialReferences[index].material = material;
  482. materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID() ? true : false;
  483. //materialReferences[index].padding = 0;
  484. materialReferences[index].referenceCount = 0;
  485. return index;
  486. }
  487. }
  488. /// <summary>
  489. ///
  490. /// </summary>
  491. /// <param name="material"></param>
  492. /// <param name="spriteAsset"></param>
  493. /// <param name="materialReferences"></param>
  494. /// <param name="materialReferenceIndexLookup"></param>
  495. /// <returns></returns>
  496. public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
  497. {
  498. int materialID = material.GetInstanceID();
  499. if (materialReferenceIndexLookup.TryGetValue(materialID, out int index))
  500. {
  501. return index;
  502. }
  503. else
  504. {
  505. index = materialReferenceIndexLookup.Count;
  506. // Add new reference index
  507. materialReferenceIndexLookup[materialID] = index;
  508. materialReferences[index].index = index;
  509. materialReferences[index].fontAsset = materialReferences[0].fontAsset;
  510. materialReferences[index].spriteAsset = spriteAsset;
  511. materialReferences[index].material = material;
  512. materialReferences[index].isDefaultMaterial = true;
  513. //materialReferences[index].padding = 0;
  514. materialReferences[index].referenceCount = 0;
  515. return index;
  516. }
  517. }
  518. }
  519. }