OpenBarnyard
 
Loading...
Searching...
No Matches
AModelRepos.cpp
Go to the documentation of this file.
1#include "pch.h"
2#include "AModelRepos.h"
4
5//-----------------------------------------------------------------------------
6// Enables memory debugging.
7// Note: Should be the last include!
8//-----------------------------------------------------------------------------
10
12
14
15// $Barnyard: FUNCTION 00612340
17 : m_UsedModels( AMemory::GetAllocator( AMemory::POOL_Misc ) ), m_AllModels( AMemory::GetAllocator( AMemory::POOL_Misc ) )
18{
19}
20
21// $Barnyard: FUNCTION 00613040
22// $Barnyard: FUNCTION 006130f0
24{
25 TIMPLEMENT();
27 MarkAllModelsUnused();
29}
30
31// $Barnyard: FUNCTION 00612440
33{
34 while ( !m_UnusedModels.IsEmpty() )
35 {
36 auto pModel = m_UnusedModels.Head();
37
38 pModel->Remove();
39 delete pModel;
40 }
41}
42
43// $Barnyard: FUNCTION 006123c0
44AModel* AModelRepos::GetModel( const Toshi::TPString8& a_rName )
45{
46 {
47 // Look in the list of all models
48 auto pRes = m_AllModels.Find( a_rName );
49 if ( m_AllModels.IsValid( pRes ) ) return pRes->GetSecond();
50 }
51
52 {
53 // Look in the list used models
54 auto pRes = m_UsedModels.Find( a_rName );
55 if ( m_UsedModels.IsValid( pRes ) ) return pRes->GetSecond();
56 }
57
58 return TNULL;
59}
60
61// $Barnyard: FUNCTION 00612480
62AModel* AModelRepos::GetUnusedModel( const Toshi::TPString8& a_rName )
63{
65 {
66 if ( it->GetName() == a_rName )
67 {
68 return it;
69 }
70 }
71
72 return TNULL;
73}
74
75// $Barnyard: FUNCTION 00612540
76void AModelRepos::Update( TFLOAT a_fDeltaTime )
77{
79 {
80 it->GetSecond()->Update( a_fDeltaTime );
81 }
82
84 {
85 it->GetSecond()->Update( a_fDeltaTime );
86 }
87}
88
89// $Barnyard: FUNCTION 006125d0
91{
92 // Render used models
94 {
95 if ( HASANYFLAG( a_uiMask, 1 ) )
96 it->GetSecond()->Render( 1 );
97
98 if ( HASANYFLAG( a_uiMask, 2 ) )
99 it->GetSecond()->Render( 0 );
100 }
101
102 // Render other (all?) models
104 {
105 if ( HASANYFLAG( a_uiMask, 1 ) )
106 it->GetSecond()->Render( 1 );
107
108 if ( HASANYFLAG( a_uiMask, 2 ) )
109 it->GetSecond()->Render( 0 );
110 }
111}
112
113// $Barnyard: FUNCTION 00612270
114AModel* AModelRepos::AllocateAModel( const Toshi::TPString8& a_rName, Toshi::TTRB* a_pTRB )
115{
116 if ( !a_pTRB )
117 {
119 }
120
121 TVALIDPTR( a_pTRB );
122 return new AModel( a_rName, a_pTRB );
123}
124
125// $Barnyard: FUNCTION 00612fe0
126void AModelRepos::MarkAllModelsUnused()
127{
128 for ( ModelsMap::Iterator it = m_UsedModels.Begin(); it != m_UsedModels.End(); )
129 {
130 ModelsMap::Iterator next = it.Next();
131
132 MarkModelUnused( it->GetSecond() );
133 it = next;
134 }
135}
136
137// $Barnyard: FUNCTION 00612be0
138void AModelRepos::MarkModelUnused( AModel* a_pModel )
139{
140 ModelsMap::Iterator modelIt = m_UsedModels.FindByValue( a_pModel );
141 AModel* pModel = modelIt->GetSecond();
142
143 TASSERT( modelIt != m_UsedModels.End() );
144 m_UsedModels.Remove( modelIt );
145 m_UnusedModels.PushFront( pModel );
146
147 // Delete 1 unused model if there are too many of them
149 {
150 AModel* pOldestUnusedModel = m_UnusedModels.Tail();
151 pOldestUnusedModel->Remove();
152
153 delete pOldestUnusedModel;
154 }
155}
156
157// $Barnyard: FUNCTION 00612df0
159{
160 for ( ModelsMap::Iterator it = m_AllModels.Begin(); it != m_AllModels.End(); )
161 {
162 ModelsMap::Iterator next = it.Next();
163 AModel* pModel = it->GetSecond();
164
165 if ( pModel->GetNumInstances() < 1 )
166 {
167 m_AllModels.Remove( it );
168
169 m_UnusedModels.PushFront( pModel );
170 }
171
172 it = next;
173 }
174}
175
176// $Barnyard: FUNCTION 006127f0
178{
179 TVALIDPTR( a_pModel );
180 return a_pModel->CreateInstance().Get();
181}
182
183// $Barnyard: FUNCTION 00612b10
184AModelInstance* AModelRepos::InstantiateNewModel( const Toshi::TPString8& a_rName, Toshi::TTRB* a_pTRB )
185{
186 AModel* pModel = TNULL;
187 ModelsMap::Iterator pModels2Res = m_AllModels.Find( a_rName );
188
189 if ( pModels2Res != m_AllModels.End() )
190 {
191 pModel = pModels2Res->GetSecond();
192 }
193 else
194 {
195 ModelsMap::Iterator pUsedModelsRes = m_UsedModels.Find( a_rName );
196
197 if ( m_UsedModels.IsValid( pUsedModelsRes ) )
198 {
199 pModel = pUsedModelsRes->GetSecond();
200 }
201 }
202
203 if ( !pModel )
204 {
205 pModel = AllocateAModel( a_rName, a_pTRB );
206 m_UsedModels.Insert( a_rName, pModel );
207 }
208
209 TVALIDPTR( pModel );
210 return InstantiateModel( pModel );
211}
212
213// $Barnyard: FUNCTION 00612f50
215{
216 {
217 // Remove from the list of all models
218 auto it = m_AllModels.FindByValue( a_pInstance->GetModel() );
219
220 if ( m_AllModels.IsValid( it ) )
221 {
222 AModel* pModel = it->GetSecond();
223 pModel->DestroyInstance( a_pInstance );
224 }
225 }
226
227 {
228 // Remove from the list of used models
229 auto it = m_UsedModels.FindByValue( a_pInstance->GetModel() );
230
231 if ( m_UsedModels.IsValid( it ) )
232 {
233 AModel* pModel = it->GetSecond();
234 pModel->DestroyInstance( a_pInstance );
235
236 if ( pModel->GetNumInstances() < 1 )
237 {
238 MarkModelUnused( pModel );
239 }
240 }
241 }
242}
243
244// $Barnyard: FUNCTION 00612c90
245void AModelRepos::LoadModel( const Toshi::TPString8& a_rName, Toshi::TTRB* a_pTRB )
246{
247 if ( m_AllModels.Find( a_rName ) == m_AllModels.End() )
248 {
249 AModel* pModel = TNULL;
250 auto pUsedModelsRes = m_UsedModels.Find( a_rName );
251
252 if ( !m_UsedModels.IsValid( pUsedModelsRes ) )
253 {
254 pModel = GetUnusedModel( a_rName );
255
256 if ( pModel )
257 {
258 pModel->Remove();
259 }
260 else
261 {
262 pModel = AllocateAModel( a_rName, a_pTRB );
263 }
264 }
265 else
266 {
267 pModel = pUsedModelsRes->GetSecond();
268 m_UsedModels.Remove( pUsedModelsRes );
269 }
270
271 TVALIDPTR( pModel );
272 m_AllModels.Insert( a_rName, pModel );
273 }
274}
275
276// $Barnyard: FUNCTION 00612d60
277void AModelRepos::UnloadModel( const Toshi::TPString8& a_rcName, TBOOL a_bDestroy )
278{
279 auto pModelNode = m_AllModels.Find( a_rcName );
280
281 if ( m_AllModels.IsValid( pModelNode ) && pModelNode->GetSecond()->GetNumInstances() == 0 )
282 {
283 AModel* pModel = pModelNode->GetSecond();
284 m_AllModels.Remove( pModelNode );
285
286 if ( a_bDestroy )
287 {
288 if ( pModel->IsLinked() )
289 pModel->Remove();
290
291 delete pModel;
292 }
293 else
294 {
295 m_UnusedModels.PushFront( pModel );
296 }
297 }
298}
299
300// $Barnyard: FUNCTION 006124e0
301// Note: this function was replaced with T2Map::FindByValue
302
303// $Barnyard: FUNCTION 00612300
304// Note: m_UnusedModels.PushFront
305
306// $Barnyard: FUNCTION 0060fc00
307// Note: m_vecInstanceRefs.PopBack
#define TIMPLEMENT()
Definition Defines.h:136
#define TASSERT(X,...)
Definition Defines.h:138
#define HASANYFLAG(STATE, FLAG)
Definition Defines.h:5
#define TOSHI_NAMESPACE_USING
Definition Defines.h:46
#define TVALIDPTR(PTR)
Definition Defines.h:139
#define T2_FOREACH(vecName, iteratorName)
Definition T2Iterator.h:4
#define TDEFINE_CLASS(...)
Definition TObject.h:120
unsigned int TUINT
Definition Typedefs.h:8
float TFLOAT
Definition Typedefs.h:4
#define TNULL
Definition Typedefs.h:23
bool TBOOL
Definition Typedefs.h:6
@ AAssetType_AssetPack
Definition AAssetLoader.h:7
AModel * GetModel() const
Definition AModel.h:50
void DestroyInstance(AModelInstance *a_pInstance)
Definition AModel.cpp:150
AModelInstanceRef CreateInstance()
Definition AModel.cpp:134
TSIZE GetNumInstances() const
Definition AModel.cpp:155
AModel * GetUnusedModel(const Toshi::TPString8 &a_rName)
void Update(TFLOAT a_fDeltaTime)
ModelsMap m_AllModels
Definition AModelRepos.h:46
AModelInstance * InstantiateNewModel(const Toshi::TPString8 &a_rName, Toshi::TTRB *a_pTRB)
void LoadModel(const Toshi::TPString8 &a_rcName, Toshi::TTRB *a_pTRB)
AModelInstance * InstantiateModel(AModel *a_pModel)
Toshi::T2DList< AModel > m_UnusedModels
Definition AModelRepos.h:44
ModelsMap m_UsedModels
Definition AModelRepos.h:45
void UnloadUnusedModels()
void UnloadModel(const Toshi::TPString8 &a_rcName, TBOOL a_bDestroy)
void DestroyModelInstance(AModelInstance *a_pInstance)
void UnloadAllModels()
static constexpr TSIZE MAX_UNUSED_MODELS_NUM
Definition AModelRepos.h:15
void RenderModels(TUINT a_uiMask)
AModel * GetModel(const Toshi::TPString8 &a_rcName)
static Toshi::TTRB * GetAssetTRB(AAssetType a_eAssetType)