5171: Extract CConsole::TraverseChain, fix toggle with multiple chains r=def- a=Robyt3

Extract `CConsole::TraverseChain` (https://github.com/teeworlds/teeworlds/pull/2933).

Fix `toggle`/`+toggle` commands with commands which are chained multiple times.

## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2022-05-20 20:25:09 +00:00 committed by GitHub
commit 79f377b133
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 35 deletions

View file

@ -352,12 +352,7 @@ void CConsole::InitChecksum(CChecksumData *pData) const
{
FCommandCallback pfnCallback = pCommand->m_pfnCallback;
void *pUserData = pCommand->m_pUserData;
while(pfnCallback == Con_Chain)
{
CChain *pChainInfo = static_cast<CChain *>(pUserData);
pfnCallback = pChainInfo->m_pfnCallback;
pUserData = pChainInfo->m_pCallbackUserData;
}
TraverseChain(&pfnCallback, &pUserData);
int CallbackBits = (uintptr_t)pfnCallback & 0xfff;
int *pTarget = &pData->m_aCommandsChecksum[pData->m_NumCommands];
*pTarget = ((uint8_t)pCommand->m_pName[0]) | ((uint8_t)pCommand->m_pName[1] << 8) | (CallbackBits << 16);
@ -859,6 +854,16 @@ static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData)
}
}
void CConsole::TraverseChain(FCommandCallback *ppfnCallback, void **ppUserData)
{
while(*ppfnCallback == Con_Chain)
{
CChain *pChainInfo = static_cast<CChain *>(*ppUserData);
*ppfnCallback = pChainInfo->m_pfnCallback;
*ppUserData = pChainInfo->m_pCallbackUserData;
}
}
void CConsole::ConToggle(IConsole::IResult *pResult, void *pUser)
{
CConsole *pConsole = static_cast<CConsole *>(pUser);
@ -868,15 +873,7 @@ void CConsole::ConToggle(IConsole::IResult *pResult, void *pUser)
{
FCommandCallback pfnCallback = pCommand->m_pfnCallback;
void *pUserData = pCommand->m_pUserData;
// check for chain
if(pCommand->m_pfnCallback == Con_Chain)
{
CChain *pChainInfo = static_cast<CChain *>(pCommand->m_pUserData);
pfnCallback = pChainInfo->m_pfnCallback;
pUserData = pChainInfo->m_pCallbackUserData;
}
TraverseChain(&pfnCallback, &pUserData);
if(pfnCallback == IntVariableCommand)
{
CIntVariableData *pData = static_cast<CIntVariableData *>(pUserData);
@ -927,14 +924,8 @@ void CConsole::ConToggleStroke(IConsole::IResult *pResult, void *pUser)
if(pCommand)
{
FCommandCallback pfnCallback = pCommand->m_pfnCallback;
// check for chain
if(pCommand->m_pfnCallback == Con_Chain)
{
CChain *pChainInfo = static_cast<CChain *>(pCommand->m_pUserData);
pfnCallback = pChainInfo->m_pfnCallback;
}
void *pUserData = pCommand->m_pUserData;
TraverseChain(&pfnCallback, &pUserData);
if(pfnCallback == IntVariableCommand)
{
int Val = pResult->GetInteger(0) == 0 ? pResult->GetInteger(3) : pResult->GetInteger(2);
@ -1273,12 +1264,7 @@ void CConsole::ResetServerGameSettings()
CCommand *pCommand = FindCommand(#ScriptName, CFGFLAG_SERVER); \
void *pUserData = pCommand->m_pUserData; \
FCommandCallback pfnCallback = pCommand->m_pfnCallback; \
while(pfnCallback == Con_Chain) \
{ \
CChain *pChainInfo = (CChain *)pUserData; \
pUserData = pChainInfo->m_pCallbackUserData; \
pfnCallback = pChainInfo->m_pfnCallback; \
} \
TraverseChain(&pfnCallback, &pUserData); \
CIntVariableData *pData = (CIntVariableData *)pUserData; \
*pData->m_pVariable = pData->m_OldValue; \
} \
@ -1293,12 +1279,7 @@ void CConsole::ResetServerGameSettings()
CCommand *pCommand = FindCommand(#ScriptName, CFGFLAG_SERVER); \
void *pUserData = pCommand->m_pUserData; \
FCommandCallback pfnCallback = pCommand->m_pfnCallback; \
while(pfnCallback == Con_Chain) \
{ \
CChain *pChainInfo = (CChain *)pUserData; \
pUserData = pChainInfo->m_pCallbackUserData; \
pfnCallback = pChainInfo->m_pfnCallback; \
} \
TraverseChain(&pfnCallback, &pUserData); \
CStrVariableData *pData = (CStrVariableData *)pUserData; \
str_copy(pData->m_pOldValue, pData->m_pStr, pData->m_MaxSize); \
} \

View file

@ -53,6 +53,8 @@ class CConsole : public IConsole
CCommand *m_pRecycleList;
CHeap m_TempCommands;
static void TraverseChain(FCommandCallback *ppfnCallback, void **ppUserData);
static void Con_Chain(IResult *pResult, void *pUserData);
static void Con_Echo(IResult *pResult, void *pUserData);
static void Con_Exec(IResult *pResult, void *pUserData);