Skip to content

Commit 92d9c86

Browse files
authored
Merge pull request #2 from Machillka/features/objectpool
feature: ObjectPool
2 parents dbe0043 + b5734f8 commit 92d9c86

11 files changed

Lines changed: 225 additions & 0 deletions

File tree

Assets/Framework/Scripts/Infra.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using UnityEngine;
2+
using UnityEngine.Pool;
3+
using System.Collections;
4+
5+
namespace Framework.Utilities.ObjectPool
6+
{
7+
public class GameobjectPool : IObjectPool<GameObject>
8+
{
9+
private readonly ObjectPool<GameObject> _pool;
10+
private readonly Transform _parent;
11+
private readonly GameObject _prefab;
12+
private readonly int _initializedSize;
13+
private readonly int _maxSize;
14+
15+
public int InitializedSize => _initializedSize;
16+
17+
public int MaxSize => _maxSize;
18+
19+
/// <summary>
20+
/// 仅提供预制体和父节点
21+
/// </summary>
22+
/// <param name="parent"></param>
23+
/// <param name="prefab"></param>
24+
/// <param name="initializedSize"></param>
25+
/// <param name="maxSize"></param>
26+
public GameobjectPool(Transform parent, GameObject prefab, int initializedSize, int maxSize)
27+
{
28+
_parent = parent;
29+
_prefab = prefab;
30+
_initializedSize = initializedSize;
31+
_maxSize = maxSize;
32+
33+
_pool = new ObjectPool<GameObject>(
34+
createFunc: () => Object.Instantiate(_prefab, _parent),
35+
actionOnGet: go => { if (go != null) go.SetActive(true); },
36+
actionOnRelease: go => { if (go != null) { go.SetActive(false); go.transform.SetParent(_parent); } },
37+
actionOnDestroy: obj => { if (obj != null) Object.Destroy(obj); },
38+
collectionCheck: false,
39+
defaultCapacity: initializedSize,
40+
maxSize: maxSize
41+
);
42+
}
43+
44+
public GameObject Create()
45+
{
46+
return _pool.Get();
47+
}
48+
49+
public void Clear()
50+
{
51+
_pool.Clear();
52+
}
53+
54+
public void Destroy(GameObject obj)
55+
{
56+
if (obj != null)
57+
Object.Destroy(obj);
58+
}
59+
60+
public GameObject Get()
61+
{
62+
return _pool.Get();
63+
}
64+
65+
// NOTE: 实现一个回调函数, 实现 After Get
66+
67+
public void Release(GameObject obj)
68+
{
69+
_pool.Release(obj);
70+
}
71+
}
72+
}

Assets/Framework/Scripts/Utilities/ObjectPool/GameObjectPool.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Framework/Scripts/Utilities/ObjectPool/IObjectPool.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ namespace Framework.Utilities.ObjectPool
22
{
33
public interface IObjectPool<T>
44
{
5+
int InitializedSize { get; }
6+
int MaxSize { get; }
7+
58
T Get();
9+
T Create();
610
void Release(T obj);
11+
void Destroy(T obj);
712
void Clear();
813
}
914
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using UnityEngine;
2+
3+
namespace Framework.Utilities.ObjectPool
4+
{
5+
/// <summary>
6+
/// 工厂方法, 用于管理所有的对象池
7+
/// </summary>
8+
public interface IPoolManager
9+
{
10+
IObjectPool<T> GetPool<T>(string key = null) where T : class;
11+
IObjectPool<T> CreatePool<T>(string key, IObjectPool<T> pool);
12+
bool TryRelease<T>(T item) where T : class;
13+
}
14+
}

Assets/Framework/Scripts/Utilities/ObjectPool/IPoolManager.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Collections.Generic;
2+
using Framework.Core.Service;
3+
using UnityEngine;
4+
5+
namespace Framework.Utilities.ObjectPool
6+
{
7+
[Service]
8+
public class PoolManager : IPoolManager
9+
{
10+
private readonly Dictionary<string, object> pools = new();
11+
12+
public IObjectPool<T> CreatePool<T>(string key, IObjectPool<T> pool)
13+
{
14+
if (pools.ContainsKey(Hash(key)))
15+
{
16+
Debug.LogWarning($"Pool already exists for key:{key}");
17+
return pool;
18+
}
19+
20+
pools.Add(Hash(key), pool);
21+
22+
return pool;
23+
}
24+
25+
public IObjectPool<T> GetPool<T>(string key = null) where T : class
26+
{
27+
if (pools.TryGetValue(Hash(key), out var p))
28+
return (IObjectPool<T>)p;
29+
return null;
30+
}
31+
32+
// 自动匹配类型, 尝试释放对象到对应池子
33+
public bool TryRelease<T>(T item) where T : class
34+
{
35+
foreach (var p in pools.Values)
36+
{
37+
if (p is IObjectPool<T> pool)
38+
{
39+
pool.Release(item);
40+
return true;
41+
}
42+
}
43+
return false;
44+
}
45+
46+
/// <summary>
47+
/// 是否要做一层key的映射?使得出现不同类型的池子但是可以有相同名字
48+
/// </summary>
49+
/// <param name="key"></param>
50+
/// <returns></returns>
51+
public string Hash(string key)
52+
{
53+
return key;
54+
}
55+
}
56+
}

Assets/Framework/Scripts/Utilities/ObjectPool/PoolManager.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Framework/Tests/Utilities.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using UnityEngine;
2+
using NUnit.Framework;
3+
using Framework.Core.Service;
4+
using Framework.Utilities.ObjectPool;
5+
6+
namespace Tests
7+
{
8+
public class PoolManagerTests
9+
{
10+
public GameObject prefab;
11+
public GameObject parent;
12+
public ServiceLocator serviceManager;
13+
14+
[SetUp]
15+
public void SetUp()
16+
{
17+
prefab = new GameObject("TestPrefab");
18+
serviceManager = new();
19+
parent = new GameObject("TestParent");
20+
serviceManager.RegisterSingleton(serviceManager);
21+
}
22+
23+
[Test]
24+
public void CreateAndGetPool_Works()
25+
{
26+
var poolManager = serviceManager.Resolve<PoolManager>();
27+
var pool = new GameobjectPool(parent.transform, prefab, 5, 20);
28+
var returnedPool = poolManager.CreatePool("TestPool", pool);
29+
Assert.AreEqual(pool, returnedPool);
30+
var fetchPool = poolManager.GetPool<GameObject>("TestPool");
31+
Assert.AreEqual(pool, fetchPool);
32+
}
33+
34+
[Test]
35+
public void PoolOperation_Works()
36+
{
37+
var poolManager = serviceManager.Resolve<PoolManager>();
38+
var pool = new GameobjectPool(parent.transform, prefab, 5, 20);
39+
poolManager.CreatePool("Op", pool);
40+
var obj = pool.Get();
41+
Assert.IsNotNull(obj);
42+
pool.Release(obj);
43+
44+
var tryReleaseOut = poolManager.TryRelease(obj);
45+
Assert.IsTrue(tryReleaseOut);
46+
}
47+
48+
[TearDown]
49+
public void TearDown()
50+
{
51+
Object.DestroyImmediate(prefab);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)