Skip to content

Commit 0334452

Browse files
committed
Improved example scene, Improved documentation, Marked PoolUtils internal to simplify API, Fixed an issue where Pool would never reach max size.
1 parent 07b803f commit 0334452

15 files changed

+313
-59
lines changed

Runtime/Asset/PoolAsset.cs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,62 @@
33
namespace BP.RefPool
44
{
55
/// <summary>
6-
/// ScriptableObject asset representing a pool for GameObjects.
6+
/// ScriptableObject representing a pooled GameObject resource.
7+
/// This asset acts as a referenceable and configurable container for a shared object pool.
78
/// </summary>
89
[CreateAssetMenu(fileName = "Pool", menuName = "RefPool/Pool")]
910
public class PoolAsset : PoolResource
1011
{
1112
[SerializeField] private string poolName;
1213
[SerializeField] private GameObject prefab;
13-
[SerializeField] private int initSize;
14-
[SerializeField] private int maxSize;
15-
[SerializeField] private bool reuseObjects;
16-
[SerializeField] private bool isPersistent;
14+
[SerializeField] private int initSize = 10;
15+
[SerializeField] private int maxSize = 100;
16+
[SerializeField] private bool reuseObjects = true;
17+
[SerializeField] private bool isPersistent = false;
18+
19+
private IPool poolRef;
1720

1821
/// <summary>
19-
/// Gets the name of the pool.
20-
/// </summary>
21-
public string PoolName => poolName;
22+
/// Display name of the pool. Defaults to the prefab name if unset.
23+
/// </summary>O
24+
public string PoolName => string.IsNullOrEmpty(poolName) && prefab ? prefab.name : poolName;
2225

2326
/// <summary>
24-
/// Gets the prefab associated with this pool.
27+
/// The prefab that will be pooled.
2528
/// </summary>
2629
public GameObject Prefab => prefab;
2730

2831
/// <summary>
29-
/// Gets the initial size of the pool.
32+
/// Number of instances to preallocate at initialization.
3033
/// </summary>
3134
public int InitSize => initSize;
35+
3236
/// <summary>
33-
/// Gets the maximum size of the pool.
37+
/// Maximum number of instances allowed in the pool.
3438
/// </summary>
3539
public int MaxSize => maxSize;
3640

3741
/// <summary>
38-
/// Gets a value indicating whether objects in the pool should be reused.
42+
/// Whether the pool reuses released instances when max size is reached.
3943
/// </summary>
4044
public bool ReuseObjects => reuseObjects;
4145

4246
/// <summary>
43-
/// Gets a value indicating whether the pool should persist across scene loads.
47+
/// Whether the pool persists across scene changes.
4448
/// </summary>
4549
public bool IsPersistent => isPersistent;
4650

47-
private IPool poolRef;
51+
private void OnValidate()
52+
{
53+
if (string.IsNullOrEmpty(poolName) && prefab != null)
54+
{
55+
poolName = prefab.name;
56+
}
57+
}
4858

59+
/// <summary>
60+
/// Initializes the internal pool if it hasn't been created yet.
61+
/// </summary>
4962
public override void Initialize()
5063
{
5164
if (PoolUtils.IsNull(poolRef))
@@ -54,13 +67,20 @@ public override void Initialize()
5467
poolRef.Initialize();
5568
}
5669
}
70+
71+
/// <summary>
72+
/// Gets an instance from the pool, creating the pool if necessary.
73+
/// </summary>
5774
public override GameObject Get() => GetPool().Get();
75+
76+
/// <summary>
77+
/// Returns an instance to the pool.
78+
/// </summary>
5879
public override bool Release(GameObject gameObject) => poolRef?.Release(gameObject) ?? false;
5980

6081
/// <summary>
61-
/// Gets the pool instance, creating it if necessary.
82+
/// Ensures the pool is initialized and returns the internal pool reference.
6283
/// </summary>
63-
/// <returns>The pool instance implementing IPoolable.</returns>
6484
private IPool GetPool()
6585
{
6686
Initialize();

Runtime/Asset/PoolGroupAsset.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,67 @@
33
namespace BP.RefPool
44
{
55
/// <summary>
6-
/// Enumeration for selecting the pooling strategy.
7-
/// </summary>
8-
public enum PoolPickMode
9-
{
10-
Random,
11-
Sequential,
12-
Back2Back
13-
}
14-
15-
/// <summary>
16-
/// ScriptableObject asset representing a group of pools.
6+
/// ScriptableObject representing a referenceable group of pool assets.
7+
/// Allows configuring pooled objects and pick strategy via asset.
178
/// </summary>
189
[CreateAssetMenu(fileName = "PoolGroup", menuName = "RefPool/Pool Group")]
1910
public class PoolGroupAsset : PoolResource
2011
{
21-
[SerializeField] private string groupName;
12+
[SerializeField] private string groupName = "New Group";
2213
[SerializeField] private PoolPickMode pickMode = PoolPickMode.Random;
2314
[SerializeField] private PoolAsset[] pools;
24-
[SerializeField] private bool isPersistent;
15+
[SerializeField] private bool isPersistent = false;
16+
17+
private PoolGroup groupRef;
2518

2619
/// <summary>
27-
/// Gets the name of the pool group.
20+
/// Optional display name for the pool group.
2821
/// </summary>
2922
public string GroupName => groupName;
3023

3124
/// <summary>
32-
/// Gets the picking mode for selecting pools.
25+
/// Strategy used to pick which pool to pull from.
3326
/// </summary>
3427
public PoolPickMode PickMode => pickMode;
3528

3629
/// <summary>
37-
/// Gets the array of pool assets in the group.
30+
/// Array of pool assets that make up this group.
3831
/// </summary>
3932
public PoolAsset[] Pools => pools;
4033

4134
/// <summary>
42-
/// Gets a value indicating whether the pool group should persist across scene loads.
35+
/// Whether this group should persist across scene loads.
4336
/// </summary>
4437
public bool IsPersistent => isPersistent;
4538

46-
private PoolGroup groupRef;
47-
39+
/// <summary>
40+
/// Initializes the internal PoolGroup instance.
41+
/// </summary>
4842
public override void Initialize()
4943
{
50-
if (PoolUtils.IsNull(groupRef))
44+
if (groupRef == null)
5145
{
5246
groupRef = PoolUtils.CreatePoolGroup(this);
5347
groupRef.Initialize();
5448
}
5549
}
50+
51+
/// <summary>
52+
/// Gets a pooled object using the group strategy.
53+
/// </summary>
5654
public override GameObject Get() => GetPoolGroup().Get();
55+
56+
/// <summary>
57+
/// Attempts to release the GameObject to one of the internal pools.
58+
/// </summary>
5759
public override bool Release(GameObject gameObject)
5860
{
59-
if (PoolUtils.IsNull(groupRef)) return false;
60-
return groupRef.Release(gameObject);
61+
return groupRef != null && groupRef.Release(gameObject);
6162
}
63+
64+
/// <summary>
65+
/// Ensures the group is initialized and returns the internal reference.
66+
/// </summary>
6267
private PoolGroup GetPoolGroup()
6368
{
6469
Initialize();

Runtime/Components/Pool.cs

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,87 @@
44
namespace BP.RefPool
55
{
66
/// <summary>
7-
/// A simple pool implementation.
7+
/// A basic GameObject pool that supports initialization, reuse, and optional persistence across scenes.
88
/// </summary>
99
public class Pool : PoolComponent
1010
{
1111
[SerializeField] private GameObject prefab;
12-
[SerializeField] private int initSize;
13-
[SerializeField] private int maxSize;
14-
[SerializeField] private bool reuseObjects;
15-
[SerializeField] private bool dontDestroyOnLoad;
12+
[SerializeField] private int initSize = 10;
13+
[SerializeField] private int maxSize = 50;
14+
[SerializeField] private bool reuseObjects = false;
15+
[SerializeField] private bool dontDestroyOnLoad = false;
1616

17+
/// <summary>
18+
/// The prefab used for pooled instances.
19+
/// </summary>
1720
public GameObject Pooled { get => prefab; set => prefab = value; }
21+
22+
/// <summary>
23+
/// If true, old objects will be reused when the pool exceeds its maximum size.
24+
/// </summary>
1825
public bool ReuseObjects { get => reuseObjects; set => reuseObjects = value; }
26+
27+
/// <summary>
28+
/// Initial number of objects to populate in the pool.
29+
/// </summary>
1930
public int InitSize { get => initSize; set => initSize = value; }
31+
32+
/// <summary>
33+
/// Maximum number of objects allowed in the pool.
34+
/// </summary>
2035
public int MaxSize { get => maxSize; set => maxSize = value; }
2136

2237
private readonly Queue<GameObject> availableQueue = new();
2338
private readonly LinkedList<GameObject> usedList = new();
2439
private bool isInitialized;
2540

2641
private void Start() => Initialize();
42+
43+
/// <summary>
44+
/// Configures this pool using the data from a <see cref="PoolAsset"/>.
45+
/// </summary>
2746
public void SetAsset(PoolAsset asset)
2847
{
2948
prefab = asset.Prefab;
30-
reuseObjects = asset.ReuseObjects;
3149
initSize = asset.InitSize;
50+
maxSize = asset.MaxSize;
51+
reuseObjects = asset.ReuseObjects;
3252
dontDestroyOnLoad = asset.IsPersistent;
3353
}
3454

55+
/// <summary>
56+
/// Initializes the pool by instantiating the initial objects.
57+
/// </summary>
3558
public override void Initialize()
3659
{
3760
if (isInitialized) return;
61+
3862
if (dontDestroyOnLoad)
39-
{
4063
DontDestroyOnLoad(gameObject);
41-
}
4264

43-
for (var i = 0; i < initSize; i++)
65+
for (int i = 0; i < initSize; i++)
4466
{
4567
var item = CreatePooledObject();
4668
availableQueue.Enqueue(item);
4769
}
70+
4871
isInitialized = true;
4972
}
73+
74+
/// <summary>
75+
/// Retrieves a GameObject from the pool.
76+
/// </summary>
5077
public override GameObject Get()
5178
{
5279
GameObject item;
80+
5381
if (availableQueue.Count > 0)
5482
{
5583
item = availableQueue.Dequeue();
5684
}
5785
else if (usedList.Count < maxSize)
5886
{
5987
item = CreatePooledObject();
60-
usedList.AddFirst(item);
6188
}
6289
else if (reuseObjects && usedList.Count > 0)
6390
{
@@ -73,6 +100,10 @@ public override GameObject Get()
73100
usedList.AddFirst(item);
74101
return item;
75102
}
103+
104+
/// <summary>
105+
/// Returns a GameObject to the pool, if it was previously retrieved.
106+
/// </summary>
76107
public override bool Release(GameObject gameObject)
77108
{
78109
if (usedList.Contains(gameObject))
@@ -84,6 +115,21 @@ public override bool Release(GameObject gameObject)
84115
return false;
85116
}
86117

118+
/// <summary>
119+
/// Ensures this pool persists across scene loads.
120+
/// </summary>
121+
public override void MakePersistent()
122+
{
123+
if (!dontDestroyOnLoad)
124+
{
125+
dontDestroyOnLoad = true;
126+
DontDestroyOnLoad(gameObject);
127+
}
128+
}
129+
130+
/// <summary>
131+
/// Prepares a reused object by resetting it and disabling it.
132+
/// </summary>
87133
private void PrepareForReuse(GameObject pooledObject)
88134
{
89135
if (pooledObject.TryGetComponent<IPoolable>(out var poolable))
@@ -93,6 +139,10 @@ private void PrepareForReuse(GameObject pooledObject)
93139

94140
pooledObject.SetActive(false);
95141
}
142+
143+
/// <summary>
144+
/// Instantiates and sets up a new pooled object.
145+
/// </summary>
96146
private GameObject CreatePooledObject()
97147
{
98148
var go = Instantiate(prefab);
@@ -102,13 +152,5 @@ private GameObject CreatePooledObject()
102152
go.transform.SetParent(transform);
103153
return go;
104154
}
105-
public override void MakePersistent()
106-
{
107-
if (!dontDestroyOnLoad)
108-
{
109-
dontDestroyOnLoad = true;
110-
DontDestroyOnLoad(gameObject);
111-
}
112-
}
113155
}
114156
}

Runtime/PickMode.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace BP.RefPool
2+
{
3+
/// <summary>
4+
/// Enumeration for selecting the pooling strategy.
5+
/// </summary>
6+
public enum PoolPickMode
7+
{
8+
Random,
9+
Sequential,
10+
Back2Back
11+
}
12+
}

Runtime/PickMode.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.

Runtime/PoolUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace BP.RefPool
44
{
5-
public static class PoolUtils
5+
internal static class PoolUtils
66
{
77
const string POOL_NAME_PREFIX = "[POOL]_";
88
const string POOLGROUP_NAME_PREFIX = "[PGROUP]_";

Samples/Basic.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.

0 commit comments

Comments
 (0)