obsidian/笔记文件/2.笔记/协程管理器.md
2025-04-16 14:29:09 +08:00

2.3 KiB

#unity/日常积累

首先是是抽象出来的接口

!Pasted image 20250416142333.png

然后,是对于接口的,具体逻辑实现: 先是单例的处理,然后用哈希表,去存储协程相关,参考HashSet

!Pasted image 20250416142501.png

再然后,就是管理相关协程的,具体实现了;

CoroutineManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 协程管理器
/// </summary>
public interface ICoroutineManager
{
    /// <summary>
    /// 启动受管理的协程
    /// </summary>
    Coroutine StartManagedCoroutine(IEnumerator routine);
    
    /// <summary>
    /// 停止指定协程
    /// </summary>
    void StopManagedCoroutine(Coroutine coroutine);
    
    /// <summary>
    /// 停止所有协程
    /// </summary>
    void StopAllManagedCoroutines();
}

public class CoroutineManager : MonoBehaviour, ICoroutineManager
{
    private static CoroutineManager _instance;
    private readonly HashSet<Coroutine> _activeCoroutines = new HashSet<Coroutine>();

    public static ICoroutineManager Instance
    {
        get
        {
            if (_instance == null)
            {
                var go = new GameObject("CoroutineManager");
                DontDestroyOnLoad(go);
                _instance = go.AddComponent<CoroutineManager>();
            }
            return _instance;
        }
    }

    public Coroutine StartManagedCoroutine(IEnumerator routine)
    {
        var coroutine = StartCoroutine(WrappedCoroutine(routine));
        _activeCoroutines.Add(coroutine);
        return coroutine;
    }

    public void StopManagedCoroutine(Coroutine coroutine)
    {
        if (coroutine != null && _activeCoroutines.Contains(coroutine))
        {
            StopCoroutine(coroutine);
            _activeCoroutines.Remove(coroutine);
        }
    }

    public void StopAllManagedCoroutines()
    {
        foreach (var coroutine in _activeCoroutines)
        {
            if (coroutine != null)
            {
                StopCoroutine(coroutine);
            }
        }
        _activeCoroutines.Clear();
    }

    private IEnumerator WrappedCoroutine(IEnumerator routine)
    {
        yield return routine;
        _activeCoroutines.Remove(StartCoroutine(routine));
    }
}