1
This repository has been archived on 2025-03-15. You can view files and clone it, but cannot push or open issues or pull requests.

138 lines
3.1 KiB
C#
Raw Normal View History

2025-03-15 20:02:21 +01:00
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
/// Generic implementation for an object pool as described
/// at https://en.wikipedia.org/wiki/Object_pool_pattern.
/// Can be used to pool any class with a default constructor.
///
/// If you need to do more than just call a default constructor when
/// allocating an object of type T or returning an object to the pool,
/// then create a subclass of ObjectPool to specialize it for a particular
/// type of object. See _GameObjectPool_ as an example.
public class ObjectPool<T> : IObjectPool where T : class, new() {
protected Stack<T> pool;
protected int capacity;
public int NumAllocatedObjects {
get {
return pool.Count;
}
}
public bool IsPoolEmpty {
get {
return pool.Count == 0;
}
}
public bool IsPoolFull {
get {
return pool.Count == capacity;
}
}
protected ObjectPool() {
}
public ObjectPool(int capacity) : this(capacity, 0) {
}
public ObjectPool(int capacity, int preAllocateAmount) {
Initialize(capacity, preAllocateAmount);
}
public T Borrow() {
if (IsPoolEmpty) {
return AllocateObject();
}
T obj = pool.Pop();
OnBorrowed(obj);
return obj;
}
public void Return(T obj) {
// Don't return object if pool is already full.
if (IsPoolFull) {
OnUnableToReturn(obj);
return;
}
pool.Push(obj);
OnPooled(obj);
}
public void Clear() {
pool.Clear();
}
public void Allocate(int amount) {
int counter = 0;
while (counter < amount && !IsPoolFull) {
AddObject();
}
}
public virtual void Dispose() {
}
protected void Initialize(int capacity, int preAllocateAmount) {
if (capacity < 1) {
Debug.LogWarning("Capacity must be at least 1.");
capacity = 1;
}
pool = new Stack<T>(capacity);
this.capacity = capacity;
if (preAllocateAmount > capacity) {
Debug.LogWarning("preAllocateAmount cannot be higher than capacity.");
preAllocateAmount = capacity;
}
Allocate(preAllocateAmount);
}
protected virtual void OnBorrowed(T borrowedObject) {
}
protected virtual void OnPooled(T returnedObject) {
}
protected virtual void OnUnableToReturn(T returnedObject) {
}
protected virtual T AllocateObject() {
return new T();
}
private void AddObject() {
if (IsPoolFull) {
Debug.LogWarning("Cannot addObject, pool is already full.");
return;
}
T obj = AllocateObject();
pool.Push(obj);
OnPooled(obj);
}
}