11using System . Collections . Generic ;
22using UnityEngine ;
3+ #if ZENJECT
4+ using Zenject ;
5+ #endif
36
47namespace ToolBox . Pools
58{
6- internal sealed class Pool
7- {
8- private readonly Poolable _prefab = null ;
9- private readonly Stack < Poolable > _instances = null ;
10- private readonly Quaternion _rotation = default ;
11- private readonly Vector3 _scale = default ;
9+ internal sealed class Pool
10+ {
11+ private readonly Poolable _prefab = null ;
12+ private readonly Stack < Poolable > _instances = null ;
13+ private readonly Quaternion _rotation = default ;
14+ private readonly Vector3 _scale = default ;
15+ #if ZENJECT
16+ private readonly DiContainer _projectContainer = null ;
17+ #endif
18+
19+ private static readonly Dictionary < GameObject , Pool > _prefabLookup = new Dictionary < GameObject , Pool > ( 64 ) ;
20+ private static readonly Dictionary < GameObject , Pool > _instanceLookup = new Dictionary < GameObject , Pool > ( 512 ) ;
1221
13- private static readonly Dictionary < GameObject , Pool > _prefabLookup = new Dictionary < GameObject , Pool > ( 64 ) ;
14- private static readonly Dictionary < GameObject , Pool > _instanceLookup = new Dictionary < GameObject , Pool > ( 512 ) ;
22+ private const int CAPACITY = 128 ;
1523
16- private const int CAPACITY = 128 ;
24+ public Pool ( GameObject prefab )
25+ {
26+ _prefab = prefab . GetComponent < Poolable > ( ) ;
1727
18- public Pool ( GameObject prefab )
19- {
20- _prefab = prefab . GetComponent < Poolable > ( ) ;
28+ if ( _prefab == null )
29+ {
30+ _prefab = Object . Instantiate ( prefab ) . AddComponent < Poolable > ( ) ;
31+ Object . DontDestroyOnLoad ( _prefab ) ;
32+ _prefab . gameObject . SetActive ( false ) ;
33+ }
2134
22- if ( _prefab == null )
23- {
24- _prefab = Object . Instantiate ( prefab ) . AddComponent < Poolable > ( ) ;
25- Object . DontDestroyOnLoad ( _prefab ) ;
26- _prefab . gameObject . SetActive ( false ) ;
27- }
35+ #if ZENJECT
36+ _projectContainer = ProjectContext . Instance . Container ;
37+ #endif
38+ _instances = new Stack < Poolable > ( CAPACITY ) ;
39+ _prefabLookup . Add ( prefab , this ) ;
2840
29- _instances = new Stack < Poolable > ( CAPACITY ) ;
30- _prefabLookup . Add ( prefab , this ) ;
41+ var transform = prefab . transform ;
42+ _rotation = transform . rotation ;
43+ _scale = transform . localScale ;
44+ }
3145
32- var transform = prefab . transform ;
33- _rotation = transform . rotation ;
34- _scale = transform . localScale ;
35- }
46+ public static Pool GetPrefabPool ( GameObject prefab )
47+ {
48+ bool hasPool = _prefabLookup . TryGetValue ( prefab , out var pool ) ;
3649
37- public static Pool GetPrefabPool ( GameObject prefab )
38- {
39- bool hasPool = _prefabLookup . TryGetValue ( prefab , out var pool ) ;
50+ if ( ! hasPool )
51+ pool = new Pool ( prefab ) ;
4052
41- if ( ! hasPool )
42- pool = new Pool ( prefab ) ;
53+ return pool ;
54+ }
4355
44- return pool ;
45- }
56+ public static bool TryGetInstancePool ( GameObject instance , out Pool pool ) =>
57+ _instanceLookup . TryGetValue ( instance , out pool ) ;
4658
47- public static bool TryGetInstancePool ( GameObject instance , out Pool pool ) =>
48- _instanceLookup . TryGetValue ( instance , out pool ) ;
59+ public void Populate ( int count )
60+ {
61+ for ( int i = 0 ; i < count ; i ++ )
62+ _instances . Push ( CreateInstance ( ) ) ;
63+ }
64+
65+ public GameObject Get ( )
66+ {
67+ var instance = GetInstance ( ) ;
68+
69+ return instance . gameObject ;
70+ }
71+
72+ public GameObject Get ( Transform parent )
73+ {
74+ var instance = GetInstance ( ) ;
75+
76+ instance . transform . SetParent ( parent ) ;
77+
78+ return instance . gameObject ;
79+ }
80+
81+ public GameObject Get ( Transform parent , bool worldPositionStays )
82+ {
83+ var instance = GetInstance ( ) ;
84+
85+ instance . transform . SetParent ( parent , worldPositionStays ) ;
86+
87+ return instance . gameObject ;
88+ }
89+
90+ public GameObject Get ( Vector3 position , Quaternion rotation )
91+ {
92+ var instance = GetInstance ( ) ;
93+
94+ instance . transform . SetPositionAndRotation ( position , rotation ) ;
95+
96+ return instance . gameObject ;
97+ }
98+
99+ public GameObject Get ( Vector3 position , Quaternion rotation , Transform parent )
100+ {
101+ var instance = GetInstance ( ) ;
102+ var instanceTransform = instance . transform ;
103+
104+ instanceTransform . SetPositionAndRotation ( position , rotation ) ;
105+ instanceTransform . SetParent ( parent ) ;
106+
107+ return instance . gameObject ;
108+ }
109+
110+ public void Release ( GameObject instance )
111+ {
112+ var poolable = instance . GetComponent < Poolable > ( ) ;
113+ poolable . OnRelease ( ) ;
114+
115+ instance . SetActive ( false ) ;
116+
117+ var instanceTransform = instance . transform ;
118+ instanceTransform . SetParent ( null ) ;
119+ instanceTransform . rotation = _rotation ;
120+ instanceTransform . localScale = _scale ;
121+
122+ _instances . Push ( poolable ) ;
123+ }
124+
125+ private Poolable GetInstance ( )
126+ {
127+ int count = _instances . Count ;
128+
129+ if ( count != 0 )
130+ {
131+ var instance = _instances . Pop ( ) ;
132+
133+ if ( instance == null )
134+ {
135+ count -- ;
136+
137+ while ( count != 0 )
138+ {
139+ instance = _instances . Pop ( ) ;
49140
50- public void Populate ( int count )
51- {
52- for ( int i = 0 ; i < count ; i ++ )
53- _instances . Push ( CreateInstance ( ) ) ;
54- }
141+ if ( instance != null )
142+ {
143+ instance . OnGet ( ) ;
144+ instance . gameObject . SetActive ( true ) ;
55145
56- public GameObject Get ( )
57- {
58- var instance = GetInstance ( ) ;
146+ return instance ;
147+ }
59148
60- return instance . gameObject ;
61- }
149+ count -- ;
150+ }
62151
63- public GameObject Get ( Transform parent )
64- {
65- var instance = GetInstance ( ) ;
66-
67- instance . transform . SetParent ( parent ) ;
68-
69- return instance . gameObject ;
70- }
71-
72- public GameObject Get ( Transform parent , bool worldPositionStays )
73- {
74- var instance = GetInstance ( ) ;
75-
76- instance . transform . SetParent ( parent , worldPositionStays ) ;
77-
78- return instance . gameObject ;
79- }
80-
81- public GameObject Get ( Vector3 position , Quaternion rotation )
82- {
83- var instance = GetInstance ( ) ;
84-
85- instance . transform . SetPositionAndRotation ( position , rotation ) ;
86-
87- return instance . gameObject ;
88- }
89-
90- public GameObject Get ( Vector3 position , Quaternion rotation , Transform parent )
91- {
92- var instance = GetInstance ( ) ;
93- var instanceTransform = instance . transform ;
94-
95- instanceTransform . SetPositionAndRotation ( position , rotation ) ;
96- instanceTransform . SetParent ( parent ) ;
97-
98- return instance . gameObject ;
99- }
100-
101- public void Release ( GameObject instance )
102- {
103- var poolable = instance . GetComponent < Poolable > ( ) ;
104- poolable . OnRelease ( ) ;
105-
106- instance . SetActive ( false ) ;
107-
108- var instanceTransform = instance . transform ;
109- instanceTransform . SetParent ( null ) ;
110- instanceTransform . rotation = _rotation ;
111- instanceTransform . localScale = _scale ;
112-
113- _instances . Push ( poolable ) ;
114- }
115-
116- private Poolable GetInstance ( )
117- {
118- int count = _instances . Count ;
119-
120- if ( count != 0 )
121- {
122- var instance = _instances . Pop ( ) ;
123-
124- if ( instance == null )
125- {
126- count -- ;
127-
128- while ( count != 0 )
129- {
130- instance = _instances . Pop ( ) ;
131-
132- if ( instance != null )
133- {
134- instance . OnGet ( ) ;
135- instance . gameObject . SetActive ( true ) ;
136-
137- return instance ;
138- }
139-
140- count -- ;
141- }
142-
143- instance = CreateInstance ( ) ;
144- instance . gameObject . SetActive ( true ) ;
145-
146- return instance ;
147- }
148- else
149- {
150- instance . OnGet ( ) ;
151- instance . gameObject . SetActive ( true ) ;
152-
153- return instance ;
154- }
155- }
156- else
157- {
158- var instance = CreateInstance ( ) ;
159- instance . gameObject . SetActive ( true ) ;
160-
161- return instance ;
162- }
163- }
164-
165- private Poolable CreateInstance ( )
166- {
167- var instance = Object . Instantiate ( _prefab ) ;
168- _instanceLookup . Add ( instance . gameObject , this ) ;
169-
170- return instance ;
171- }
172- }
173- }
152+ instance = CreateInstance ( ) ;
153+ instance . gameObject . SetActive ( true ) ;
154+
155+ return instance ;
156+ }
157+ else
158+ {
159+ instance . OnGet ( ) ;
160+ instance . gameObject . SetActive ( true ) ;
161+
162+ return instance ;
163+ }
164+ }
165+ else
166+ {
167+ var instance = CreateInstance ( ) ;
168+ instance . gameObject . SetActive ( true ) ;
169+
170+ return instance ;
171+ }
172+ }
173+
174+ private Poolable CreateInstance ( )
175+ {
176+ var instance = Object . Instantiate ( _prefab ) ;
177+ var instanceGameObject = instance . gameObject ;
178+ _instanceLookup . Add ( instanceGameObject , this ) ;
179+ #if ZENJECT
180+ _projectContainer
181+ . Resolve < SceneContextRegistry > ( )
182+ . GetContainerForScene ( instanceGameObject . scene )
183+ . InjectGameObject ( instanceGameObject ) ;
184+ #endif
185+
186+ return instance ;
187+ }
188+ }
189+ }
0 commit comments