2025-07-08 10:46:31 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace Superlazy.UI
|
|
|
|
|
{
|
|
|
|
|
public class SLUIRepeat : SLUIComponent
|
|
|
|
|
{
|
|
|
|
|
public string bindingValue;
|
|
|
|
|
|
|
|
|
|
public SLValueComparison comparison;
|
|
|
|
|
|
|
|
|
|
[NonSerialized]
|
|
|
|
|
public GameObject prefab = null;
|
|
|
|
|
|
|
|
|
|
private readonly Queue<GameObject> unused = new Queue<GameObject>();
|
|
|
|
|
private readonly Queue<GameObject> bindObjects = new Queue<GameObject>();
|
|
|
|
|
|
|
|
|
|
protected override void Validate()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Init()
|
|
|
|
|
{
|
|
|
|
|
prefab = transform.GetChild(0).gameObject;
|
|
|
|
|
prefab.SetActive(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Enable()
|
|
|
|
|
{
|
|
|
|
|
if (comparison.useCheckValue) comparison.OnEnable(bindParent.BindPath, OnChange);
|
|
|
|
|
|
|
|
|
|
SLGame.AddNotify(bindParent.BindPath.CombinePath(bindingValue), OnChange);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Disable()
|
|
|
|
|
{
|
|
|
|
|
while (bindObjects.Count != 0)
|
|
|
|
|
{
|
|
|
|
|
DisableItem(bindObjects.Dequeue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (comparison.useCheckValue) comparison.OnDisable();
|
|
|
|
|
SLGame.RemoveNotify(bindParent.BindPath.CombinePath(bindingValue), OnChange);
|
|
|
|
|
|
|
|
|
|
if (unused.Count > 16) // 아이템이 너무 많으면 초기화를 한다
|
|
|
|
|
{
|
|
|
|
|
foreach (var unusedItem in unused)
|
|
|
|
|
{
|
|
|
|
|
Destroy(unusedItem);
|
|
|
|
|
}
|
|
|
|
|
unused.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisableItem(GameObject obj)
|
|
|
|
|
{
|
|
|
|
|
obj.SetActive(false);
|
|
|
|
|
unused.Enqueue(obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void EnableItem(GameObject obj)
|
|
|
|
|
{
|
|
|
|
|
obj.SetActive(true);
|
|
|
|
|
bindObjects.Enqueue(obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnChange()
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
var sessionRoot = SLGame.SessionGet(bindParent.BindPath);
|
|
|
|
|
if (sessionRoot == false) return; // TEMP: 세션루트가 삭제되었지만, 삭제되되기전 코루틴 처리가 있을 수 있음
|
|
|
|
|
|
|
|
|
|
var session = SLGame.SessionGet(bindParent.BindPath).Get(bindingValue);
|
|
|
|
|
if (comparison.useCheckValue && comparison.Result == false)
|
|
|
|
|
{
|
|
|
|
|
session = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (session < 0) session = 0;
|
|
|
|
|
|
|
|
|
|
var current = bindObjects.Count;
|
|
|
|
|
if (current > 32)
|
|
|
|
|
{
|
|
|
|
|
SLLog.Warn($"Too many repeat Count : {bindParent.BindPath}.{bindingValue} : {current}", this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (current > session)
|
|
|
|
|
{
|
|
|
|
|
while (current != session)
|
|
|
|
|
{
|
|
|
|
|
DisableItem(bindObjects.Dequeue());
|
|
|
|
|
current--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (current < session)
|
|
|
|
|
{
|
|
|
|
|
while (current != session)
|
|
|
|
|
{
|
|
|
|
|
if (unused.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
var child = Instantiate(prefab, transform, false);
|
|
|
|
|
unused.Enqueue(child);
|
|
|
|
|
}
|
|
|
|
|
EnableItem(unused.Dequeue());
|
|
|
|
|
current++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|