-
Notifications
You must be signed in to change notification settings - Fork 0
/
EntityPool.cs
120 lines (103 loc) · 3.27 KB
/
EntityPool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Binocle
{
public class EntityPool<T> where T : Entity
{
private static Queue<T> _objectQueue = new Queue<T>(10);
private Scene scene;
private Entity PoolEntity;
public EntityPool(Scene scene)
{
this.scene = scene;
PoolEntity = scene.CreateEntity<Entity>("Pool");
}
/// <summary>
/// warms up the cache filling it with a max of cacheCount objects
/// </summary>
/// <param name="cacheCount">new cache count</param>
public void WarmCache(int cacheCount)
{
cacheCount -= _objectQueue.Count;
if (cacheCount > 0)
{
for (var i = 0; i < cacheCount; i++) {
var e = scene.CreateEntity<T>("_pooledobject");
e.SetParent(PoolEntity);
e.gameObject.SetActive(false);
_objectQueue.Enqueue(e);
}
}
}
/// <summary>
/// trims the cache down to cacheCount items
/// </summary>
/// <param name="cacheCount">Cache count.</param>
public static void TrimCache(int cacheCount)
{
while (cacheCount > _objectQueue.Count)
{
_objectQueue.Dequeue();
}
}
/// <summary>
/// clears out the cache
/// </summary>
public static void ClearCache()
{
_objectQueue.Clear();
}
/// <summary>
/// pops an item off the stack if available creating a new item as necessary
/// </summary>
public T Obtain(string name)
{
if (_objectQueue.Count > 0)
{
var e = _objectQueue.Dequeue();
e.name = name;
e.gameObject.SetActive(true);
return e;
}
return scene.CreateEntity<T>(name);
}
/// <summary>
/// pushes an item back on the stack
/// </summary>
/// <param name="obj">Object.</param>
public void Free(T obj)
{
obj.name = "_pooledobject";
obj.gameObject.SetActive(false);
obj.SetParent(PoolEntity);
/*
// Remove all children
foreach(Transform child in obj.transform) {
GameObject.Destroy(child.gameObject);
}
// Remove all components
foreach (var comp in obj.GetComponents<Component>())
{
if (!(comp is Transform) && !(comp is T))
{
GameObject.Destroy(comp);
}
}
*/
_objectQueue.Enqueue(obj);
if (obj is IPoolableEntity)
((IPoolableEntity)obj).Reset();
}
}
/// <summary>
/// Objects implementing this interface will have {@link #reset()} called when passed to {@link #push(Object)}
/// </summary>
public interface IPoolableEntity
{
/// <summary>
/// Resets the object for reuse. Object references should be nulled and fields may be set to default values
/// </summary>
void Reset();
}
}