05-06-源码-异步操作体系(OperationSystem)

0 阅读6分钟

源码-异步体系(OperationSystem)

篇章:05-源码深度-运行时核心模块 阅读时间:约 30 分钟 前置知识:了解 Provider 体系


一、引言

本章将深入解析 YooAsset 异步体系(OperationSystem)的源码实现。OperationSystem 是 YooAsset 异步操作管理的核心,提供了统一的异步操作管理接口。YooAsset 的所有异步操作都基于 OperationSystem 实现。

OperationSystem 的设计目标是提供统一、灵活、高效的异步操作管理能力。本章将从源码层面深入解析 OperationSystem 的设计和实现。


二、Operation 概述

2.1 Operation 的概念

Operation 是 YooAsset 异步操作的抽象:

Operation 的定义:

Operation 是一个抽象类,定义了异步操作的基本行为。

Operation 的特点:

  • 统一接口:所有异步操作都遵循相同的接口
  • 状态管理:Operation 维护自己的状态
  • 进度跟踪:Operation 提供进度跟踪
  • 回调通知:Operation 支持完成回调

Operation 的作用:

  • 封装异步操作逻辑
  • 提供统一的异步操作接口
  • 支持异步操作的优先级调度
  • 支持异步操作的时间片管理

2.2 Operation 状态机

Operation 内部维护了一个状态机:

Operation 状态机
├── Pending:等待中
├── Running:运行中
├── Succeeded:成功
├── Failed:失败
└── Cancelled:已取消

Pending 详解:

Pending 是 Operation 的初始状态,Operation 创建后即进入 Pending 状态。

Running 详解:

Running 是 Operation 的运行中状态。Operation 被调度执行时进入 Running 状态。

Succeeded 详解:

Succeeded 是 Operation 的成功状态。异步操作执行成功时进入此状态。

Failed 详解:

Failed 是 Operation 的失败状态。异步操作执行失败时进入此状态。

Cancelled 详解:

Cancelled 是 Operation 的已取消状态。Operation 被取消时进入此状态。

2.3 Operation 状态详解

public enum EOperationStatus
{
    None = 0,
    Pending = 1,
    Running = 2,
    Succeeded = 3,
    Failed = 4,
    Cancelled = 5,
}

状态转换详解:

  • None → Pending:Operation 被注册
  • Pending → Running:Operation 开始执行
  • Running → Succeeded:执行成功
  • Running → Failed:执行失败
  • Pending/Running → Cancelled:操作被取消

2.4 Operation 基类

public abstract class AsyncOperationBase
{
    public EOperationStatus Status { get; protected set; }
    public float Progress { get; protected set; }
    public string Error { get; protected set; }
    public bool IsDone => Status == EOperationStatus.Succeeded || Status == EOperationStatus.Failed || Status == EOperationStatus.Cancelled;
    public event Action<AsyncOperationBase> OnCompleted;
    
    public abstract void Start();
    public abstract void Update();
    public virtual void Destroy();
}

Status 详解:

Status 是 Operation 的当前状态。

Progress 详解:

Progress 是 Operation 的执行进度。

Error 详解:

Error 是 Operation 失败时的错误信息。

OnCompleted 详解:

OnCompleted 是 Operation 完成时触发的事件。


三、优先级队列

3.1 优先级队列的作用

YooAsset 使用优先级队列管理 Operation:

优先级队列的作用:

  • 高优先级 Operation 优先执行
  • 支持紧急资源的快速加载
  • 灵活调度异步操作

3.2 优先级定义

public enum EOperationPriority
{
    Low = 0,
    BelowNormal = 3,
    Normal = 5,
    AboveNormal = 7,
    High = 9,
    Ultra = 10,
}

优先级详解:

  • Low:低优先级
  • BelowNormal:低于正常
  • Normal:正常
  • AboveNormal:高于正常
  • High:高优先级
  • Ultra:超高优先级

3.3 优先级队列的实现

public class PriorityQueue<T> where T : IComparable<T>
{
    private List<T> _data;
    
    public void Enqueue(T item)
    {
        _data.Add(item);
        int childIndex = _data.Count - 1;
        while (childIndex > 0)
        {
            int parentIndex = (childIndex - 1) / 2;
            if (_data[childIndex].CompareTo(_data[parentIndex]) >= 0) break;
            T tmp = _data[childIndex];
            _data[childIndex] = _data[parentIndex];
            _data[parentIndex] = tmp;
            childIndex = parentIndex;
        }
    }
    
    public T Dequeue()
    {
        int lastIndex = _data.Count - 1;
        T frontItem = _data[0];
        _data[0] = _data[lastIndex];
        _data.RemoveAt(lastIndex);
        // 下沉调整
        // ...
        return frontItem;
    }
}

二叉堆实现详解:

使用二叉堆(Binary Heap)实现优先级队列。

入队操作详解:

入队时将元素添加到堆尾,然后上浮调整。

出队操作详解:

出队时取出堆顶元素,然后将堆尾元素移到堆顶,最后下沉调整。

3.4 优先级应用场景

关键资源优先加载:

使用高优先级加载关键资源,如玩家角色、UI 等。

后台资源低优先级加载:

使用低优先级加载后台资源,如未来的关卡资源。

动态调整优先级:

可以根据游戏状态动态调整 Operation 的优先级。


四、Operation 加载/卸载

4.1 加载流程

Operation 的加载流程:

Operation 加载流程
1. 创建 Operation
2. 设置 Operation 参数
3. 启动 Operation(Start)
4. OperationSystem 调度 Operation
5. 每帧调用 Update
6. Operation 完成
7. 触发完成回调

创建 Operation 详解:

开发者创建 Operation 实例并设置参数。

启动 Operation 详解:

调用 Start 方法启动 Operation。

调度 Operation 详解:

OperationSystem 调度 Operation,根据优先级决定执行顺序。

每帧 Update 详解:

OperationSystem 在每帧调用 Operation 的 Update 方法。

完成回调详解:

Operation 完成时触发 OnCompleted 事件。

4.2 加载实现

public class AssetLoadOperation : AsyncOperationBase
{
    private ResourcePackage _package;
    private string _location;
    
    public override void Start()
    {
        Status = EOperationStatus.Running;
        // 启动加载逻辑
    }
    
    public override void Update()
    {
        // 更新加载进度
        Progress = CalculateProgress();
        
        // 检查是否完成
        if (IsLoadComplete())
        {
            Status = EOperationStatus.Succeeded;
            OnCompleted?.Invoke(this);
        }
    }
}

Start 详解:

Start 方法启动加载逻辑,将状态设置为 Running。

Update 详解:

Update 方法在每帧被调用,更新加载进度并检查是否完成。

完成回调详解:

加载完成时触发 OnCompleted 事件。

4.3 取消流程

Operation 的取消流程:

Operation 取消流程
1. 调用 Cancel 方法
2. 设置状态为 Cancelled
3. 触发完成回调

Cancel 方法详解:

public class AsyncOperationBase
{
    public virtual void Cancel()
    {
        if (Status == EOperationStatus.Succeeded || Status == EOperationStatus.Failed) return;
        Status = EOperationStatus.Cancelled;
        OnCompleted?.Invoke(this);
    }
}

取消限制详解:

已完成的 Operation 不能被取消。

取消通知详解:

取消时触发 OnCompleted 事件,通知监听者。

4.4 销毁流程

Operation 的销毁流程:

Operation 销毁流程
1. 调用 Destroy 方法
2. 清理 Operation 资源
3. 从 OperationSystem 中移除

Destroy 方法详解:

public virtual void Destroy()
{
    OnCompleted = null;
    Status = EOperationStatus.None;
    Progress = 0;
    Error = null;
}

清理资源详解:

销毁时清理 Operation 占用的资源,如取消订阅、释放内存等。

从 OperationSystem 移除详解:

销毁的 Operation 需要从 OperationSystem 中移除,避免内存泄漏。


五、OperationSystem 调度器

5.1 OperationSystem 的作用

OperationSystem 是 YooAsset 异步操作的调度器:

调度器的作用:

  • 管理所有 Operation
  • 调度 Operation 的执行
  • 维护 Operation 的优先级
  • 处理 Operation 的完成回调

5.2 OperationSystem 的实现

public class OperationSystem
{
    private List<AsyncOperationBase> _operations = new List<AsyncOperationBase>();
    private List<AsyncOperationBase> _completeList = new List<AsyncOperationBase>();
    private List<AsyncOperationBase> _destroyList = new List<AsyncOperationBase>();
    
    public void ProcessOperation(AsyncOperationBase operation)
    {
        operation.Start();
        _operations.Add(operation);
    }
    
    public void Update()
    {
        // 更新所有 Operation
        for (int i = 0; i < _operations.Count; i++)
        {
            var op = _operations[i];
            op.Update();
            
            if (op.IsDone)
            {
                _completeList.Add(op);
            }
        }
        
        // 处理完成的 Operation
        ProcessCompletedOperations();
    }
    
    private void ProcessCompletedOperations()
    {
        foreach (var op in _completeList)
        {
            op.OnCompleted?.Invoke(op);
            _destroyList.Add(op);
        }
        _completeList.Clear();
        
        foreach (var op in _destroyList)
        {
            op.Destroy();
            _operations.Remove(op);
        }
        _destroyList.Clear();
    }
}

ProcessOperation 详解:

注册新的 Operation 到 OperationSystem。

Update 详解:

每帧调用 Update 方法,更新所有 Operation。

完成处理详解:

处理已完成的 Operation,触发回调并销毁。

5.3 OperationSystem 的时间片

public class OperationSystem
{
    public float TimeSlice { get; set; } = 0.5f; // 0.5 毫秒
    
    public void Update()
    {
        float startTime = Time.realtimeSinceStartup;
        
        for (int i = 0; i < _operations.Count; i++)
        {
            _operations[i].Update();
            
            if (Time.realtimeSinceStartup - startTime > TimeSlice)
                break;
        }
    }
}

时间片的作用详解:

时间片限制 OperationSystem 在单帧内执行的最大时间,避免阻塞主线程。

时间片的应用详解:

开发者可以根据项目需求调整时间片大小。

5.4 OperationUpdater

public class OperationUpdater : MonoBehaviour
{
    private void Update()
    {
        OperationSystem.Update();
    }
}

OperationUpdater 的作用详解:

OperationUpdater 是 OperationSystem 的 MonoBehaviour 包装,在每帧调用 OperationSystem.Update。

DontDestroyOnLoad 详解:

OperationUpdater 使用 DontDestroyOnLoad 确保在场景切换时不被销毁。


六、总结

本章深入解析了 YooAsset 异步体系(OperationSystem)的源码实现,包括:

  • Operation 概述:Operation 的概念、状态机、状态详解
  • 优先级队列:优先级队列的作用、定义、实现、应用
  • Operation 加载/卸载:加载流程、加载实现、取消流程、销毁流程
  • OperationSystem 调度器:调度器的作用、实现、时间片、Updater

通过深入理解 OperationSystem 的实现,开发者可以更好地理解 YooAsset 的异步操作管理机制,并实现自定义的异步操作。


上一篇:资源提供者(Provider 体系) 下一篇:引用计数机制