Skip to content

Commit 1aad7ca

Browse files
committed
Implement event context management in CEvents and CElement classes
1 parent 0f49768 commit 1aad7ca

File tree

4 files changed

+90
-16
lines changed

4 files changed

+90
-16
lines changed

Server/mods/deathmatch/logic/CElement.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,10 +438,11 @@ bool CElement::CallEvent(const char* szName, const CLuaArguments& Arguments, CPl
438438
if (!g_pGame->GetDebugHookManager()->OnPreEvent(szName, Arguments, this, pCaller))
439439
return false;
440440

441-
CEvents* pEvents = g_pGame->GetEvents();
441+
CEvents* pEvents = g_pGame->GetEvents();
442+
CEventContext eventContext;
442443

443444
// Make sure our event-manager knows we're about to call an event
444-
pEvents->PreEventPulse();
445+
pEvents->PreEventPulse(&eventContext);
445446

446447
// Call the event on our parents/us first
447448
CallParentEvent(szName, Arguments, this, pCaller);
@@ -450,15 +451,13 @@ bool CElement::CallEvent(const char* szName, const CLuaArguments& Arguments, CPl
450451
CallEventNoParent(szName, Arguments, this, pCaller);
451452

452453
// Tell the event manager that we're done calling the event
453-
pEvents->PostEventPulse();
454+
pEvents->PostEventPulse(&eventContext);
454455

455456
g_pGame->GetDebugHookManager()->OnPostEvent(szName, Arguments, this, pCaller);
456457

457458
// Return whether our event was cancelled or not
458-
return (!pEvents->WasEventCancelled());
459-
}
460-
461-
bool CElement::DeleteEvent(CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction)
459+
return !eventContext.IsCancelled();
460+
}bool CElement::DeleteEvent(CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction)
462461
{
463462
return m_pEventManager->Delete(pLuaMain, szName, iLuaFunction);
464463
}

Server/mods/deathmatch/logic/CEvents.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111

1212
#include "StdInc.h"
1313
#include "CEvents.h"
14+
#include "CLogger.h"
15+
#include "CGame.h"
16+
#include "CScriptDebugging.h"
1417

1518
CEvents::CEvents()
1619
{
1720
m_bWasEventCancelled = false;
1821
m_bEventCancelled = false;
22+
m_pCurrentContext = nullptr;
1923
}
2024

2125
bool CEvents::AddEvent(const char* szName, const char* szArguments, CLuaMain* pLuaMain, bool bAllowRemoteTrigger)
@@ -123,38 +127,67 @@ void CEvents::RemoveAllEvents()
123127
m_EventHashMap.clear();
124128
}
125129

126-
void CEvents::PreEventPulse()
130+
void CEvents::PreEventPulse(CEventContext* pContext)
127131
{
132+
assert(pContext);
133+
128134
m_CancelledList.push_back(m_bEventCancelled);
135+
136+
m_pCurrentContext = pContext;
137+
pContext->Reset();
138+
129139
m_bEventCancelled = false;
130140
m_bWasEventCancelled = false;
131141
m_strLastError = "";
132142
}
133143

134-
void CEvents::PostEventPulse()
144+
void CEvents::PostEventPulse(CEventContext* pContext)
135145
{
136-
m_bWasEventCancelled = m_bEventCancelled;
146+
assert(pContext);
147+
assert(m_pCurrentContext == pContext);
148+
149+
m_bWasEventCancelled = pContext->IsCancelled();
137150
m_bEventCancelled = m_CancelledList.back() ? true : false;
138151
m_CancelledList.pop_back();
152+
153+
m_pCurrentContext = nullptr;
139154
}
140155

141156
void CEvents::CancelEvent(bool bCancelled)
142157
{
143-
m_bEventCancelled = bCancelled;
158+
CancelEvent(bCancelled, nullptr);
144159
}
145160

146161
void CEvents::CancelEvent(bool bCancelled, const char* szReason)
147162
{
163+
// ALWAYS set the old global variable for backward compatibility
148164
m_bEventCancelled = bCancelled;
149-
m_strLastError = SStringX(szReason);
165+
166+
// Also update context if it exists
167+
if (m_pCurrentContext)
168+
{
169+
if (bCancelled)
170+
m_pCurrentContext->Cancel(szReason);
171+
else
172+
m_pCurrentContext->Reset();
173+
}
174+
175+
if (szReason)
176+
m_strLastError = szReason;
150177
}
151178

152179
bool CEvents::WasEventCancelled()
153180
{
154-
return m_bWasEventCancelled;
181+
if (m_pCurrentContext)
182+
return m_pCurrentContext->IsCancelled();
183+
184+
return m_bEventCancelled || m_bWasEventCancelled;
155185
}
156186

157187
const char* CEvents::GetLastError()
158188
{
189+
if (m_pCurrentContext)
190+
return m_pCurrentContext->GetCancelReason().c_str();
191+
159192
return m_strLastError;
160193
}

Server/mods/deathmatch/logic/CEvents.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <string>
1515
#include <list>
1616
#include <vector>
17+
#include "CEventContext.h"
1718

1819
struct SEvent
1920
{
@@ -40,8 +41,8 @@ class CEvents
4041
CFastHashMap<SString, SEvent*>::const_iterator IterBegin() { return m_EventHashMap.begin(); };
4142
CFastHashMap<SString, SEvent*>::const_iterator IterEnd() { return m_EventHashMap.end(); };
4243

43-
void PreEventPulse();
44-
void PostEventPulse();
44+
void PreEventPulse(CEventContext* pContext);
45+
void PostEventPulse(CEventContext* pContext);
4546

4647
void CancelEvent(bool bCancelled = true);
4748
void CancelEvent(bool bCancelled, const char* szReason);
@@ -56,6 +57,7 @@ class CEvents
5657
std::vector<int> m_CancelledList;
5758
bool m_bEventCancelled;
5859
bool m_bWasEventCancelled;
60+
SString m_strLastError;
5961

60-
SString m_strLastError;
62+
CEventContext* m_pCurrentContext;
6163
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: Shared/mods/deathmatch/logic/CEventContext.h
6+
* PURPOSE: Per-event context for event dispatch and cancellation
7+
*
8+
* Multi Theft Auto is available from https://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#pragma once
13+
14+
#include <string>
15+
16+
class CEventContext
17+
{
18+
public:
19+
CEventContext() noexcept : m_isCancelled(false) {}
20+
21+
void Cancel(const char* reason = nullptr) noexcept
22+
{
23+
m_isCancelled = true;
24+
if (reason)
25+
m_cancelReason = reason;
26+
}
27+
28+
bool IsCancelled() const noexcept { return m_isCancelled; }
29+
const std::string& GetCancelReason() const noexcept { return m_cancelReason; }
30+
31+
void Reset() noexcept
32+
{
33+
m_isCancelled = false;
34+
m_cancelReason.clear();
35+
}
36+
37+
private:
38+
bool m_isCancelled;
39+
std::string m_cancelReason;
40+
};

0 commit comments

Comments
 (0)