123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- using System;
- using System.Collections.Generic;
- namespace Asset_Cleaner {
- class Pool<T> : IDisposable where T : class {
- Func<T> _ctor;
- readonly Stack<T> _stack;
- // todo place asserts on app quit
- Action<T> _reset;
- Action<T> _destroy;
- static Action<T> Empty = _ => { };
- 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);
- }
- }
- }
- }
|