GroveGames.ObjectPool
0.0.15
dotnet add package GroveGames.ObjectPool --version 0.0.15
NuGet\Install-Package GroveGames.ObjectPool -Version 0.0.15
<PackageReference Include="GroveGames.ObjectPool" Version="0.0.15" />
<PackageVersion Include="GroveGames.ObjectPool" Version="0.0.15" />
<PackageReference Include="GroveGames.ObjectPool" />
paket add GroveGames.ObjectPool --version 0.0.15
#r "nuget: GroveGames.ObjectPool, 0.0.15"
#:package GroveGames.ObjectPool@0.0.15
#addin nuget:?package=GroveGames.ObjectPool&version=0.0.15
#tool nuget:?package=GroveGames.ObjectPool&version=0.0.15
GroveGames.ObjectPool
A high-performance object pooling library for .NET, Unity, and Godot with Native AOT support. Built for game development scenarios where allocation-free code is critical.
Features
- Generic Object Pooling: Pool any reference type with customizable factory, rent, and return callbacks
- Collection Pools: Specialized pools for List, Dictionary, Queue, Stack, HashSet, LinkedList, and Array
- Thread-Safe Variants: Concurrent versions of all pools for multi-threaded scenarios
- Multi-Type Pooling: Pool multiple derived types with a single pool using frozen dictionaries
- Rental Pattern: Ref struct-based rentals for automatic return via
usingstatements - Native AOT Compatible: Fully supports ahead-of-time compilation for maximum performance
- Unity Integration: GameObjectPool and ComponentPool with automatic activation management
- Godot Integration: Available as a Godot addon
.NET
Install via NuGet:
dotnet add package GroveGames.ObjectPool
Basic Object Pooling
using GroveGames.ObjectPool;
var pool = new ObjectPool<MyObject>(
factory: () => new MyObject(),
onRent: obj => obj.Initialize(),
onReturn: obj => obj.Reset(),
initialSize: 10,
maxSize: 100
);
var obj = pool.Rent();
obj.DoWork();
pool.Return(obj);
pool.Dispose();
Using the Rental Pattern
The rental pattern provides automatic return via using statements with zero-allocation ref structs:
using GroveGames.ObjectPool;
var pool = new ObjectPool<MyObject>(
() => new MyObject(),
null,
obj => obj.Reset(),
0,
100
);
using (pool.Rent(out var obj))
{
obj.DoWork();
}
Collection Pools
Pool collections to avoid repeated allocations:
using GroveGames.ObjectPool;
var listPool = new ListPool<int>(initialSize: 5, maxSize: 50);
var list = listPool.Rent();
list.Add(1);
list.Add(2);
list.Add(3);
listPool.Return(list);
using (listPool.Rent(out var items))
{
items.Add(42);
ProcessItems(items);
}
Available collection pools:
ListPool<T>- PoolsList<T>instancesDictionaryPool<TKey, TValue>- PoolsDictionary<TKey, TValue>instancesQueuePool<T>- PoolsQueue<T>instancesStackPool<T>- PoolsStack<T>instancesHashSetPool<T>- PoolsHashSet<T>instancesLinkedListPool<T>- PoolsLinkedList<T>instancesArrayPool<T>- Pools array instances
Thread-Safe Pools
Use concurrent pools for multi-threaded scenarios:
using GroveGames.ObjectPool.Concurrent;
var concurrentPool = new ConcurrentObjectPool<MyObject>(
() => new MyObject(),
null,
obj => obj.Reset(),
10,
100
);
var concurrentListPool = new ConcurrentListPool<int>(5, 50);
var concurrentDictPool = new ConcurrentDictionaryPool<string, int>(5, 50);
Multi-Type Object Pool
Pool multiple derived types with a single pool interface:
using GroveGames.ObjectPool;
public abstract class Enemy { }
public class Zombie : Enemy { }
public class Skeleton : Enemy { }
public class Ghost : Enemy { }
var pools = new MultiTypeObjectPoolBuilder<Enemy>()
.AddPool(() => new Zombie(), null, null, 5, 20)
.AddPool(() => new Skeleton(), null, null, 5, 20)
.AddPool(() => new Ghost(), null, null, 3, 10)
.Build();
var multiPool = new MultiTypeObjectPool<Enemy>(pools);
var zombie = multiPool.Rent<Zombie>();
var skeleton = multiPool.Rent<Skeleton>();
multiPool.Return(zombie);
multiPool.Return(skeleton);
Core Components
IObjectPool<T>: Core pooling interface with Rent, Return, Clear, and DisposeObjectPool<T>: Main implementation with customizable callbacksObjectRental<T>: Ref struct for automatic return via using statementsListPool<T>,DictionaryPool<TKey, TValue>, etc.: Specialized collection poolsMultiTypeObjectPool<T>: Polymorphic pooling with frozen dictionary lookupMultiTypeObjectPoolBuilder<T>: Fluent builder for multi-type pools
Concurrent Components
ConcurrentObjectPool<T>: Thread-safe object poolConcurrentListPool<T>,ConcurrentDictionaryPool<TKey, TValue>, etc.: Thread-safe collection poolsConcurrentMultiTypeObjectPool<T>: Thread-safe polymorphic pooling
Unity
There are two installation steps required to use it in Unity.
Install
GroveGames.ObjectPoolfrom NuGet using NuGetForUnity. Open Window from NuGet → Manage NuGet Packages, search "GroveGames.ObjectPool" and press Install.Install the
GroveGames.ObjectPool.Unitypackage by referencing the git URL:
https://github.com/grovegs/ObjectPool.git?path=src/GroveGames.ObjectPool.Unity/Packages/com.grovegames.objectpool
With the Unity package, GameObjectPool and ComponentPool become available for pooling Unity objects with automatic activation/deactivation management.
GameObjectPool
using GroveGames.ObjectPool.Unity;
using UnityEngine;
public class BulletSpawner : MonoBehaviour
{
[SerializeField] private GameObject _bulletPrefab;
[SerializeField] private int _initialSize = 10;
[SerializeField] private int _maxSize = 100;
private GameObjectPool _pool;
private void Awake()
{
_pool = new GameObjectPool(_bulletPrefab, transform, _initialSize, _maxSize);
}
public GameObject SpawnBullet()
{
return _pool.Rent();
}
public void DespawnBullet(GameObject bullet)
{
_pool.Return(bullet);
}
private void OnDestroy()
{
_pool.Dispose();
}
}
GameObjectPool with Rental Pattern
using GroveGames.ObjectPool.Unity;
using UnityEngine;
public class EffectSpawner : MonoBehaviour
{
[SerializeField] private GameObject _effectPrefab;
private GameObjectPool _pool;
private void Awake()
{
_pool = new GameObjectPool(_effectPrefab, transform, 5, 20);
}
public void SpawnEffect(Vector3 position)
{
using (_pool.Rent(out var effect))
{
effect.transform.position = position;
}
}
}
ComponentPool
Pool specific components for type-safe access:
using GroveGames.ObjectPool.Unity;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField] private Enemy _enemyPrefab;
[SerializeField] private int _maxEnemies = 50;
private ComponentPool<Enemy> _pool;
private void Awake()
{
_pool = new ComponentPool<Enemy>(_enemyPrefab, transform, 0, _maxEnemies);
}
public Enemy SpawnEnemy(Vector3 position)
{
var enemy = _pool.Rent();
enemy.transform.position = position;
enemy.Initialize();
return enemy;
}
public void DespawnEnemy(Enemy enemy)
{
_pool.Return(enemy);
}
private void OnDestroy()
{
_pool.Dispose();
}
}
ComponentPool with Rental Pattern
using GroveGames.ObjectPool.Unity;
using UnityEngine;
public class ProjectileSystem : MonoBehaviour
{
[SerializeField] private Rigidbody _projectilePrefab;
private ComponentPool<Rigidbody> _pool;
private void Awake()
{
_pool = new ComponentPool<Rigidbody>(_projectilePrefab, transform, 10, 100);
}
public void FireProjectile(Vector3 position, Vector3 velocity)
{
using (_pool.Rent(out var projectile))
{
projectile.transform.position = position;
projectile.linearVelocity = velocity;
}
}
}
Unity Components
IGameObjectPool: Interface for GameObject poolingGameObjectPool: Pools GameObjects with automatic activation/deactivationGameObjectRental: Ref struct for automatic GameObject returnIComponentPool<T>: Interface for Component poolingComponentPool<T>: Pools Components with automatic activation/deactivationComponentRental<T>: Ref struct for automatic Component return
Godot
Install via NuGet:
dotnet add package GroveGames.ObjectPool.Godot
Download the Godot addon from the latest release and extract it to your project's addons folder. Enable the addon in Project Settings → Plugins.
res://
├── addons/
│ └── GroveGames.ObjectPool/
│ ├── plugin.cfg
│ └── ...
└── ...
Architecture
Performance Optimizations
- Ref Struct Rentals: Zero-allocation automatic return pattern
- Frozen Dictionaries: O(1) type lookup for multi-type pools
- Queue-Based Storage: Efficient FIFO pooling behavior
- Native AOT: Full compatibility with ahead-of-time compilation
- No Boxing: Generic constraints ensure no boxing allocations
Testing
Run tests:
dotnet test
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- System.Collections.Immutable (>= 9.0.9)
-
net10.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on GroveGames.ObjectPool:
| Package | Downloads |
|---|---|
|
GroveGames.Tween
Lightweight Tween library for Godot C# |
|
|
GroveGames.ObjectPool.Godot
High-performance object pooling library for .NET, Unity, and Godot with Native AOT support |
GitHub repositories
This package is not used by any popular GitHub repositories.