大修
This commit is contained in:
116
Assets/Scripts/SLSUtilities/General/CompoundBool.cs
Normal file
116
Assets/Scripts/SLSUtilities/General/CompoundBool.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SLSUtilities.General
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个复合布尔值类,支持多来源修改和优先级系统。
|
||||
/// 可以将多个来源对布尔值的修改综合起来,由高优先级的修改决定最终结果。
|
||||
/// </summary>
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
public class CompoundBool
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回当前生效优先级层级的计数。
|
||||
/// </summary>
|
||||
[ShowInInspector]
|
||||
[LabelText("True Count"), LabelWidth(70)]
|
||||
[HorizontalGroup("Stats", Width = 100)]
|
||||
public int TrueCount => GetEffectiveCount();
|
||||
|
||||
private SortedList<int, int> counts = new SortedList<int, int>();
|
||||
private bool isDirty = true;
|
||||
private bool cachedValue;
|
||||
|
||||
/// <summary>
|
||||
/// 获取最终计算出的布尔值。
|
||||
/// </summary>
|
||||
[ShowInInspector]
|
||||
[LabelText("Value"), LabelWidth(50)]
|
||||
[HorizontalGroup("Stats", Width = 100)]
|
||||
public bool Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (isDirty) RecalculateValue();
|
||||
return cachedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 CompoundBool。
|
||||
/// </summary>
|
||||
/// <param name="initialValue">初始值。如果为 true,将在优先级 0 初始化计数为 1。</param>
|
||||
public CompoundBool(bool initialValue = false)
|
||||
{
|
||||
if (initialValue) Modify(true, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在指定的优先级层级修改布尔值。
|
||||
/// 高优先级的值会覆盖低优先级的值。
|
||||
/// 如果某个非零优先级的计数变为零,将自动移除该优先级层级。
|
||||
/// </summary>
|
||||
/// <param name="marker">修改意图(true 增加计数,false 减少计数)。</param>
|
||||
/// <param name="priority">优先级,默认为 0。数字越大优先级越高。</param>
|
||||
public void Modify(bool marker, int priority = 0)
|
||||
{
|
||||
if (counts.TryGetValue(priority, out int currentCount))
|
||||
{
|
||||
counts[priority] = marker ? currentCount + 1 : currentCount - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
counts.Add(priority, marker ? 1 : -1);
|
||||
}
|
||||
|
||||
if(priority != 0 && counts[priority] == 0)
|
||||
{
|
||||
counts.Remove(priority);
|
||||
}
|
||||
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有修改,恢复到默认状态(false)。
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
counts.Clear();
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
private void RecalculateValue()
|
||||
{
|
||||
// 从最高优先级(列表末尾)向最低优先级迭代
|
||||
for (int i = counts.Count - 1; i >= 0; i--)
|
||||
{
|
||||
int count = counts.Values[i];
|
||||
if (count != 0)
|
||||
{
|
||||
cachedValue = count > 0;
|
||||
isDirty = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有计数都为零或列表为空,则默认为 false
|
||||
cachedValue = false;
|
||||
isDirty = false;
|
||||
}
|
||||
|
||||
private int GetEffectiveCount()
|
||||
{
|
||||
// 从最高优先级向最低优先级迭代
|
||||
for (int i = counts.Count - 1; i >= 0; i--)
|
||||
{
|
||||
int count = counts.Values[i];
|
||||
if (count != 0) return count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user