GFramework/docs/zh-CN/core/utility.md
GeWuYou d1cdac8082 docs: 更新文档链接和代码块格式
- 修复了文档中多个文件的链接指向,统一使用相对路径格式
- 移除了代码块中的语言标识符以保持一致性
- 更新了存储模块文档中的类名显示方式
- 修正了架构文档中的跨文档引用链接
- 调整了事件、命令、查询等核心模块的文档链接结构
- 规范化了所有代码示例的格式和引用方式
2026-02-11 14:44:46 +08:00

14 KiB
Raw Blame History

Utility 包使用说明

概述

Utility 包定义了工具类层。Utility 提供无状态的辅助功能,如数学计算、文件操作、序列化等通用工具方法。与 System 不同Utility 不依赖架构状态,是纯粹的工具函数集合。

核心接口

IUtility

Utility 标记接口,所有工具类都应实现此接口。

接口定义:

``csharp public interface IUtility { // 标记接口,无方法定义 }


### IContextUtility

上下文工具接口扩展了IUtility接口为需要感知架构上下文的工具类提供基础能力。

**接口定义:**

``csharp
public interface IContextUtility : IUtility
{
    void Init();  // 初始化上下文工具
}

核心类

AbstractContextUtility

抽象上下文工具类,提供上下文相关的通用功能实现。继承自 ContextAwareBase 并实现 IContextUtility 接口。

使用方式:

public abstract class AbstractContextUtility : ContextAwareBase, IContextUtility
{
    protected ILogger Logger = null!;
    
    void IContextUtility.Init() 
    {
        var name = GetType().Name;
        Logger = LoggerFactoryResolver.Provider.CreateLogger(name);
        Logger.Debug($"Initializing Context Utility: {name}");
        
        OnInit();  // 子类实现初始化逻辑
        
        Logger.Info($"Context Utility initialized: {name}");
    }
    
    protected abstract void OnInit();  // 子类实现具体的初始化逻辑
}

基本使用

1. 定义 Utility

// 存储工具类继承自AbstractContextUtility
public class StorageUtility : AbstractContextUtility
{
    private const string SavePath = "user://save_data.json";
    
    protected override void OnInit()
    {
        Logger.Info("StorageUtility initialized");
    }
    
    public void Save<T>(T data)
    {
        string json = JsonSerializer.Serialize(data);
        // 实际保存逻辑
        File.WriteAllText(SavePath, json);
    }
    
    public T Load<T>()
    {
        if (!File.Exists(SavePath))
            return default(T);
            
        string json = File.ReadAllText(SavePath);
        return JsonSerializer.Deserialize<T>(json);
    }
    
    public void Delete()
    {
        if (File.Exists(SavePath))
        {
            File.Delete(SavePath);
        }
    }
}

// 数学工具类作为普通Utility
public class MathUtility : IUtility
{
    public float Lerp(float a, float b, float t)
    {
        return a + (b - a) * Math.Clamp(t, 0f, 1f);
    }
    
    public bool IsInRange(float value, float min, float max)
    {
        return value >= min && value <= max;
    }
}

// 时间工具类
public class TimeUtility : IUtility
{
    public string FormatTime(float seconds)
    {
        int minutes = (int)(seconds / 60);
        int secs = (int)(seconds % 60);
        return $"{minutes:D2}:{secs:D2}";
    }
    
    public long GetCurrentTimestamp()
    {
        return DateTimeOffset.UtcNow.ToUnixTimeSeconds();
    }
    
    public bool IsExpired(long timestamp, int durationSeconds)
    {
        return GetCurrentTimestamp() > timestamp + durationSeconds;
    }
}

2. 注册 Utility

``csharp public class GameArchitecture : Architecture { protected override void Init() { // 注册 Utility不需要初始化 this.RegisterUtility(new StorageUtility()); this.RegisterUtility(new MathUtility()); this.RegisterUtility(new TimeUtility()); } }


### 3. 使用 Utility

``csharp
// 在 System 中使用
public class SaveSystem : AbstractSystem
{
    protected override void OnInit()
    {
        this.RegisterEvent<SaveGameEvent>(OnSaveGame);
        this.RegisterEvent<LoadGameEvent>(OnLoadGame);
    }
    
    private void OnSaveGame(SaveGameEvent e)
    {
        var storage = this.GetUtility<StorageUtility>();
        var playerModel = this.GetModel<PlayerModel>();
        
        var saveData = new SaveData
        {
            PlayerName = playerModel.Name.Value,
            Level = playerModel.Level.Value,
            Gold = playerModel.Gold.Value,
            Timestamp = this.GetUtility<TimeUtility>().GetCurrentTimestamp()
        };
        
        storage.Save(saveData);
        this.SendEvent(new GameSavedEvent());
    }
    
    private void OnLoadGame(LoadGameEvent e)
    {
        var storage = this.GetUtility<StorageUtility>();
        var saveData = storage.Load<SaveData>();
        
        if (saveData != null)
        {
            var playerModel = this.GetModel<PlayerModel>();
            playerModel.Name.Value = saveData.PlayerName;
            playerModel.Level.Value = saveData.Level;
            playerModel.Gold.Value = saveData.Gold;
            
            this.SendEvent(new GameLoadedEvent());
        }
    }
}

// 在 Command 中使用
public class MovePlayerCommand : AbstractCommand
{
    public Vector3 TargetPosition { get; set; }
    public float Speed { get; set; }
    
    protected override void OnExecute()
    {
        var playerModel = this.GetModel<PlayerModel>();
        var mathUtil = this.GetUtility<MathUtility>();
        
        // 使用工具类计算
        Vector3 currentPos = playerModel.Position.Value;
        Vector3 direction = (TargetPosition - currentPos).Normalized();
        Vector3 newPos = currentPos + direction * Speed;
        
        playerModel.Position.Value = newPos;
    }
}

常见 Utility 类型

1. 序列化/反序列化工具

``csharp public class JsonUtility : IUtility { public string Serialize(T obj) { return Json.Stringify(obj); }

public T Deserialize<T>(string json) where T : new()
{
    return Json.Parse<T>(json);
}

public bool TryDeserialize<T>(string json, out T result) where T : new()
{
    try
    {
        result = Json.Parse<T>(json);
        return true;
    }
    catch
    {
        result = default;
        return false;
    }
}

}


### 2. 随机数工具

``csharp
public class RandomUtility : IUtility
{
    private Random _random = new Random();
    
    public int Range(int min, int max)
    {
        return _random.Next(min, max + 1);
    }
    
    public float Range(float min, float max)
    {
        return min + (float)_random.NextDouble() * (max - min);
    }
    
    public T Choose<T>(params T[] items)
    {
        return items[Range(0, items.Length - 1)];
    }
    
    public List<T> Shuffle<T>(List<T> list)
    {
        var shuffled = new List<T>(list);
        for (int i = shuffled.Count - 1; i > 0; i--)
        {
            int j = Range(0, i);
            (shuffled[i], shuffled[j]) = (shuffled[j], shuffled[i]);
        }
        return shuffled;
    }
    
    public bool Probability(float chance)
    {
        return _random.NextDouble() < chance;
    }
}

3. 字符串工具

``csharp public class StringUtility : IUtility { public string Truncate(string text, int maxLength, string suffix = "...") { if (text.Length <= maxLength) return text; return text.Substring(0, maxLength - suffix.Length) + suffix; }

public string FormatNumber(int number)
{
    if (number >= 1000000)
        return $"{number / 1000000.0:F1}M";
    if (number >= 1000)
        return $"{number / 1000.0:F1}K";
    return number.ToString();
}

public string ToTitleCase(string text)
{
    return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text.ToLower());
}

public bool IsValidEmail(string email)
{
    return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$");
}

}


### 4. 加密工具

``csharp
public class EncryptionUtility : IUtility
{
    private const string EncryptionKey = "YourSecretKey123";
    
    public string Encrypt(string plainText)
    {
        byte[] data = System.Text.Encoding.UTF8.GetBytes(plainText);
        byte[] encrypted = EncryptBytes(data);
        return Convert.ToBase64String(encrypted);
    }
    
    public string Decrypt(string encryptedText)
    {
        byte[] data = Convert.FromBase64String(encryptedText);
        byte[] decrypted = DecryptBytes(data);
        return System.Text.Encoding.UTF8.GetString(decrypted);
    }
    
    private byte[] EncryptBytes(byte[] data)
    {
        // 简单的 XOR 加密示例(实际项目应使用更安全的算法)
        byte[] key = System.Text.Encoding.UTF8.GetBytes(EncryptionKey);
        byte[] result = new byte[data.Length];
        for (int i = 0; i < data.Length; i++)
        {
            result[i] = (byte)(data[i] ^ key[i % key.Length]);
        }
        return result;
    }
    
    private byte[] DecryptBytes(byte[] data)
    {
        return EncryptBytes(data); // XOR 解密与加密相同
    }
}

5. 对象池工具

``csharp public class ObjectPoolUtility : IUtility { private Dictionary<Type, Queue