개발 완료

This commit is contained in:
logonkhi
2025-11-03 19:07:04 +09:00
parent a5a3f7d553
commit 5292879aaf
6 changed files with 349 additions and 299 deletions

View File

@@ -127,6 +127,12 @@ namespace UVC.UI.List.Tree
/// </summary>
public List<TreeListItem> TreeLists => root.GetComponentsInChildren<TreeListItem>().ToList();
// 뷰 매핑: 데이터 ↔ View O(1) 조회
private readonly Dictionary<TreeListItemData, TreeListItem> _viewMap = new Dictionary<TreeListItemData, TreeListItem>();
// 플래튼 업데이트 스로틀링 플래그
private bool _flattenScheduled;
private void Awake()
{
// 드래그 & 드롭 이벤트 구독
@@ -183,6 +189,42 @@ namespace UVC.UI.List.Tree
}
}
/// <summary>
/// View 등록(데이터↔View 맵). Init 시점에 호출됩니다.
/// </summary>
internal void RegisterView(TreeListItemData data, TreeListItem view)
{
if (data == null || view == null) return;
_viewMap[data] = view;
}
/// <summary>
/// View 등록 해제. Delete/OnDestroy 시점에 호출됩니다.
/// </summary>
internal void UnregisterView(TreeListItemData data, TreeListItem view)
{
if (data == null) return;
if (_viewMap.TryGetValue(data, out var existing) && existing == view)
{
_viewMap.Remove(data);
}
}
/// <summary>
/// 다음 프레임에 평탄화 리스트 업데이트를 예약합니다.
/// 과도한 재계산을 방지하기 위한 스로틀링 유틸입니다.
/// </summary>
public void ScheduleFlattenedUpdate()
{
if (_flattenScheduled) return;
_flattenScheduled = true;
UniTask.NextFrame().ContinueWith(() =>
{
_flattenScheduled = false;
UpdateFlattenedItemDataList();
});
}
/// <summary>
/// Escape 키 입력 시 모든 선택 해제
///
@@ -535,6 +577,7 @@ namespace UVC.UI.List.Tree
TreeListItem item = GameObject.Instantiate<TreeListItem>(ItemPrefab, root);
item.Init(data, this, dragDropManager);
index = Mathf.Clamp(index, 0, items.Count);
items.Insert(index, data);
UniTask.DelayFrame(1).ContinueWith(() =>
@@ -605,20 +648,20 @@ namespace UVC.UI.List.Tree
}
/// <summary>
/// 아이템을 지정 인덱스로 이동
/// 아이템을 지정 인덱스로 이동합니다(기존 위치 제거 후 삽입).
/// </summary>
/// <param name="data">이동할 아이템 데이터</param>
/// <param name="index">목표 위치</param>
public void SwapItem(TreeListItemData data, int index)
{
// 기존 위치 제거
items.Remove(data);
// 인덱스 보정 후 삽입
index = Mathf.Clamp(index, 0, items.Count);
items.Insert(index, data);
TreeListItem? item = allItemFlattened.FirstOrDefault(x => x.Data == data);
if (item != null) items.Insert(index, data);
UniTask.DelayFrame(1).ContinueWith(() =>
{
//gameObject 순서 조절
if (item != null) item.transform.SetSiblingIndex(index);
// 범위 선택에 필요한 평탄화 리스트 업데이트
UpdateFlattenedItemDataList();
});
}
@@ -674,6 +717,7 @@ namespace UVC.UI.List.Tree
allItemDataFlattened.Clear();
items.Clear();
selectedItems.Clear();
_viewMap.Clear();
}
/// <summary>
@@ -702,8 +746,7 @@ namespace UVC.UI.List.Tree
allItemFlattened.Clear();
foreach (var data in allItemDataFlattened)
{
var item = root.GetComponentsInChildren<TreeListItem>(true).FirstOrDefault(x => x.Data == data);
if (item != null)
if (_viewMap.TryGetValue(data, out var item) && item != null)
{
allItemFlattened.Add(item);
}