mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-18 22:18:19 +00:00
Merge pull request #8243 from Robyt3/Console-Scrolling-Fix
Fix potential client crash and console not keeping scrolling position when console backlog is full
This commit is contained in:
commit
18d8e987f3
|
@ -123,11 +123,21 @@ void *CRingBufferBase::Allocate(int Size)
|
|||
return (void *)(pBlock + 1);
|
||||
}
|
||||
|
||||
void CRingBufferBase::SetPopCallback(std::function<void(void *pCurrent)> PopCallback)
|
||||
{
|
||||
m_PopCallback = std::move(PopCallback);
|
||||
}
|
||||
|
||||
int CRingBufferBase::PopFirst()
|
||||
{
|
||||
if(m_pConsume->m_Free)
|
||||
return 0;
|
||||
|
||||
if(m_PopCallback)
|
||||
{
|
||||
m_PopCallback(m_pConsume + 1);
|
||||
}
|
||||
|
||||
// set the free flag
|
||||
m_pConsume->m_Free = 1;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <base/system.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
class CRingBufferBase
|
||||
{
|
||||
class CItem
|
||||
|
@ -25,6 +27,8 @@ class CRingBufferBase
|
|||
int m_Size;
|
||||
int m_Flags;
|
||||
|
||||
std::function<void(void *pCurrent)> m_PopCallback = nullptr;
|
||||
|
||||
CItem *NextBlock(CItem *pItem);
|
||||
CItem *PrevBlock(CItem *pItem);
|
||||
CItem *MergeBack(CItem *pItem);
|
||||
|
@ -39,6 +43,7 @@ protected:
|
|||
|
||||
void Init(void *pMemory, int Size, int Flags);
|
||||
int PopFirst();
|
||||
void SetPopCallback(const std::function<void(void *pCurrent)> PopCallback);
|
||||
|
||||
public:
|
||||
enum
|
||||
|
@ -55,6 +60,12 @@ class CTypedRingBuffer : public CRingBufferBase
|
|||
public:
|
||||
T *Allocate(int Size) { return (T *)CRingBufferBase::Allocate(Size); }
|
||||
int PopFirst() { return CRingBufferBase::PopFirst(); }
|
||||
void SetPopCallback(std::function<void(T *pCurrent)> PopCallback)
|
||||
{
|
||||
CRingBufferBase::SetPopCallback([PopCallback](void *pCurrent) {
|
||||
PopCallback((T *)pCurrent);
|
||||
});
|
||||
}
|
||||
|
||||
T *Prev(T *pCurrent) { return (T *)CRingBufferBase::Prev(pCurrent); }
|
||||
T *Next(T *pCurrent) { return (T *)CRingBufferBase::Next(pCurrent); }
|
||||
|
|
|
@ -208,6 +208,13 @@ CGameConsole::CInstance::CInstance(int Type)
|
|||
|
||||
m_IsCommand = false;
|
||||
|
||||
m_Backlog.SetPopCallback([this](CBacklogEntry *pEntry) {
|
||||
if(pEntry->m_LineCount != -1)
|
||||
{
|
||||
m_NewLineCounter -= pEntry->m_LineCount;
|
||||
}
|
||||
});
|
||||
|
||||
m_Input.SetClipboardLineCallback([this](const char *pStr) { ExecuteLine(pStr); });
|
||||
|
||||
m_CurrentMatchIndex = -1;
|
||||
|
@ -236,7 +243,7 @@ void CGameConsole::CInstance::ClearBacklog()
|
|||
void CGameConsole::CInstance::UpdateBacklogTextAttributes()
|
||||
{
|
||||
// Pending backlog entries are not handled because they don't have text attributes yet.
|
||||
for(CInstance::CBacklogEntry *pEntry = m_Backlog.First(); pEntry; pEntry = m_Backlog.Next(pEntry))
|
||||
for(CBacklogEntry *pEntry = m_Backlog.First(); pEntry; pEntry = m_Backlog.Next(pEntry))
|
||||
{
|
||||
UpdateEntryTextAttributes(pEntry);
|
||||
}
|
||||
|
@ -244,27 +251,29 @@ void CGameConsole::CInstance::UpdateBacklogTextAttributes()
|
|||
|
||||
void CGameConsole::CInstance::PumpBacklogPending()
|
||||
{
|
||||
std::vector<CInstance::CBacklogEntry *> vpEntries;
|
||||
{
|
||||
// We must ensure that no log messages are printed while owning
|
||||
// m_BacklogPendingLock or this will result in a dead lock.
|
||||
const CLockScope LockScopePending(m_BacklogPendingLock);
|
||||
for(CInstance::CBacklogEntry *pPendingEntry = m_BacklogPending.First(); pPendingEntry; pPendingEntry = m_BacklogPending.Next(pPendingEntry))
|
||||
for(CBacklogEntry *pPendingEntry = m_BacklogPending.First(); pPendingEntry; pPendingEntry = m_BacklogPending.Next(pPendingEntry))
|
||||
{
|
||||
const size_t EntrySize = sizeof(CBacklogEntry) + pPendingEntry->m_Length;
|
||||
CBacklogEntry *pEntry = m_Backlog.Allocate(EntrySize);
|
||||
mem_copy(pEntry, pPendingEntry, EntrySize);
|
||||
vpEntries.push_back(pEntry);
|
||||
}
|
||||
|
||||
m_BacklogPending.Init();
|
||||
}
|
||||
|
||||
// Update text attributes and count number of added lines
|
||||
m_pGameConsole->Ui()->MapScreen();
|
||||
for(CInstance::CBacklogEntry *pEntry : vpEntries)
|
||||
for(CBacklogEntry *pEntry = m_Backlog.First(); pEntry; pEntry = m_Backlog.Next(pEntry))
|
||||
{
|
||||
UpdateEntryTextAttributes(pEntry);
|
||||
m_NewLineCounter += pEntry->m_LineCount;
|
||||
if(pEntry->m_LineCount == -1)
|
||||
{
|
||||
UpdateEntryTextAttributes(pEntry);
|
||||
m_NewLineCounter += pEntry->m_LineCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1142,7 @@ void CGameConsole::OnRender()
|
|||
}
|
||||
|
||||
pConsole->PumpBacklogPending();
|
||||
if(pConsole->m_NewLineCounter > 0)
|
||||
if(pConsole->m_NewLineCounter != 0)
|
||||
{
|
||||
pConsole->UpdateSearch();
|
||||
|
||||
|
@ -1143,6 +1152,8 @@ void CGameConsole::OnRender()
|
|||
pConsole->m_BacklogCurLine += pConsole->m_NewLineCounter;
|
||||
pConsole->m_BacklogLastActiveLine += pConsole->m_NewLineCounter;
|
||||
}
|
||||
if(pConsole->m_NewLineCounter < 0)
|
||||
pConsole->m_NewLineCounter = 0;
|
||||
}
|
||||
|
||||
// render console log (current entry, status, wrap lines)
|
||||
|
|
Loading…
Reference in a new issue