Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / ui / grid / UiGrid.cs
@lijincheng lijincheng on 30 Jun 2023 3 KB 小修改
  1.  
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using Godot;
  6.  
  7. public partial class UiGrid<TNodeType, TUiNodeType, TData> : GridContainer, IDestroy where TNodeType : Node where TUiNodeType : IUiNode<TNodeType, TUiNodeType>
  8. {
  9. public bool IsDestroyed { get; private set; }
  10. private TUiNodeType _template;
  11. private Node _parent;
  12. private Type _cellType;
  13. private Stack<UiCell<TNodeType, TUiNodeType, TData>> _cellPool = new Stack<UiCell<TNodeType, TUiNodeType, TData>>();
  14. private List<UiCell<TNodeType, TUiNodeType, TData>> _cellList = new List<UiCell<TNodeType, TUiNodeType, TData>>();
  15.  
  16. public UiGrid(TUiNodeType template, Type cellType, int columns, int offsetX, int offsetY)
  17. {
  18. _template = template;
  19. _cellType = cellType;
  20. _parent = _template.Instance.GetParent();
  21. _parent.RemoveChild(_template.Instance);
  22. _parent.AddChild(this);
  23. Columns = columns;
  24. AddThemeConstantOverride("h_separation", offsetX);
  25. AddThemeConstantOverride("v_separation", offsetY);
  26. }
  27.  
  28. public override void _Ready()
  29. {
  30. if (_template.Instance is Control control)
  31. {
  32. Position = control.Position;
  33. }
  34. }
  35.  
  36. public void SetDataList(TData[] array)
  37. {
  38. if (array.Length > _cellList.Count)
  39. {
  40. do
  41. {
  42. var cell = GetCellInstance();
  43. _cellList.Add(cell);
  44. AddChild(cell.CellNode.Instance);
  45. } while (array.Length > _cellList.Count);
  46. }
  47. else if(array.Length < _cellList.Count)
  48. {
  49. do
  50. {
  51. var cell = _cellList[_cellList.Count - 1];
  52. _cellList.RemoveAt(_cellList.Count - 1);
  53. ReclaimCellInstance(cell);
  54. } while (array.Length < _cellList.Count);
  55. }
  56.  
  57. for (var i = 0; i < _cellList.Count; i++)
  58. {
  59. var data = array[i];
  60. _cellList[i].OnSetData(data);
  61. }
  62. }
  63.  
  64. public void Add(TData data)
  65. {
  66. var cell = GetCellInstance();
  67. _cellList.Add(cell);
  68. AddChild(cell.CellNode.Instance);
  69. cell.OnSetData(data);
  70. }
  71. public void Destroy()
  72. {
  73. if (IsDestroyed)
  74. {
  75. return;
  76. }
  77.  
  78. IsDestroyed = true;
  79. for (var i = 0; i < _cellList.Count; i++)
  80. {
  81. _cellList[i].Destroy();
  82. }
  83. foreach (var uiCell in _cellPool)
  84. {
  85. uiCell.Destroy();
  86. }
  87. _cellList = null;
  88. _cellPool = null;
  89. }
  90.  
  91. private UiCell<TNodeType, TUiNodeType, TData> GetCellInstance()
  92. {
  93. if (_cellPool.Count > 0)
  94. {
  95. return _cellPool.Pop();
  96. }
  97.  
  98. var uiCell = Activator.CreateInstance(_cellType) as UiCell<TNodeType, TUiNodeType, TData>;
  99. if (uiCell is null)
  100. {
  101. throw new Exception($"cellType 无法转为'{typeof(UiCell<TNodeType, TUiNodeType, TData>).FullName}'类型!");
  102. }
  103. uiCell.CellNode = _template.Clone();
  104. uiCell.Grid = this;
  105. uiCell.OnInit();
  106. return uiCell;
  107. }
  108.  
  109. private void ReclaimCellInstance(UiCell<TNodeType, TUiNodeType, TData> cell)
  110. {
  111. RemoveChild(cell.CellNode.Instance);
  112. _cellPool.Push(cell);
  113. }
  114. }