supervisor-simulator/scripts/Models/PropertyValue.cs
2026-01-11 23:57:24 +08:00

171 lines
5.7 KiB
C#
Raw 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;
namespace Models;
/// <summary>
/// 属性值类型(通用数值封装)
/// 设计说明:
/// 1) 过去固定使用 0-100 的范围,导致“精力/算力”等大数值被强行截断。
/// 2) 现在改为“每个实例自带范围”,默认仍然是 0-100兼顾直觉和可扩展性。
/// 3) 这个类仅承担“数值与范围”的职责,不负责业务含义,便于在 MVC 中被复用。
/// 注意事项:
/// - 运算符会保留左操作数的范围(或右操作数的范围),避免范围丢失。
/// - 如果需要无上限/无下限,请显式传入更大的 Max/更小的 Min。
/// 未来扩展:
/// - 可加入“软上限/软下限”和“可见范围”等 UI 表现字段。
/// - 可增加数值变化事件,以便 View 层更高效地刷新。
/// </summary>
public sealed class PropertyValue
{
public const float DefaultMin = 0f;
public const float DefaultMax = 100f;
/// <summary>
/// 最小值
/// </summary>
public float Min { get; }
/// <summary>
/// 最大值
/// </summary>
public float Max { get; }
private float _value;
/// <summary>
/// 当前值(自动限制在 Min/Max 范围内)
/// </summary>
public float Value
{
get => _value;
set => _value = Clamp(value, Min, Max);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="value">初始值</param>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
public PropertyValue(float value = 0, float min = DefaultMin, float max = DefaultMax)
{
if (max < min)
{
// 兜底修正,避免传参错误导致全局异常
(min, max) = (max, min);
}
Min = min;
Max = max;
Value = value;
}
/// <summary>
/// 构造函数(整数)
/// </summary>
/// <param name="value">初始值</param>
/// <param name="min">最小值</param>
/// <param name="max">最大值</param>
public PropertyValue(int value, float min = DefaultMin, float max = DefaultMax)
: this((float)value, min, max)
{
}
/// <summary>
/// 获取显示的整数值
/// </summary>
/// <returns>整数值</returns>
public int DisplayInt() => (int)_value;
/// <summary>
/// 获取归一化值 (0.0 - 1.0)
/// </summary>
public float Normalized
{
get
{
if (Max <= Min) return 0f;
return (Value - Min) / (Max - Min);
}
}
/// <summary>
/// 克隆
/// </summary>
/// <returns>新实例</returns>
public PropertyValue Clone() => new(Value, Min, Max);
/// <summary>
/// 增加值
/// </summary>
/// <param name="delta">增量</param>
public void Add(float delta) => Value += delta;
/// <summary>
/// 减少值
/// </summary>
/// <param name="delta">减量</param>
public void Subtract(float delta) => Value -= delta;
public override string ToString() => DisplayInt().ToString();
// --- 隐式转换(用于简化调用,但不改变范围语义) ---
public static implicit operator PropertyValue(int value)
{
return new PropertyValue(value);
}
public static implicit operator PropertyValue(float value)
{
return new PropertyValue(value);
}
public static implicit operator int(PropertyValue p)
{
return (int)p._value;
}
public static implicit operator float(PropertyValue p)
{
return p._value;
}
// --- 运算符重载(保留范围) ---
public static PropertyValue operator +(PropertyValue a, int b) => new(a._value + b, a.Min, a.Max);
public static PropertyValue operator +(int a, PropertyValue b) => new(a + b._value, b.Min, b.Max);
public static PropertyValue operator -(PropertyValue a, int b) => new(a._value - b, a.Min, a.Max);
public static PropertyValue operator -(int a, PropertyValue b) => new(a - b._value, b.Min, b.Max);
public static PropertyValue operator *(PropertyValue a, int b) => new(a._value * b, a.Min, a.Max);
public static PropertyValue operator *(int a, PropertyValue b) => new(a * b._value, b.Min, b.Max);
public static PropertyValue operator /(PropertyValue a, int b)
{
return b == 0 ? throw new DivideByZeroException() : new PropertyValue(a._value / b, a.Min, a.Max);
}
public static PropertyValue operator /(int a, PropertyValue b)
{
return b._value == 0 ? throw new DivideByZeroException() : new PropertyValue(a / b._value, b.Min, b.Max);
}
public static PropertyValue operator +(PropertyValue a, float b) => new(a._value + b, a.Min, a.Max);
public static PropertyValue operator +(float a, PropertyValue b) => new(a + b._value, b.Min, b.Max);
public static PropertyValue operator -(PropertyValue a, float b) => new(a._value - b, a.Min, a.Max);
public static PropertyValue operator -(float a, PropertyValue b) => new(a - b._value, b.Min, b.Max);
public static PropertyValue operator *(PropertyValue a, float b) => new(a._value * b, a.Min, a.Max);
public static PropertyValue operator *(float a, PropertyValue b) => new(a * b._value, b.Min, b.Max);
public static PropertyValue operator /(PropertyValue a, float b) => new(a._value / b, a.Min, a.Max);
public static PropertyValue operator /(float a, PropertyValue b) => new(a / b._value, b.Min, b.Max);
public static PropertyValue operator +(PropertyValue a, PropertyValue b) => new(a._value + b._value, a.Min, a.Max);
public static PropertyValue operator -(PropertyValue a, PropertyValue b) => new(a._value - b._value, a.Min, a.Max);
public static PropertyValue operator *(PropertyValue a, PropertyValue b) => new(a._value * b._value, a.Min, a.Max);
public static PropertyValue operator /(PropertyValue a, PropertyValue b)
{
return b._value == 0 ? throw new DivideByZeroException() : new PropertyValue(a._value / b._value, a.Min, a.Max);
}
private static float Clamp(float value, float min, float max)
{
if (value < min) return min;
if (value > max) return max;
return value;
}
}