Files
zeling_v2/Assets/Scripts/Core/Pool/PooledObject.cs
2026-05-12 15:34:08 +08:00

79 lines
2.9 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;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BaseGames.Core.Pool
{
/// <summary>
/// 可池化对象组件,挂在每个可池化 Prefab 的根节点上。
/// 实现 <see cref="IPoolable"/> 的子类可覆盖 OnSpawn/OnDespawn。
/// </summary>
public class PooledObject : MonoBehaviour
{
public string AddressKey { get; private set; }
private GlobalObjectPool _pool;
/// <summary>
/// 对象在 GlobalObjectPool._alive 链表中的节点引用。
/// 存储节点可将 Despawn 时的链表移除从 O(n) 降为 O(1)。
/// 仅 GlobalObjectPool 内部读写,业务代码不应访问。
/// </summary>
internal LinkedListNode<PooledObject> AliveNode;
// 组件缓存(避免反复 GetComponent
private readonly Dictionary<Type, Component> _componentCache = new();
public void Setup(string key, GlobalObjectPool pool)
{
AddressKey = key;
_pool = pool;
}
public virtual void OnSpawn() { }
public virtual void OnDespawn(){ }
// ── 归还 API ──────────────────────────────────────────────────────
/// <summary>立即归还到对象池。</summary>
public void ReturnToPool() => _pool?.Despawn(AddressKey, this);
/// <summary>延迟 delay 秒后归还。</summary>
public void ReturnToPoolDelayed(float delay) => StartCoroutine(DelayedReturn(delay));
/// <summary>
/// 由 GlobalObjectPool LRU 回收触发,不应由业务代码直接调用。
/// </summary>
internal void ForceReturnToPool()
{
OnDespawn();
gameObject.SetActive(false);
}
// ── 组件缓存 ──────────────────────────────────────────────────────
/// <summary>从缓存获取 Component首次调用才执行 GetComponent。</summary>
public T GetComponentCached<T>() where T : Component
{
if (!_componentCache.TryGetValue(typeof(T), out var cached))
_componentCache[typeof(T)] = cached = GetComponent<T>();
return (T)cached;
}
private IEnumerator DelayedReturn(float delay)
{
yield return new WaitForSeconds(delay);
ReturnToPool();
}
}
/// <summary>
/// 可选接口:若池化对象需要在 Spawn/Despawn 时执行额外逻辑,
/// 由 PooledObject 子类或同 GameObject 上的其他 MonoBehaviour 实现,
/// 并在 PooledObject.OnSpawn/OnDespawn 中手动驱动。
/// </summary>
public interface IPoolable
{
void OnSpawn();
void OnDespawn();
}
}