From c434f8bb348950569381a95d5ad09d1420ff3950 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Wed, 14 Apr 2021 19:40:21 +0200 Subject: [PATCH] Make game console thread safe --- src/client/component/game_console.cpp | 114 +++++++++++++++----------- src/client/component/game_console.hpp | 1 - 2 files changed, 68 insertions(+), 47 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 2db857b..4915e8e 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -9,6 +9,7 @@ #include #include +#include #include "version.hpp" #define console_font game::R_RegisterFont("fonts/consolefont") @@ -29,6 +30,8 @@ namespace game_console int info_line_count{}; }; + using output_queue = std::deque; + struct ingame_console { char buffer[256]{}; @@ -42,7 +45,7 @@ namespace game_console bool output_visible{}; int display_line_offset{}; int line_count{}; - std::deque output{}; + utils::concurrency::container output{}; }; ingame_console con{}; @@ -67,15 +70,19 @@ namespace game_console void print_internal(const std::string& data) { - if (con.visible_line_count > 0 && con.display_line_offset == (con.output.size() - con.visible_line_count)) + con.output.access([&](output_queue& output) { - con.display_line_offset++; - } - con.output.push_back(data); - if (con.output.size() > 512) - { - con.output.pop_front(); - } + if (con.visible_line_count > 0 + && con.display_line_offset == (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } + output.push_back(data); + if (output.size() > 512) + { + output.pop_front(); + } + }); } void print(const std::string& data) @@ -171,7 +178,7 @@ namespace game_console const auto _y = con.globals.font_height + con.globals.y + (con.globals.font_height * (line + 1)) + 15.0f; game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset, _y, 1.0f, 1.0f, 0.0f, color, - 0); + 0); } void draw_input() @@ -276,19 +283,19 @@ namespace game_console } } - void draw_output_scrollbar(const float x, float y, const float width, const float height) + void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output) { const auto _x = (x + width) - 10.0f; draw_box(_x, y, 10.0f, height, dvars::con_outputBarColor->current.vector); auto _height = height; - if (con.output.size() > con.visible_line_count) + if (output.size() > con.visible_line_count) { - const auto percentage = static_cast(con.visible_line_count) / con.output.size(); + const auto percentage = static_cast(con.visible_line_count) / output.size(); _height *= percentage; const auto remainingSpace = height - _height; - const auto percentageAbove = static_cast(con.display_line_offset) / (con.output.size() - con. + const auto percentageAbove = static_cast(con.display_line_offset) / (output.size() - con. visible_line_count); y = y + (remainingSpace * percentageAbove); @@ -297,42 +304,46 @@ namespace game_console draw_box(_x, y, 10.0f, _height, dvars::con_outputSliderColor->current.vector); } - void draw_output_text(const float x, float y) + void draw_output_text(const float x, float y, output_queue& output) { - const auto offset = con.output.size() >= con.visible_line_count + const auto offset = output.size() >= con.visible_line_count ? 0.0f - : (con.font_height * (con.visible_line_count - con.output.size())); + : (con.font_height * (con.visible_line_count - output.size())); for (auto i = 0; i < con.visible_line_count; i++) { y = console_font->pixelHeight + y; const auto index = i + con.display_line_offset; - if (index >= con.output.size()) + if (index >= output.size()) { break; } - game::R_AddCmdDrawText(con.output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, + game::R_AddCmdDrawText(output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, 0.0f, color_white, 0); } } void draw_output_window() { - draw_box(con.screen_min[0], con.screen_min[1] + 32.0f, con.screen_max[0] - con.screen_min[0], - (con.screen_max[1] - con.screen_min[1]) - 32.0f, dvars::con_outputWindowColor->current.vector); + con.output.access([](output_queue& output) + { + draw_box(con.screen_min[0], con.screen_min[1] + 32.0f, con.screen_max[0] - con.screen_min[0], + (con.screen_max[1] - con.screen_min[1]) - 32.0f, dvars::con_outputWindowColor->current.vector); - const auto x = con.screen_min[0] + 6.0f; - const auto y = (con.screen_min[1] + 32.0f) + 6.0f; - const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; - const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; + const auto x = con.screen_min[0] + 6.0f; + const auto y = (con.screen_min[1] + 32.0f) + 6.0f; + const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; + const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; - game::R_AddCmdDrawText(game::Dvar_FindVar("version")->current.string, 0x7FFFFFFF, console_font, x, - ((height - 12.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_s1, 0); + game::R_AddCmdDrawText(game::Dvar_FindVar("version")->current.string, 0x7FFFFFFF, console_font, x, + ((height - 12.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_s1, + 0); - draw_output_scrollbar(x, y, width, height); - draw_output_text(x, y); + draw_output_scrollbar(x, y, width, height, output); + draw_output_text(x, y, output); + }); } void draw_console() @@ -392,7 +403,7 @@ namespace game_console } } - bool console_char_event(const int localClientNum, const int key) + bool console_char_event(const int local_client_num, const int key) { if (key == game::keyNum_t::K_GRAVE || key == game::keyNum_t::K_TILDE) { @@ -436,7 +447,7 @@ namespace game_console for (size_t i = 0; i < clipboard.length(); i++) { - console_char_event(localClientNum, clipboard[i]); + console_char_event(local_client_num, clipboard[i]); } return false; @@ -447,7 +458,10 @@ namespace game_console clear(); con.line_count = 0; con.display_line_offset = 0; - con.output.clear(); + con.output.access([](output_queue& output) + { + output.clear(); + }); history_index = -1; history.clear(); @@ -489,16 +503,16 @@ namespace game_console return true; } - bool console_key_event(const int localClientNum, const int key, const int down) + bool console_key_event(const int local_client_num, const int key, const int down) { if (key == game::keyNum_t::K_F10) { - if (game::mp::svs_clients[localClientNum].header.state >= 1) + if (game::mp::svs_clients[local_client_num].header.state >= 1) { return false; } - - game::Cmd_ExecuteSingleCommand(localClientNum, 0, "lui_open menu_systemlink_join\n"); + + game::Cmd_ExecuteSingleCommand(local_client_num, 0, "lui_open menu_systemlink_join\n"); } if (key == game::keyNum_t::K_GRAVE || key == game::keyNum_t::K_TILDE) @@ -508,7 +522,7 @@ namespace game_console return false; } - if (game::playerKeys[localClientNum].keys[game::keyNum_t::K_SHIFT].down) + if (game::playerKeys[local_client_num].keys[game::keyNum_t::K_SHIFT].down) { if (!(*game::keyCatchers & 1)) toggle_console(); @@ -580,19 +594,24 @@ namespace game_console //scroll through output if (key == game::keyNum_t::K_MWHEELUP || key == game::keyNum_t::K_PGUP) { - if (con.output.size() > con.visible_line_count && con.display_line_offset > 0) + con.output.access([](output_queue& output) { - con.display_line_offset--; - } + if (output.size() > con.visible_line_count && con.display_line_offset > 0) + { + con.display_line_offset--; + } + }); } else if (key == game::keyNum_t::K_MWHEELDOWN || key == game::keyNum_t::K_PGDN) { - if (con.output.size() > con.visible_line_count && con.display_line_offset < (con.output.size() - - con. - visible_line_count)) + con.output.access([](output_queue& output) { - con.display_line_offset++; - } + if (output.size() > con.visible_line_count + && con.display_line_offset < (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } + }); } if (key == game::keyNum_t::K_ENTER) @@ -718,7 +737,10 @@ namespace game_console clear(); con.line_count = 0; con.display_line_offset = 0; - con.output.clear(); + con.output.access([](output_queue& output) + { + output.clear(); + }); history_index = -1; history.clear(); }); diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index e3b059c..c8a88fd 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -10,7 +10,6 @@ namespace game_console }; void print(int type, const char* fmt, ...); - void print_internal(const char* fmt, ...); bool console_char_event(int local_client_num, int key); bool console_key_event(int local_client_num, int key, int down);