UIRedDotConfigView.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #if UNITY_EDITOR
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Sirenix.OdinInspector;
  7. using Sirenix.Serialization;
  8. using Sirenix.Utilities;
  9. using UnityEngine;
  10. namespace YIUIFramework.Editor
  11. {
  12. [HideLabel]
  13. [HideReferenceObjectPicker]
  14. internal class UIRedDotConfigView : BaseCreateModule
  15. {
  16. internal UIRedDotModule m_UIRedDotModule;
  17. internal RedDotConfigAsset m_RedDotConfigAsset;
  18. private EnumPrefs<ERedDotConfigViewIndexType> m_ERedDotConfigViewIndexTypePrefs =
  19. new EnumPrefs<ERedDotConfigViewIndexType>("AutoUIRedDotModule_ERedDotConfigViewIndexType", null,
  20. ERedDotConfigViewIndexType.Get);
  21. [EnumToggleButtons]
  22. [HideLabel]
  23. [ShowInInspector]
  24. [PropertyOrder(-100)]
  25. [OnValueChanged("OnValueChangedConfigViewIndex")]
  26. internal ERedDotConfigViewIndexType m_ERedDotConfigViewIndexType = ERedDotConfigViewIndexType.Get;
  27. public UIRedDotConfigView(UIRedDotModule redDotModule)
  28. {
  29. m_UIRedDotModule = redDotModule;
  30. m_RedDotConfigAsset = redDotModule.m_RedDotConfigAsset;
  31. }
  32. public override void Initialize()
  33. {
  34. m_ERedDotConfigViewIndexType = m_ERedDotConfigViewIndexTypePrefs.Value;
  35. NewAddConfigEditorData();
  36. InitConfigEditorDataList();
  37. m_UIRedDotModule.OnChangeViewSetIndex += OnChangeViewSetIndex;
  38. }
  39. public override void OnDestroy()
  40. {
  41. m_UIRedDotModule.OnChangeViewSetIndex -= OnChangeViewSetIndex;
  42. AutoSyncEditorData();
  43. }
  44. private void OnChangeViewSetIndex(UIRedDotModule.EUIRedDotViewType obj)
  45. {
  46. if (obj != UIRedDotModule.EUIRedDotViewType.Config)
  47. {
  48. AutoSyncEditorData();
  49. }
  50. }
  51. private void OnValueChangedConfigViewIndex()
  52. {
  53. m_ERedDotConfigViewIndexTypePrefs.Value = m_ERedDotConfigViewIndexType;
  54. if (m_ERedDotConfigViewIndexType != ERedDotConfigViewIndexType.Get)
  55. {
  56. //AutoSyncEditorData(); //暂时取消这个同步 频率很高
  57. }
  58. }
  59. #region 同步脏标
  60. //编辑器数据同步脏标
  61. internal bool m_EditorDataSyncDirty = false;
  62. //自动同步数据
  63. private void AutoSyncEditorData()
  64. {
  65. if (!m_EditorDataSyncDirty) return;
  66. UnityTipsHelper.CallBack($"关联配置数据 已修改是否同步 \n\n取消同步将会丢失所有修改!!!", UpdateConfigEditorDataToAsset);
  67. }
  68. #endregion
  69. #region 添加
  70. [OdinSerialize]
  71. [ShowInInspector]
  72. [BoxGroup("新增关联配置数据", centerLabel: true)]
  73. [ShowIf("m_ERedDotConfigViewIndexType", ERedDotConfigViewIndexType.Add)]
  74. [HideLabel]
  75. [HideReferenceObjectPicker]
  76. private UIRedDotConfigEditorData m_AddUIRedDotConfigEditorData;
  77. [GUIColor(0, 1, 0)]
  78. [Button("添加关联配置", 50)]
  79. [ShowIf("m_ERedDotConfigViewIndexType", ERedDotConfigViewIndexType.Add)]
  80. private void AddConfigEditorDataBtn()
  81. {
  82. var keyType = m_AddUIRedDotConfigEditorData.KeyType;
  83. if (keyType == 0)
  84. {
  85. UnityTipsHelper.Show($"请设置一个合理的key");
  86. return;
  87. }
  88. if (EditorDataContains(keyType))
  89. {
  90. UnityTipsHelper.Show($"当前Key的相关配置已存在 无法重复添加 {keyType}");
  91. return;
  92. }
  93. m_AddUIRedDotConfigEditorData.ShowDeleteBtn = true;
  94. AddConfigEditorDataToList(m_AddUIRedDotConfigEditorData);
  95. NewAddConfigEditorData();
  96. m_EditorDataSyncDirty = true;
  97. UnityTipsHelper.Show($"成功添加 {keyType}");
  98. }
  99. private void NewAddConfigEditorData()
  100. {
  101. m_AddUIRedDotConfigEditorData = new UIRedDotConfigEditorData(this)
  102. {
  103. ShowDeleteBtn = false,
  104. };
  105. m_AddUIRedDotConfigEditorData.ParentList.Add(new UIRedDotKeyEditorData(m_AddUIRedDotConfigEditorData));
  106. }
  107. #endregion
  108. #region 查看
  109. [GUIColor(0.4f, 0.8f, 1)]
  110. [Button("同步到Asset配置", 50)]
  111. [ShowIf("m_ERedDotConfigViewIndexType", ERedDotConfigViewIndexType.Get)]
  112. [PropertyOrder(-1)]
  113. [EnableIf("m_EditorDataSyncDirty")]
  114. private void UpdateConfigEditorDataToAsset()
  115. {
  116. m_EditorDataSyncDirty = false;
  117. DeserializationEditorData();
  118. InitConfigEditorDataList();
  119. UnityTipsHelper.Show($"同步完成");
  120. }
  121. [TableList(DrawScrollView = true, AlwaysExpanded = true, IsReadOnly = true)]
  122. [OdinSerialize]
  123. [BoxGroup("所有关联配置数据", centerLabel: true)]
  124. [HideLabel]
  125. [ShowIf("m_ERedDotConfigViewIndexType", ERedDotConfigViewIndexType.Get)]
  126. private List<UIRedDotConfigEditorData> m_RedDotConfigEditorDataList = new List<UIRedDotConfigEditorData>();
  127. private HashSet<int> m_HashRedDotKeyType = new HashSet<int>();
  128. #region 初始化 数据 根据存储的Asset
  129. private void InitConfigEditorDataList()
  130. {
  131. m_RedDotConfigEditorDataList.Clear();
  132. m_HashRedDotKeyType.Clear();
  133. foreach (var data in m_RedDotConfigAsset.AllRedDotConfigDic.Values)
  134. {
  135. var editorData = NewEditorDataByRuntimeData(data);
  136. AddConfigEditorDataToList(editorData);
  137. }
  138. }
  139. private UIRedDotConfigEditorData NewEditorDataByRuntimeData(RedDotConfigData data)
  140. {
  141. var editorData = new UIRedDotConfigEditorData(this)
  142. {
  143. Id = data.Key,
  144. KeyType = data.Key,
  145. SwitchTips = data.SwitchTips,
  146. ShowDeleteBtn = true
  147. };
  148. editorData.ParentList = GetParentListByRuntimeData(data, editorData);
  149. return editorData;
  150. }
  151. private List<UIRedDotKeyEditorData> GetParentListByRuntimeData(RedDotConfigData data,
  152. UIRedDotConfigEditorData editorData)
  153. {
  154. var parentList = new List<UIRedDotKeyEditorData>();
  155. foreach (var key in data.ParentList)
  156. {
  157. parentList.Add(new UIRedDotKeyEditorData(editorData)
  158. {
  159. Id = key,
  160. KeyType = key,
  161. });
  162. }
  163. return parentList;
  164. }
  165. #endregion
  166. #region 反序列化当前数据到存储数据
  167. private void DeserializationEditorData()
  168. {
  169. var list = GetRuntimeDataListToEditorData();
  170. list.Sort(SortRuntimeData);
  171. m_RedDotConfigAsset.SetAllRedDotConfigList(list);
  172. }
  173. private int SortRuntimeData(RedDotConfigData x, RedDotConfigData y)
  174. {
  175. return x.Key < y.Key ? -1 : 1;
  176. }
  177. private List<RedDotConfigData> GetRuntimeDataListToEditorData()
  178. {
  179. var runtimeDataList = new List<RedDotConfigData>();
  180. foreach (var data in m_RedDotConfigEditorDataList)
  181. {
  182. var runtimeData = NewRuntimeDataByEditorData(data);
  183. runtimeDataList.Add(runtimeData);
  184. }
  185. return runtimeDataList;
  186. }
  187. private RedDotConfigData NewRuntimeDataByEditorData(UIRedDotConfigEditorData data)
  188. {
  189. var runtimeData = new RedDotConfigData()
  190. {
  191. Key = data.KeyType,
  192. ParentList = GetParentListByEditorData(data),
  193. SwitchTips = data.SwitchTips,
  194. };
  195. return runtimeData;
  196. }
  197. private List<int> GetParentListByEditorData(UIRedDotConfigEditorData data)
  198. {
  199. var parentList = new List<int>();
  200. foreach (var parentData in data.ParentList)
  201. {
  202. if (parentData.KeyType == 0)
  203. {
  204. continue;
  205. }
  206. parentList.Add(parentData.KeyType);
  207. }
  208. return parentList;
  209. }
  210. #endregion
  211. private bool AddConfigEditorDataToList(UIRedDotConfigEditorData data)
  212. {
  213. if (m_HashRedDotKeyType.Contains(data.KeyType))
  214. {
  215. Debug.LogError($"已存在 无法重复添加");
  216. return false;
  217. }
  218. m_RedDotConfigEditorDataList.Add(data);
  219. m_HashRedDotKeyType.Add(data.KeyType);
  220. return true;
  221. }
  222. internal bool EditorDataContains(int keyType)
  223. {
  224. return m_HashRedDotKeyType.Contains(keyType);
  225. }
  226. internal void DeleteConfigEditorData(UIRedDotConfigEditorData data)
  227. {
  228. m_RedDotConfigEditorDataList.Remove(data);
  229. m_HashRedDotKeyType.Remove(data.KeyType);
  230. }
  231. #endregion
  232. #region DAG
  233. [ShowIf("m_ERedDotConfigViewIndexType", ERedDotConfigViewIndexType.Get)]
  234. [Button("额外检查是否有循环引用", 30)]
  235. [PropertyOrder(-100)]
  236. public void CheckDataCycles()
  237. {
  238. var redDotConfigDAG = new UIRedDotConfigDAG();
  239. foreach (int key in RedDotKeyHelper.GetKeys())
  240. {
  241. redDotConfigDAG.AddNode(key);
  242. }
  243. foreach (var data in m_RedDotConfigEditorDataList)
  244. {
  245. foreach (var parentData in data.ParentList)
  246. {
  247. redDotConfigDAG.AddEdge(parentData.KeyType, data.KeyType);
  248. }
  249. }
  250. var result = redDotConfigDAG.Check();
  251. UnityTipsHelper.Show(result ? "安全 无循环嵌套" : "有循环嵌套 请详细检查");
  252. }
  253. #endregion
  254. [HideLabel]
  255. internal enum ERedDotConfigViewIndexType
  256. {
  257. [LabelText("增")]
  258. Add = 1,
  259. [LabelText("删/改/查")]
  260. Get = 2,
  261. }
  262. }
  263. }
  264. #endif