Skip to content

Commit d7649ba

Browse files
committed
Fix engineIFPLoad failure on resource multiple restarts
IFP was failing to load after restarting resource multiple times, because it was removed from map in CElementDeleter::DeleteIFP which caused a small delay in ms. Now, it will be removed from map when it's added to element deleter list, so engineLoadIFP won't fail because the element with the same block name does not exist in map anymore.
1 parent 79c2463 commit d7649ba

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

Client/mods/deathmatch/logic/CClientIFP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CClientIFP::CClientIFP ( class CClientManager* pManager, ElementID ID ) : CClien
1515

1616
CClientIFP::~CClientIFP ( void )
1717
{
18+
//g_pCore->GetConsole ()->Printf( "CClientIFP::~CClientIFP called! BlockName: %s", m_strBlockName.c_str ( ) );
1819
}
1920

2021
bool CClientIFP::LoadIFP ( const char* szFilePath, const SString & strBlockName )

Client/mods/deathmatch/logic/CElementDeleter.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ void CElementDeleter::Delete ( class CClientEntity* pElement )
3535
// Add it to our list
3636
if ( !pElement->IsBeingDeleted () )
3737
{
38+
// Just to be clear, not a Lua event
39+
OnClientSpecialElementDestroy ( pElement );
3840
m_List.push_back ( pElement );
3941
}
4042

@@ -68,6 +70,8 @@ void CElementDeleter::DeleteRecursive ( class CClientEntity* pElement )
6870
// Add it to our list over deleting objects
6971
if ( !pElement->IsBeingDeleted () )
7072
{
73+
// Just to be clear, not a Lua event
74+
OnClientSpecialElementDestroy ( pElement );
7175
m_List.push_back ( pElement );
7276
}
7377

@@ -94,15 +98,14 @@ void CElementDeleter::DeleteIFP ( CClientEntity * pElement )
9498
{
9599
CClientIFP & IFP = static_cast < CClientIFP& > ( *pElement );
96100
const unsigned int u32BlockNameHash = IFP.GetBlockNameHash ( );
97-
std::shared_ptr < CClientIFP > pIFP = g_pClientGame->GetIFPPointerFromMap ( u32BlockNameHash );
98-
if ( pIFP )
99-
{
100-
// Remove IFP from map, so we can indicate that it does not exist
101-
g_pClientGame->RemoveIFPPointerFromMap ( u32BlockNameHash );
102-
103-
// Remove IFP animations from replaced animations of peds/players
104-
g_pClientGame->OnClientIFPUnload ( pIFP );
105-
}
101+
for ( auto it = m_vecIFPElements.begin ( ); it != m_vecIFPElements.end ( ); ++it )
102+
{
103+
if ( (*it)->GetBlockNameHash ( ) == u32BlockNameHash )
104+
{
105+
m_vecIFPElements.erase ( it );
106+
break;
107+
}
108+
}
106109
}
107110

108111

@@ -130,6 +133,38 @@ void CElementDeleter::DoDeleteAll ( void )
130133
}
131134

132135

136+
bool CElementDeleter::OnClientSpecialElementDestroy ( CClientEntity* pElement )
137+
{
138+
if ( IS_IFP ( pElement ) )
139+
{
140+
OnClientIFPElementDestroy ( pElement );
141+
return true;
142+
}
143+
return false;
144+
}
145+
146+
147+
void CElementDeleter::OnClientIFPElementDestroy ( CClientEntity * pElement )
148+
{
149+
CClientIFP & IFP = static_cast < CClientIFP& > ( *pElement );
150+
const unsigned int u32BlockNameHash = IFP.GetBlockNameHash ( );
151+
152+
std::shared_ptr < CClientIFP > pIFP = g_pClientGame->GetIFPPointerFromMap ( u32BlockNameHash );
153+
if ( pIFP )
154+
{
155+
// Remove IFP from map, so we can indicate that it does not exist
156+
g_pClientGame->RemoveIFPPointerFromMap ( u32BlockNameHash );
157+
158+
// Remove IFP animations from replaced animations of peds/players
159+
g_pClientGame->OnClientIFPUnload ( pIFP );
160+
161+
// keep a reference to shared_ptr CClientIFP in list, so it does not get
162+
// destroyed after exiting this function
163+
m_vecIFPElements.push_back ( pIFP );
164+
}
165+
}
166+
167+
133168
bool CElementDeleter::IsBeingDeleted ( CClientEntity* pElement )
134169
{
135170
return m_List.Contains ( pElement );

Client/mods/deathmatch/logic/CElementDeleter.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,35 @@
1515
#ifndef __CELEMENTDELETER_H
1616
#define __CELEMENTDELETER_H
1717

18+
#include <memory>
1819
#include <list>
1920

2021
class CElementDeleter
2122
{
2223
public:
23-
CElementDeleter ( void );
24-
inline ~CElementDeleter ( void ) { DoDeleteAll (); };
24+
CElementDeleter ( void );
25+
inline ~CElementDeleter ( void ) { DoDeleteAll (); };
2526

26-
void Delete ( class CClientEntity* pElement );
27-
void DeleteRecursive ( class CClientEntity* pElement );
28-
bool DeleteElementSpecial ( CClientEntity* pElement );
29-
void DeleteIFP ( CClientEntity * pElement );
27+
void Delete ( class CClientEntity* pElement );
28+
void DeleteRecursive ( class CClientEntity* pElement );
29+
bool DeleteElementSpecial ( CClientEntity* pElement );
30+
void DeleteIFP ( CClientEntity * pElement );
3031

31-
void DoDeleteAll ( void );
32+
void DoDeleteAll ( void );
33+
bool OnClientSpecialElementDestroy ( CClientEntity* pElement );
34+
void OnClientIFPElementDestroy ( CClientEntity * pElement );
35+
bool IsBeingDeleted ( class CClientEntity* pElement );
3236

33-
bool IsBeingDeleted ( class CClientEntity* pElement );
37+
void Unreference ( class CClientEntity* pElement );
3438

35-
void Unreference ( class CClientEntity* pElement );
36-
37-
void CleanUpForVM ( CLuaMain* pLuaMain );
39+
void CleanUpForVM ( CLuaMain* pLuaMain );
3840

3941
private:
40-
CMappedList < class CClientEntity* > m_List;
41-
bool m_bAllowUnreference;
42+
CMappedList < class CClientEntity* > m_List;
43+
// We are using shared_ptr for CClientIFP, and we must keep a reference
44+
// somewhere, so this is it.
45+
std::vector < std::shared_ptr < class CClientIFP > > m_vecIFPElements;
46+
bool m_bAllowUnreference;
4247
};
4348

4449
#endif

0 commit comments

Comments
 (0)