1- using FishNet . Managing ;
2- using FishNet . Managing . Object ;
3- using FishNet . Object ;
4- using FishNet . Utility . Extension ;
5- using GameKit . Dependencies . Utilities ;
6- using System ;
7- using System . Collections . Generic ;
8- using System . Runtime . CompilerServices ;
9- using UnityEngine ;
10-
11- namespace FishNet . Utility . Performance
12- {
13- public class DefaultObjectPool : ObjectPool
14- {
15- #region Public.
16- /// <summary>
17- /// Cache for pooled NetworkObjects.
18- /// Key: CollectionId.
19- /// </summary>
20- public IReadOnlyList < Dictionary < int , Stack < NetworkObject > > > Cache => _cache ;
21- private List < Dictionary < int , Stack < NetworkObject > > > _cache = new ( ) ;
22- #endregion
23-
24- #region Serialized.
25- /// <summary>
26- /// True if to use object pooling.
27- /// </summary>
28- [ Tooltip ( "True if to use object pooling." ) ]
29- [ SerializeField ]
30- private bool _enabled = true ;
31- #endregion
32-
33- #region Private.
34- /// <summary>
35- /// Current count of the cache collection.
36- /// </summary>
37- private int _cacheCount = 0 ;
38- #endregion
39-
40- #pragma warning disable CS0672 // Member overrides obsolete member
41- public override NetworkObject RetrieveObject ( int prefabId , ushort collectionId , Transform parent = null , Vector3 ? nullablePosition = null , Quaternion ? nullableRotation = null , Vector3 ? nullableScale = null , bool makeActive = true , bool asServer = true )
42- #pragma warning restore CS0672 // Member overrides obsolete member
43- {
44- ObjectPoolRetrieveOption options = ObjectPoolRetrieveOption . Unset ;
45- if ( makeActive )
46- options |= ObjectPoolRetrieveOption . MakeActive ;
47-
48- return RetrieveObject ( prefabId , collectionId , options , parent , nullablePosition , nullableRotation , nullableScale , asServer ) ;
49- }
50-
51- /// <summary>
52- /// Returns an object that has been stored. A new object will be created if no stored objects are available.
53- /// </summary>
54- /// <param name="prefabId">PrefabId of the object to return.</param>
55- /// <param name="collectionId">CollectionId of the object to return.</param>
56- /// <param name="asServer">True if being called on the server side.</param>
57- /// <returns></returns>
58- public override NetworkObject RetrieveObject ( int prefabId , ushort collectionId , ObjectPoolRetrieveOption options , Transform parent = null , Vector3 ? nullablePosition = null , Quaternion ? nullableRotation = null , Vector3 ? nullableScale = null , bool asServer = true )
59- {
60- bool makeActive = options . FastContains ( ObjectPoolRetrieveOption . MakeActive ) ;
61- bool localSpace = options . FastContains ( ObjectPoolRetrieveOption . LocalSpace ) ;
62-
63- if ( ! _enabled )
64- return GetFromInstantiate ( ) ;
65-
66- Stack < NetworkObject > cache = GetCache ( collectionId , prefabId , createIfMissing : true ) ;
67- NetworkObject nob = null ;
68-
69- //Iterate until nob is populated just in case cache entries have been destroyed.
70- while ( nob == null )
71- {
72- if ( cache . TryPop ( out nob ) )
73- {
74- if ( nob != null )
75- {
76- nob . transform . SetParent ( parent ) ;
77- if ( localSpace )
78- nob . transform . SetLocalPositionRotationAndScale ( nullablePosition , nullableRotation , nullableScale ) ;
79- else
80- nob . transform . SetWorldPositionRotationAndScale ( nullablePosition , nullableRotation , nullableScale ) ;
81-
82- if ( makeActive )
83- nob . gameObject . SetActive ( true ) ;
84-
85- return nob ;
86- }
87- }
88- //Nothing left in cache.
89- else
90- {
91- break ;
92- }
93- }
94-
95- //Fall through, nothing in cache.
96- return GetFromInstantiate ( ) ;
97-
98- //Returns a network object via instantation.
99- NetworkObject GetFromInstantiate ( )
100- {
101- NetworkObject prefab = GetPrefab ( prefabId , collectionId , asServer ) ;
102- if ( prefab == null )
103- {
104- return null ;
105- }
106- else
107- {
108- NetworkObject result ;
109- Vector3 scale ;
110-
111- if ( localSpace )
112- {
113- prefab . transform . OutLocalPropertyValues ( nullablePosition , nullableRotation , nullableScale , out Vector3 pos , out Quaternion rot , out scale ) ;
114- if ( parent != null )
115- {
116- //Convert pos and rot to world values for the instantiate.
117- pos = parent . TransformPoint ( pos ) ;
118- rot = ( parent . rotation * rot ) ;
119- }
120- result = Instantiate ( prefab , pos , rot , parent ) ;
121- }
122- else
123- {
124- prefab . transform . OutWorldPropertyValues ( nullablePosition , nullableRotation , nullableScale , out Vector3 pos , out Quaternion rot , out scale ) ;
125- result = Instantiate ( prefab , pos , rot , parent ) ;
126- }
127-
128- result . transform . localScale = scale ;
129-
130- if ( makeActive )
131- result . gameObject . SetActive ( true ) ;
132- return result ;
133- }
134- }
135- }
136-
137- /// <summary>
138- /// Returns a prefab for prefab and collectionId.
139- /// </summary>
140- public override NetworkObject GetPrefab ( int prefabId , ushort collectionId , bool asServer )
141- {
142- PrefabObjects po = base . NetworkManager . GetPrefabObjects < PrefabObjects > ( collectionId , false ) ;
143- return po . GetObject ( asServer , prefabId ) ;
144- }
145-
146- /// <summary>
147- /// Stores an object into the pool.
148- /// </summary>
149- /// <param name="instantiated">Object to store.</param>
150- /// <param name="asServer">True if being called on the server side.</param>
151- /// <returns></returns>
152- public override void StoreObject ( NetworkObject instantiated , bool asServer )
153- {
154- //Pooling is not enabled.
155- if ( ! _enabled )
156- {
157- Destroy ( instantiated . gameObject ) ;
158- return ;
159- }
160-
161- //Get all children as well and reset state on them.
162- List < NetworkObject > nestedNobs = instantiated . GetNetworkObjects ( GetNetworkObjectOption . All ) ;
163-
164- foreach ( NetworkObject nob in nestedNobs )
165- nob . ResetState ( asServer ) ;
166-
167- CollectionCaches < NetworkObject > . Store ( nestedNobs ) ;
168-
169- //Set root inactive.
170- instantiated . gameObject . SetActive ( false ) ;
171-
172- Stack < NetworkObject > cache = GetCache ( instantiated . SpawnableCollectionId , instantiated . PrefabId , createIfMissing : true ) ;
173- cache . Push ( instantiated ) ;
174- }
175-
176- /// <summary>
177- /// Instantiates a number of objects and adds them to the pool.
178- /// </summary>
179- /// <param name="prefab">Prefab to cache.</param>
180- /// <param name="count">Quantity to spawn.</param>
181- /// <param name="asServer">True if storing prefabs for the server collection. This is only applicable when using DualPrefabObjects.</param>
182- #pragma warning disable CS0672 // Member overrides obsolete member
183- public override void CacheObjects ( NetworkObject prefab , int count , bool asServer ) => StorePrefabObjects ( prefab , count , asServer ) ;
184- #pragma warning restore CS0672 // Member overrides obsolete member
185-
186- /// <summary>
187- /// Instantiates a number of objects and adds them to the pool.
188- /// </summary>
189- /// <param name="prefab">Prefab to cache.</param>
190- /// <param name="count">Quantity to spawn.</param>
191- /// <param name="asServer">True if storing prefabs for the server collection. This is only applicable when using DualPrefabObjects.</param>
192- /// <returns>Prefabs instantiated and added to cache.</returns>
193- public override List < NetworkObject > StorePrefabObjects ( NetworkObject prefab , int count , bool asServer )
194- {
195- if ( ! _enabled )
196- return null ;
197- if ( count <= 0 )
198- return null ;
199- if ( prefab == null )
200- return null ;
201- if ( prefab . PrefabId == NetworkObject . UNSET_PREFABID_VALUE )
202- {
203- NetworkManagerExtensions . LogError ( $ "Pefab { prefab . name } has an invalid prefabId and cannot be cached.") ;
204- return null ;
205- }
206-
207- List < NetworkObject > added = new ( ) ;
208- Stack < NetworkObject > cache = GetCache ( prefab . SpawnableCollectionId , prefab . PrefabId , createIfMissing : true ) ;
209-
210- for ( int i = 0 ; i < count ; i ++ )
211- {
212- NetworkObject nob = Instantiate ( prefab ) ;
213- nob . gameObject . SetActive ( false ) ;
214- cache . Push ( nob ) ;
215- added . Add ( nob ) ;
216- }
217-
218- return added ;
219- }
220-
221- /// <summary>
222- /// Clears pooled objects for a specific NetworkObject.
223- /// </summary>
224- /// <param name="nob">Prefab or Instantiated NetworkObject to clear pool for.</param>
225- /// <remarks>This will clear the entire pool for the specified object.</remarks>
226- public void ClearPool ( NetworkObject nob )
227- {
228- if ( ! _enabled )
229- return ;
230- if ( nob == null )
231- return ;
232-
233- int spawnableCollectionId = nob . SpawnableCollectionId ;
234- Stack < NetworkObject > stack = GetCache ( spawnableCollectionId , nob . PrefabId , createIfMissing : false ) ;
235- if ( stack == null )
236- return ;
237-
238- DestroyStackNetworkObjectsAndClear ( stack ) ;
239- _cache [ spawnableCollectionId ] . Clear ( ) ;
240- }
241-
242- /// <summary>
243- /// Clears all pooled objects.
244- /// </summary>
245- public void ClearPool ( )
246- {
247- int count = _cache . Count ;
248- for ( int i = 0 ; i < count ; i ++ )
249- ClearPool ( i ) ;
250- }
251-
252- /// <summary>
253- /// Clears a pool destroying objects for a SpawnableCollectionId.
254- /// </summary>
255- /// <param name="spawnableCollectionId">CollectionId to clear for.</param>
256- public void ClearPool ( int spawnableCollectionId )
257- {
258- if ( spawnableCollectionId >= _cacheCount )
259- return ;
260-
261- Dictionary < int , Stack < NetworkObject > > dict = _cache [ spawnableCollectionId ] ;
262-
263- foreach ( Stack < NetworkObject > item in dict . Values )
264- DestroyStackNetworkObjectsAndClear ( item ) ;
265-
266- dict . Clear ( ) ;
267- }
268-
269- /// <summary>
270- /// Gets a cache for an id or creates one if does not exist.
271- /// </summary>
272- /// <returns></returns>
273- public Stack < NetworkObject > GetCache ( int collectionId , int prefabId , bool createIfMissing )
274- {
275- if ( collectionId >= _cacheCount )
276- {
277- //Do not create if missing.
278- if ( ! createIfMissing )
279- return null ;
280-
281- //Add more to the cache.
282- while ( _cache . Count <= collectionId )
283- {
284- Dictionary < int , Stack < NetworkObject > > dict = new ( ) ;
285- _cache . Add ( dict ) ;
286- }
287- _cacheCount = collectionId ;
288- }
289-
290- Dictionary < int , Stack < NetworkObject > > dictionary = _cache [ collectionId ] ;
291- //No cache for prefabId yet, make one.
292- if ( ! dictionary . TryGetValueIL2CPP ( prefabId , out Stack < NetworkObject > cache ) )
293- {
294- if ( createIfMissing )
295- {
296- cache = new ( ) ;
297- dictionary [ prefabId ] = cache ;
298- }
299- }
300-
301- return cache ;
302- }
303-
304- [ Obsolete ( "Use GetCache(int, int, bool)" ) ]
305- public Stack < NetworkObject > GetOrCreateCache ( int collectionId , int prefabId ) => GetCache ( collectionId , prefabId , createIfMissing : true ) ;
306-
307- /// <summary>
308- /// Destroys all NetworkObjects within a stack and clears the stack.
309- /// </summary>
310- private void DestroyStackNetworkObjectsAndClear ( Stack < NetworkObject > stack )
311- {
312- foreach ( NetworkObject networkObject in stack )
313- {
314- if ( networkObject != null )
315- Destroy ( networkObject . gameObject ) ;
316- }
317-
318- stack . Clear ( ) ;
319- }
320- }
321- }
1+ //Clearing for merge.
0 commit comments