Files
SoulliesOfficial 7580c4d87c 大更
2026-03-14 03:13:10 -04:00

117 lines
3.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}