Run command execution in a separate thread to prevent render thread lockup

This commit is contained in:
Amos 2021-06-28 15:54:47 -07:00
parent 435c48695f
commit e0ca233333

View File

@ -1,5 +1,7 @@
#include <stdio.h> #include <thread>
#include <fstream> #include <fstream>
#include <stdio.h>
#include <windows.h> #include <windows.h>
#include <detours.h> #include <detours.h>
@ -13,8 +15,6 @@
#include "imgui_impl_dx11.h" #include "imgui_impl_dx11.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
#pragma warning(disable : 4996)
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* _overlay.cpp * _overlay.cpp
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
@ -80,6 +80,7 @@ public:
{ {
return (char*)memcpy(buf, (const void*)s, len); return (char*)memcpy(buf, (const void*)s, len);
} }
return NULL;
} }
static void Strtrim(char* s) static void Strtrim(char* s)
{ {
@ -93,7 +94,6 @@ public:
for (int i = 0; i < Items.Size; i++) { free(Items[i]); } for (int i = 0; i < Items.Size; i++) { free(Items[i]); }
Items.clear(); Items.clear();
} }
void AddLog(const char* fmt, ...) IM_FMTARGS(2) void AddLog(const char* fmt, ...) IM_FMTARGS(2)
{ {
char buf[1024]; char buf[1024];
@ -126,7 +126,7 @@ public:
AddLog("+--------------------------------------------------------+\n"); AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n"); AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n"); AddLog("+--------------------------------------------------------+\n");
ExecCommand("exec autoexec"); ProcessCommand("exec autoexec");
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::SmallButton("Netchannel Trace")) if (ImGui::SmallButton("Netchannel Trace"))
@ -135,7 +135,7 @@ public:
AddLog("+--------------------------------------------------------+\n"); AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n"); AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n"); AddLog("+--------------------------------------------------------+\n");
ExecCommand("exec netchan"); ProcessCommand("exec netchan");
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
ImGui::SameLine(); ImGui::SameLine();
@ -305,36 +305,43 @@ public:
if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
{ {
char* s = InputBuf; char* s = InputBuf;
if (strstr(InputBuf, "`")) { strcpy(s, ""); } const char* replace = "";
if (strstr(InputBuf, "`")) { strcpy_s(s, sizeof(replace), replace); }
Strtrim(s); Strtrim(s);
if (s[0]) { ExecCommand(s); } if (s[0]) { ProcessCommand(s); }
strcpy(s, ""); strcpy_s(s, sizeof(replace), replace);
reclaim_focus = true; reclaim_focus = true;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Submit")) if (ImGui::Button("Submit"))
{ {
char* s = InputBuf; char* s = InputBuf;
if (s[0]) { ExecCommand(s); } const char* replace = "";
strcpy(s, ""); if (s[0]) { ProcessCommand(s); }
strcpy_s(s, sizeof(replace), replace);
reclaim_focus = true; reclaim_focus = true;
} }
// Auto-focus on window apparition // Auto-focus on window apparition
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
if (reclaim_focus) { ImGui::SetKeyboardFocusHere(-1); }// Auto focus previous widget if (reclaim_focus)
{// Auto focus previous widget
ImGui::SetKeyboardFocusHere(-1);
}
ImGui::End(); ImGui::End();
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Exec // Exec
void ExecCommand(const char* command_line) void ProcessCommand(const char* command_line)
{ {
AddLog("# %s\n", command_line); std::thread t(&CGameConsole::ExecCommand, this, command_line);
CommandExecute(NULL, command_line); t.detach();
// HACK: This is to avoid a race condition.
Sleep(1);
AddLog("# %s\n", command_line);
// Insert into history. First find match and delete it so it can be pushed to the back.
// This isn't trying to be smart or optimal.
HistoryPos = -1; HistoryPos = -1;
for (int i = History.Size - 1; i >= 0; i--) for (int i = History.Size - 1; i >= 0; i--)
{ {
@ -362,9 +369,12 @@ public:
for (int i = first > 0 ? first : 0; i < History.Size; i++) { AddLog("%3d: %s\n", i, History[i]); } for (int i = first > 0 ? first : 0; i < History.Size; i++) { AddLog("%3d: %s\n", i, History[i]); }
} }
// On command input, we scroll to bottom even if AutoScroll==false
ScrollToBottom = true; ScrollToBottom = true;
} }
void ExecCommand(const char* command_line)
{
CommandExecute(NULL, command_line);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// History // History
@ -388,7 +398,10 @@ public:
while (word_start > data->Buf) while (word_start > data->Buf)
{ {
const char c = word_start[-1]; const char c = word_start[-1];
if (c == ' ' || c == '\t' || c == ',' || c == ';') { break; } if (c == ' ' || c == '\t' || c == ',' || c == ';')
{
break;
}
word_start--; word_start--;
} }
break; break;
@ -405,7 +418,10 @@ public:
{ {
if (HistoryPos != -1) if (HistoryPos != -1)
{ {
if (++HistoryPos >= History.Size) { HistoryPos = -1; } if (++HistoryPos >= History.Size)
{
HistoryPos = -1;
}
} }
} }
if (prev_history_pos != HistoryPos) if (prev_history_pos != HistoryPos)
@ -420,11 +436,9 @@ public:
} }
}; };
/////////////////////////////////////////////////////////////////////////////// //#############################################################################
//----------------------------------------------------------------------------- // INTERNALS
// Internals //#############################################################################
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
int Stricmp(const char* s1, const char* s2) int Stricmp(const char* s1, const char* s2)
{ {
@ -456,11 +470,9 @@ void Strtrim(char* s)
char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0;
} }
/////////////////////////////////////////////////////////////////////////////// //#############################################################################
//----------------------------------------------------------------------------- // ENTRYPOINT
// Entry //#############################################################################
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
void ShowGameConsole(bool* p_open) void ShowGameConsole(bool* p_open)
{ {