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