Skip to content

Commit f3811cb

Browse files
Improve addEvent when sharing events over multiple resources (#2333)
* Only remove an event if all resources that used addEvent for that event are stopped * Resolve potential infinite loop in CEvents::RemoveAllEvents * Use std::unordered_set instead of std::set for CEvents, use the according empty() method as well * Use std::vector for CEvents instead of std::unordered_set since there won't be that many resources and memory layout is preferred over raw speed * Simplify usage of std::vector
1 parent 83185ef commit f3811cb

File tree

4 files changed

+64
-36
lines changed

4 files changed

+64
-36
lines changed

Client/mods/deathmatch/logic/CEvents.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,28 @@ bool CEvents::AddEvent(const char* szName, const char* szArguments, CLuaMain* pL
2828
assert(szName);
2929
assert(szArguments);
3030

31-
// If it already exists, return
32-
if (Get(szName))
33-
return false;
31+
// Get the event if it already exists
32+
SEvent* pEvent = Get(szName);
3433

35-
// Create and add the event
36-
SEvent* pEvent = new SEvent;
37-
pEvent->strName = szName;
38-
pEvent->strArguments = szArguments;
39-
pEvent->pLuaMain = pLuaMain;
40-
pEvent->bAllowRemoteTrigger = bAllowRemoteTrigger;
34+
if (pEvent)
35+
{
36+
// If bAllowRemoteTrigger has been altered, return
37+
if (pEvent->bAllowRemoteTrigger != bAllowRemoteTrigger)
38+
return false;
39+
40+
// Add pLuaMain to the vector, in case it's not already there
41+
if (!ListContains(pEvent->pLuaMainVector, pLuaMain))
42+
pEvent->pLuaMainVector.push_back(pLuaMain);
43+
}
44+
else
45+
{
46+
// Create and add the event
47+
pEvent = new SEvent;
48+
pEvent->strName = szName;
49+
pEvent->strArguments = szArguments;
50+
pEvent->pLuaMainVector.push_back(pLuaMain);
51+
pEvent->bAllowRemoteTrigger = bAllowRemoteTrigger;
52+
}
4153

4254
m_EventHashMap[szName] = pEvent;
4355

@@ -80,17 +92,19 @@ void CEvents::RemoveAllEvents(class CLuaMain* pMain)
8092
while (iter != m_EventHashMap.end())
8193
{
8294
SEvent* pEvent = (*iter).second;
83-
// If they match, delete it null it and set the bool
84-
if (pEvent != NULL && pEvent->pLuaMain == pMain)
95+
ListRemoveFirst(pEvent->pLuaMainVector, pMain);
96+
97+
// If no pMain is left, delete it null it and set the bool
98+
if (pEvent->pLuaMainVector.empty())
8599
{
86100
// Delete the object
87101
delete pEvent;
88102

89103
// Remove from list
90-
m_EventHashMap.erase(iter++);
104+
m_EventHashMap.erase(iter);
91105
}
92-
else
93-
++iter;
106+
107+
++iter;
94108
}
95109
}
96110

Client/mods/deathmatch/logic/CEvents.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
struct SEvent
1818
{
19-
class CLuaMain* pLuaMain;
20-
std::string strName;
21-
std::string strArguments;
22-
bool bAllowRemoteTrigger;
19+
std::vector<class CLuaMain*> pLuaMainVector;
20+
std::string strName;
21+
std::string strArguments;
22+
bool bAllowRemoteTrigger;
2323
};
2424

2525
class CEvents

Server/mods/deathmatch/logic/CEvents.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,28 @@ bool CEvents::AddEvent(const char* szName, const char* szArguments, CLuaMain* pL
2222
assert(szName);
2323
assert(szArguments);
2424

25-
// If it already exists, return
26-
if (Get(szName))
27-
return false;
25+
// Get the event if it already exists
26+
SEvent* pEvent = Get(szName);
2827

29-
// Create and add the event
30-
SEvent* pEvent = new SEvent;
31-
pEvent->strName = szName;
32-
pEvent->strArguments = szArguments;
33-
pEvent->pLuaMain = pLuaMain;
34-
pEvent->bAllowRemoteTrigger = bAllowRemoteTrigger;
28+
if (pEvent)
29+
{
30+
// If bAllowRemoteTrigger has been altered, return
31+
if (pEvent->bAllowRemoteTrigger != bAllowRemoteTrigger)
32+
return false;
33+
34+
// Add pLuaMain to the vector, in case it's not already there
35+
if (!ListContains(pEvent->pLuaMainVector, pLuaMain))
36+
pEvent->pLuaMainVector.push_back(pLuaMain);
37+
}
38+
else
39+
{
40+
// Create and add the event
41+
pEvent = new SEvent;
42+
pEvent->strName = szName;
43+
pEvent->strArguments = szArguments;
44+
pEvent->pLuaMainVector.push_back(pLuaMain);
45+
pEvent->bAllowRemoteTrigger = bAllowRemoteTrigger;
46+
}
3547

3648
m_EventHashMap[szName] = pEvent;
3749

@@ -68,17 +80,19 @@ void CEvents::RemoveAllEvents(class CLuaMain* pMain)
6880
while (iter != m_EventHashMap.end())
6981
{
7082
SEvent* pEvent = (*iter).second;
71-
// If they match, delete it null it and set the bool
72-
if (pEvent->pLuaMain == pMain)
83+
ListRemoveFirst(pEvent->pLuaMainVector, pMain);
84+
85+
// If no pMain is left, delete it null it and set the bool
86+
if (pEvent->pLuaMainVector.empty())
7387
{
7488
// Delete the object
7589
delete pEvent;
7690

7791
// Remove from list
78-
m_EventHashMap.erase(iter++);
92+
m_EventHashMap.erase(iter);
7993
}
80-
else
81-
++iter;
94+
95+
++iter;
8296
}
8397
}
8498

Server/mods/deathmatch/logic/CEvents.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
struct SEvent
1919
{
20-
class CLuaMain* pLuaMain;
21-
std::string strName;
22-
std::string strArguments;
23-
bool bAllowRemoteTrigger;
20+
std::vector<class CLuaMain*> pLuaMainVector;
21+
std::string strName;
22+
std::string strArguments;
23+
bool bAllowRemoteTrigger;
2424
};
2525

2626
class CEvents

0 commit comments

Comments
 (0)