- org.nuget.system.runtime.compilerservices.unsafe@6.0.0
- com.cysharp.unitask
- com.laicasaane.collections.pooled
The related modules will be enabled automatically when the com.unity.addressables package is installed.
You can install this package from the Open UPM registry.
More details here.
openupm add com.zbase.foundation.pooling
- Open the Poject Settings window
- Navigate to the Package Manager section
- Add a new Scoped Registry
"name": "Unity NuGet",
"url": "https://unitynuget-registry.azurewebsites.net",
"scopes": [
"org.nuget"
]
- Open the Package Manager window
- Select the Add package from git URL option from the
+
dropdown - Enter this git url:
https://github.com/Zitga-Tech/ZBase.Foundation.Pooling.git?path=Packages/ZBase.Foundation.Pooling
The entire package is built upon these 2 interfaces:
IPool<T>
defines synchronous APIs, mostly for pooling C# objects.IAsyncPool<T>
defines asynchronous APIs, mostly for pooling Unity objects.
These are the basic pools that implement the most generic functions for pooling C# objects:
Pool<T, TInstantiator>
AsyncPool<T, T Instantiator>
Pool<T>
AsyncPool<T>
For basic pooling, Pool<T>
and AsyncPool<T>
are ready-to-use.
It should be noted that Pool<T>
and AsyncPool<T>
will create instances of T
through Activator.CreateInstance
by using these instantiators:
ActivatorInstantiator<T>
AsyncActivatorInstantiator<T>
This module also provides instantiators that use default constructor:
DefaultConstructorInstantiator<T>
AsyncDefaultConstructorInstantiator<T>
However the type T
must satisfy this constraint on the instantiators
where T : class, new()
T
must be a reference typeT
must have a public parameterless constructor (ie. default constructor)
Example usage
public class MyClass { }
...
var pool = new Pool<MyClass, DefaultConstructorInstantiator<MyClass>>(); // Works
...
var pool = new Pool<string, DefaultConstructorInstantiator<string>>(); // Error!
Alternately, users can define custom instantiators for specific types by implementing IInstantiable<T>
:
public struct MyClassInstantiator : IInstantiable<MyClass>
{
public MyClass Instantiate() => new MyClass();
}
...
var pool = new Pool<MyClass, MyClassInstantiator>();
SharedPool.Of<T>
will return a shared instance (aka singleton) of any type that satisfy this constraint:
where T : IPool, IShareable, new()
T
must implementIPool
andIShareable
T
must have a public parameterless constructor (ie. default constructor)
Example usage
var myClassPool = SharedPool.Of< Pool<MyClass> >();
var listPool = SharedPool.Of< ListPool<int> >();
Leverage IDisposable
interface to automatically return instances to the pool at the end of their usage.
- Get the context by calling
.DisposableContext()
(extension method) on the pool. - Apply
using
when renting from the context so the disposing mechanism can be automated.
Example usage
var pool = SharedPool.Of< ListPool<int> >();
var disposablePool = pool.DisposableContext(); // Get the context
using var instance = disposablePool.Rent(); // Rent from the context with `using`
using (var otherInstance = disposablePool.Rent()) // Explicit `using` scope
{
// work with `otherInstance`
} // `otherInstance` will be returned to the pool automatically
// End of the Method
// `instance` will be returned to the pool automatically
Are the pools for collection instances (such as List
, Dictionary
and so on).
ListPool<T>
HashSetPool<T>
QueuePool<T>
StackPool<T>
DictionaryPool<TKey, TValue>
They are implemented the same in these 2 modules:
System.Collections.Generic.Pooling
Collections.Pooled.Generic.Pooling
var listInst = SharedPool.Of< ListPool<int> >().Rent();
var myClassInst = SharedPool.Of< Pool<MyClass> >().Rent();
var dictPool = new DictionaryPool<int, string>();
var dictInst = dictPool.Rent();
This module provides basic facility to pooling Unity objects, especially GameObject
and Component
:
UnityPool<T, TPrefab>
is the base for Unity object pools.IPrefab
to implement custom Unity object instantiators.IPrepooler<T, TPrefab, TPool>
to implement custom prepooling mechanism.UnityPoolBehaviour<T, ...>
is the base for pooling components attached on aGameObject
.
All the pools implemented in this module are ready-to-use.
UnityPool<T, TPrefab>
GameObjectPool<TPrefab>
GameObjectPool
ComponentPool<T, TPrefab>
ComponentPool<T>
var goPool = new GameObjectPool();
var colliderPool = new ComponentPool<BoxCollider>();
Prefab is a way to change how pools would instantiate or release their objects.
UnityPrefab<T, TSource>
GameObjectPrefab
ComponentPrefab<T>
If customization is needed, a subtype of UnityPrefab<T, TSource>
must be implemented then passed to the generic pool that accept TPrefab
.
public class CustomGameObjectPrefab : UnityPrefab<GameObject, GameObject>
{
protected override async UniTask<GameObject> Instantiate(GameObject source, Transform parent)
{
// implement Instiatate method
}
public override void Release(GameObject instance)
{
// implement Release method
}
}
...
var poolA = new GameObjectPool<CustomGameObjectPrefab>();
var poolB = new UnityPool<GameObject, CustomGameObjectPrefab>()
Alternately any type implements IPrefab<T>
works the same way.
public class SimpleGameObjectPrefab : IPrefab<GameObject>
{
public async UniTask<GameObject> Instantiate()
{
// implement Instiatate method
}
public void Release(GameObject instance)
{
// implement Release method
}
}
...
var poolA = new GameObjectPool<SimpleGameObjectPrefab>();
var poolB = new UnityPool<GameObject, SimpleGameObjectPrefab>()
These are wrappers of the pools, derived from MonoBehaviour
:
PoolBehaviour<T, TPool>
UnityPoolBehaviour<T, TPrefab, TPool>
GameObjectPoolBehaviour
ComponentPoolBehaviour<T>
Only GameObjectPoolBehaviour
is ready-to-use.
Others require declaring non-generic subtypes:
public class BoxColliderPoolBehaviour
: ComponentPoolBehaviour<BoxCollider>
{ }
public class SpritePoolBehaviour
: UnityPoolBehaviour<SpriteRenderer, SpritePrefab, ComponentPool<SpriteRenderer>>
{ }
This module offers 2 ways to work with Addressables:
Address*
requires astring
address to load the assetAssetRef*
requires anAssetReference
All the pools implemented in this module are ready-to-use.
String Address | AssetReference |
---|---|
AddressComponentPool<T, TPrefab> |
AssetRefComponentPool<T> |
AddressComponentPool<T> |
AssetRefGameObjectPool |
AddressGameObjectPool<TPrefab> |
|
AddressGameObjectPool |
String Address | AssetReference |
---|---|
AddressPrefab<T> |
AssetRefPrefab<T, TAssetRef> |
AddressComponentPrefab<T> |
AssetRefComponentPrefab<T> |
AddressGameObjectPrefab |
AssetRefGameObjectPrefab |
Addressables
and AssetReference
to instantiate objects. But this behaviour can be changed by declaring subtypes and overriding the Instantiate
method.