diff --git a/src/engine/shared/ringbuffer.cpp b/src/engine/shared/ringbuffer.cpp index f9872fead..c8697942e 100644 --- a/src/engine/shared/ringbuffer.cpp +++ b/src/engine/shared/ringbuffer.cpp @@ -123,11 +123,21 @@ void *CRingBufferBase::Allocate(int Size) return (void *)(pBlock + 1); } +void CRingBufferBase::SetPopCallback(std::function 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; diff --git a/src/engine/shared/ringbuffer.h b/src/engine/shared/ringbuffer.h index 8d089260a..11af0fa32 100644 --- a/src/engine/shared/ringbuffer.h +++ b/src/engine/shared/ringbuffer.h @@ -5,6 +5,8 @@ #include +#include + class CRingBufferBase { class CItem @@ -25,6 +27,8 @@ class CRingBufferBase int m_Size; int m_Flags; + std::function 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 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 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); } diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index 0805f4c5c..a01e272bc 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -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 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)