@@ -171,6 +171,9 @@ void CModelPool::Instance_Register(LPCSTR N, dxRender_Visual* V)
171171
172172void CModelPool::Destroy ()
173173{
174+ // Pool
175+ Pool.clear ();
176+
174177 // Registry
175178 while (!Registry.empty ())
176179 {
@@ -237,21 +240,37 @@ dxRender_Visual* CModelPool::Create(const char* name, IReader* data)
237240 strlwr (low_name);
238241 if (strext (low_name)) *strext (low_name) = 0 ;
239242
240- // 1 . Search for already loaded model (reference, base model)
241- dxRender_Visual* Base = Instance_Find (low_name);
242- if (0 == Base )
243+ // 0 . Search POOL
244+ POOL_IT it = Pool. find (low_name);
245+ if (it != Pool. end () )
243246 {
244- // 2. If not found
245- bAllowChildrenDuplicate = FALSE ;
246- if (data) Base = Instance_Load (low_name, data, TRUE );
247- else Base = Instance_Load (low_name, TRUE );
248- bAllowChildrenDuplicate = TRUE ;
247+ // 1. Instance found
248+ dxRender_Visual* Model = it-> second ;
249+ Model-> Spawn ( );
250+ Pool. erase (it );
251+ return Model ;
249252 }
253+ else
254+ {
255+ // 1. Search for already loaded model (reference, base model)
256+ dxRender_Visual* Base = Instance_Find (low_name);
250257
251- // 3. If found - return (cloned) reference
252- dxRender_Visual* Model = Instance_Duplicate (Base);
253- Registry.insert (mk_pair (Model, low_name));
254- return Model;
258+ if (0 == Base)
259+ {
260+ // 2. If not found
261+ bAllowChildrenDuplicate = FALSE ;
262+ if (data) Base = Instance_Load (low_name, data, TRUE );
263+ else Base = Instance_Load (low_name, TRUE );
264+ bAllowChildrenDuplicate = TRUE ;
265+ #ifdef _EDITOR
266+ if (!Base) return 0 ;
267+ #endif
268+ }
269+ // 3. If found - return (cloned) reference
270+ dxRender_Visual* Model = Instance_Duplicate (Base);
271+ Registry.insert (mk_pair (Model, low_name));
272+ return Model;
273+ }
255274}
256275
257276dxRender_Visual* CModelPool::CreateChild (LPCSTR name, IReader* data)
@@ -282,7 +301,32 @@ void CModelPool::DeleteInternal(dxRender_Visual* & V, BOOL bDiscard)
282301 VERIFY (!g_bRendering);
283302 if (!V) return ;
284303 V->Depart ();
285- Discard (V, bDiscard || bForceDiscard);
304+ if (bDiscard || bForceDiscard)
305+ {
306+ Discard (V, TRUE );
307+ }
308+ else
309+ {
310+ //
311+ REGISTRY_IT it = Registry.find (V);
312+ if (it != Registry.end ())
313+ {
314+ // Registry entry found - move it to pool and reset changed shader/texture if necessary
315+ xr_vector<IRenderVisual*>* children = V->get_children ();
316+ if (children)
317+ for (auto * child : *children)
318+ child->ResetShaderTexture ();
319+ else
320+ V->ResetShaderTexture ();
321+
322+ Pool.insert (mk_pair (it->second , V));
323+ }
324+ else
325+ {
326+ // Registry entry not-found - just special type of visual / particles / etc.
327+ xr_delete (V);
328+ }
329+ }
286330 V = NULL ;
287331}
288332
@@ -291,18 +335,20 @@ void CModelPool::Delete(dxRender_Visual* & V, BOOL bDiscard)
291335 if (NULL == V) return ;
292336 if (g_bRendering)
293337 {
294- ModelsToDelete.insert (mk_pair (V, !!bDiscard));
338+ VERIFY (!bDiscard);
339+ ModelsToDelete.push_back (V);
295340 }
296341 else
297342 {
298343 DeleteInternal (V, bDiscard);
299344 }
345+ V = NULL ;
300346}
301347
302348void CModelPool::DeleteQueue ()
303349{
304- for (xr_map<dxRender_Visual*, bool >::iterator it = ModelsToDelete. begin () ; it != ModelsToDelete.end (); it++)
305- DeleteInternal ((dxRender_Visual*)it-> first , it-> second );
350+ for (u32 it = 0 ; it < ModelsToDelete.size (); it++)
351+ DeleteInternal (ModelsToDelete[it] );
306352 ModelsToDelete.clear ();
307353}
308354
@@ -391,6 +437,17 @@ dxRender_Visual* CModelPool::CreatePG(PS::CPGDef* source)
391437 return V;
392438}
393439
440+ void CModelPool::ClearPool (BOOL b_complete)
441+ {
442+ POOL_IT _I = Pool.begin ();
443+ POOL_IT _E = Pool.end ();
444+ for (; _I != _E; _I++)
445+ {
446+ Discard (_I->second , b_complete);
447+ }
448+ Pool.clear ();
449+ }
450+
394451void CModelPool::dump ()
395452{
396453 Log (" --- model pool --- begin:" );
@@ -409,6 +466,7 @@ void CModelPool::dump()
409466 Msg (" --- models: %d, mem usage: %d Kb " , k, sz / 1024 );
410467 sz = 0 ;
411468 k = 0 ;
469+ int free_cnt = 0 ;
412470 for (REGISTRY_IT it = Registry.begin (); it != Registry.end (); it++)
413471 {
414472 CKinematics* K = PCKinematics ((dxRender_Visual*)it->first );
@@ -417,10 +475,12 @@ void CModelPool::dump()
417475 {
418476 u32 cur = K->mem_usage (true );
419477 sz += cur;
420- Msg (" #%3d: [%5d Kb] - %s" , k++, cur / 1024 , it->second .c_str ());
478+ bool b_free = (Pool.find (it->second ) != Pool.end ());
479+ if (b_free) ++free_cnt;
480+ Msg (" #%3d: [%s] [%5d Kb] - %s" , k++, (b_free) ? " free" : " used" , cur / 1024 , it->second .c_str ());
421481 }
422482 }
423- Msg (" --- instances: %d, mem usage: %d Kb " , k, sz / 1024 );
483+ Msg (" --- instances: %d, free %d, mem usage: %d Kb " , k, free_cnt , sz / 1024 );
424484 Log (" --- model pool --- end." );
425485}
426486
0 commit comments