Created
March 31, 2020 06:55
-
-
Save korchoon/d791e9fc8e4188c96b4739c01f09782b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Pool<T> : IDisposable where T : class { | |
static Action<T> Empty { get; } = _ => { }; | |
Func<T> _ctor; | |
readonly Stack<T> _stack; | |
// todo place asserts on app quit | |
Action<T> _reset; | |
Action<T> _destroy; | |
public Pool(Func<T> ctor, Action<T> reset, Action<T> destroy = null) { | |
_ctor = ctor; | |
#if !M_DISABLE_POOLING | |
_destroy = destroy ?? Empty; | |
_reset = reset; | |
_stack = new Stack<T>(); | |
#endif | |
} | |
public T Get() { | |
#if M_DISABLE_POOLING | |
return _ctor.Invoke(); | |
#else | |
T element; | |
if (_stack.Count == 0) | |
element = _ctor(); | |
else | |
element = _stack.Pop(); | |
return element; | |
#endif | |
} | |
public void Release(ref T element) { | |
#if !M_DISABLE_POOLING | |
Asr.IsFalse(_stack.Count > 0 && ReferenceEquals(_stack.Peek(), element), | |
"Internal error. Trying to release object that is already released to pool. "); | |
_reset.Invoke(element); | |
_stack.Push(element); | |
#endif | |
element = null; | |
} | |
public void Dispose() { | |
#if !M_DISABLE_POOLING | |
while (_stack.Count > 0) { | |
var t = _stack.Pop(); | |
_destroy.Invoke(t); | |
} | |
#endif | |
} | |
public _Scope GetScoped(out T tmp) { | |
tmp = Get(); | |
return new _Scope(this, ref tmp); | |
} | |
public struct _Scope : IDisposable { | |
Pool<T> _pool; | |
T _val; | |
internal _Scope(Pool<T> pool, ref T val) { | |
_pool = pool; | |
_val = val; | |
} | |
public void Dispose() { | |
_pool.Release(ref _val); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment