From c4a58b1c95ad94997ccd8f98ae6d625e705a5274 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Wed, 18 Feb 2015 05:35:58 -0800 Subject: [PATCH] Make sure processing and fwd calls happen on main thread. --- extensions/tf2/conditions.cpp | 49 ++++++++++++++++++++++++++--------- extensions/tf2/conditions.h | 3 +++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/extensions/tf2/conditions.cpp b/extensions/tf2/conditions.cpp index d298df4e..8076fdeb 100644 --- a/extensions/tf2/conditions.cpp +++ b/extensions/tf2/conditions.cpp @@ -38,34 +38,41 @@ IForward *g_addCondForward = NULL; IForward *g_removeCondForward = NULL; -template -static void OnPlayerCondChange(const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID) +struct CondChangeData_t { - g_CondMgr.OnConVarChange(CondVar, pProp, pStructBase, pData, pOut, iElement, objectID); + CBaseEntity *pPlayer; + PlayerConditionsMgr::CondVar var; + int newConds; +}; + +void HandleCondChange(void *pData) +{ + auto *pCondData = reinterpret_cast(pData); + g_CondMgr.ProcessCondChange(pCondData); } -void PlayerConditionsMgr::OnConVarChange(CondVar var, const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID) +void PlayerConditionsMgr::ProcessCondChange(CondChangeData_t *pCondData) { - CBaseEntity *pPlayer = (CBaseEntity *)((intp) pStructBase - GetPropOffs(m_Shared)); - int client = gamehelpers->EntityToBCompatRef(pPlayer); + int client = gamehelpers->EntityToBCompatRef(pCondData->pPlayer); int newConds = 0; int prevConds = 0; + CondVar var = pCondData->var; if (var == m_nPlayerCond) { prevConds = m_OldConds[client][_condition_bits] | m_OldConds[client][var]; - newConds = m_OldConds[client][_condition_bits] | *(int *) (pData); + newConds = m_OldConds[client][_condition_bits] | pCondData->newConds; } else if (var == _condition_bits) { prevConds = m_OldConds[client][m_nPlayerCond] | m_OldConds[client][var]; - newConds = m_OldConds[client][m_nPlayerCond] | *(int *)(pData); + newConds = m_OldConds[client][m_nPlayerCond] | pCondData->newConds; } else { prevConds = m_OldConds[client][var]; - newConds = *(int *)pData; + newConds = pCondData->newConds; } if (prevConds != newConds) @@ -81,17 +88,35 @@ void PlayerConditionsMgr::OnConVarChange(CondVar var, const SendProp *pProp, con { g_addCondForward->PushCell(client); g_addCondForward->PushCell(i); - g_addCondForward->Execute(NULL, NULL); + g_addCondForward->Execute(NULL); } else if (removedConds & (1 << i)) { g_removeCondForward->PushCell(client); g_removeCondForward->PushCell(i); - g_removeCondForward->Execute(NULL, NULL); + g_removeCondForward->Execute(NULL); } } } + delete pCondData; +} + +template +static void OnPlayerCondChange(const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + g_CondMgr.OnConVarChange(CondVar, pProp, pStructBase, pData, pOut, iElement, objectID); +} + +void PlayerConditionsMgr::OnConVarChange(CondVar var, const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + auto pCondData = new CondChangeData_t; + pCondData->pPlayer = (CBaseEntity *)((intp)pStructBase - GetPropOffs(m_Shared)); + pCondData->var = var; + pCondData->newConds = *(int *)pData; + + g_pSM->AddFrameAction(&HandleCondChange, pCondData); + if (m_BackupProxyFns[var] != nullptr) m_BackupProxyFns[var](pProp, pStructBase, pData, pOut, iElement, objectID); } @@ -162,4 +187,4 @@ void PlayerConditionsMgr::OnClientPutInServer(int client) memset(&m_OldConds[client], 0, sizeof(m_OldConds[0])); } -PlayerConditionsMgr g_CondMgr; \ No newline at end of file +PlayerConditionsMgr g_CondMgr; diff --git a/extensions/tf2/conditions.h b/extensions/tf2/conditions.h index 76193c13..f22e9982 100644 --- a/extensions/tf2/conditions.h +++ b/extensions/tf2/conditions.h @@ -34,6 +34,8 @@ #include "extension.h" +struct CondChangeData_t; + class PlayerConditionsMgr : public IClientListener { public: @@ -56,6 +58,7 @@ public: }; void OnConVarChange(CondVar var, const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID); + void ProcessCondChange(CondChangeData_t *pCondData); private: inline unsigned int GetPropOffs(CondVar var) {