Skip to content

Commit 39e4679

Browse files
committed
ChatRoom: fix threading issue & text not scrolling properly during "hide chat background"
1 parent 30adc30 commit 39e4679

File tree

1 file changed

+58
-53
lines changed

1 file changed

+58
-53
lines changed

src/overlay/chatroom.cpp

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ class ChatRoom : public OverlayWindow
2929
char inputBuffer[256] = "";
3030
std::deque<ChatMessage> messages;
3131
static constexpr size_t MAX_MESSAGES = 100;
32-
static constexpr float MESSAGE_DISPLAY_DURATION = 6.0f; // seconds
33-
static constexpr float MESSAGE_VERYRECENT_DURATION = 3.0f;
32+
static constexpr float MESSAGE_DISPLAY_DURATION = 5.0f; // seconds
33+
static constexpr float MESSAGE_VERYRECENT_DURATION = 2.f;
34+
35+
std::mutex mtx;
3436

3537
void connectWebSocket()
3638
{
@@ -50,6 +52,8 @@ class ChatRoom : public OverlayWindow
5052

5153
void addMessage(const std::string& content)
5254
{
55+
std::lock_guard<std::mutex> lock(mtx);
56+
5357
messages.push_front({ content, std::chrono::system_clock::now() });
5458

5559
if (messages.size() > MAX_MESSAGES)
@@ -62,33 +66,27 @@ class ChatRoom : public OverlayWindow
6266
connectWebSocket();
6367
}
6468

65-
static void RenderTextWithOutline(ImVec2 pos, const char* text, ImU32 textColor, ImU32 outlineColor, float outlineThickness = 1.0f)
66-
{
67-
ImDrawList* drawList = ImGui::GetWindowDrawList();
68-
69-
// Render outline by drawing text slightly offset in all directions
70-
drawList->AddText(ImVec2(pos.x - outlineThickness, pos.y), outlineColor, text);
71-
drawList->AddText(ImVec2(pos.x + outlineThickness, pos.y), outlineColor, text);
72-
drawList->AddText(ImVec2(pos.x, pos.y - outlineThickness), outlineColor, text);
73-
drawList->AddText(ImVec2(pos.x, pos.y + outlineThickness), outlineColor, text);
74-
75-
// Render the main text
76-
drawList->AddText(pos, textColor, text);
77-
}
78-
79-
static void RenderTextWithOutlineWrapped(const char* text, ImU32 textColor, ImU32 outlineColor, float wrapWidth = -1.0f, float outlineThickness = 1.0f)
69+
static void DrawTextWithOutline(const char* text, ImVec4 textColor, ImVec4 outlineColor, float outlineThickness = 1.0f)
8070
{
81-
// Get starting position
82-
ImVec2 cursorPos = ImGui::GetCursorScreenPos();
83-
84-
// Calculate wrapped text
85-
ImVec2 textSize = ImGui::CalcTextSize(text, nullptr, false, wrapWidth);
71+
ImVec2 pos = ImGui::GetCursorPos();
8672

87-
// Render the text with outline
88-
RenderTextWithOutline(cursorPos, text, textColor, outlineColor, outlineThickness);
73+
// Draw the outline by drawing the text multiple times with offsets
74+
ImGui::PushStyleColor(ImGuiCol_Text, outlineColor);
75+
for (float dx = -outlineThickness; dx <= outlineThickness; dx += outlineThickness)
76+
{
77+
for (float dy = -outlineThickness; dy <= outlineThickness; dy += outlineThickness)
78+
{
79+
ImGui::SetCursorPos(ImVec2(pos.x + dx, pos.y + dy));
80+
ImGui::TextWrapped("%s", text);
81+
}
82+
}
83+
ImGui::PopStyleColor();
8984

90-
// Manually advance the cursor position
91-
ImGui::SetCursorScreenPos(ImVec2(cursorPos.x, cursorPos.y + textSize.y));
85+
// Draw the main text
86+
ImGui::SetCursorPos(pos);
87+
ImGui::PushStyleColor(ImGuiCol_Text, textColor);
88+
ImGui::TextWrapped("%s", text);
89+
ImGui::PopStyleColor();
9290
}
9391

9492
void render(bool overlayEnabled) override
@@ -114,18 +112,21 @@ class ChatRoom : public OverlayWindow
114112
bool hasRecentMessages = false;
115113
bool hasVeryRecentMessages = false;
116114

117-
for (const auto& msg : messages)
118115
{
119-
auto duration = std::chrono::duration_cast<std::chrono::seconds>(
120-
currentTime - msg.timestamp).count();
121-
122-
if (duration < MESSAGE_VERYRECENT_DURATION)
116+
std::lock_guard<std::mutex> lock(mtx);
117+
for (const auto& msg : messages)
123118
{
124-
hasVeryRecentMessages = true;
125-
hasRecentMessages = true;
119+
auto duration = std::chrono::duration_cast<std::chrono::seconds>(
120+
currentTime - msg.timestamp).count();
121+
122+
if (duration < MESSAGE_VERYRECENT_DURATION)
123+
{
124+
hasVeryRecentMessages = true;
125+
hasRecentMessages = true;
126+
}
127+
else if (duration < MESSAGE_DISPLAY_DURATION)
128+
hasRecentMessages = true;
126129
}
127-
else if (duration < MESSAGE_DISPLAY_DURATION)
128-
hasRecentMessages = true;
129130
}
130131

131132
// If not active then only show window if there are recent messages
@@ -161,28 +162,32 @@ class ChatRoom : public OverlayWindow
161162
// Get total available height of scroll region
162163
float availableHeight = ImGui::GetContentRegionAvail().y;
163164

164-
// Calculate total height of messages
165-
float totalMessageHeight = 0;
166-
for (auto it = messages.rbegin(); it != messages.rend(); ++it)
167165
{
168-
const auto& msg = *it;
169-
float textHeight = ImGui::CalcTextSize(msg.content.c_str(), nullptr, true, ImGui::GetContentRegionAvail().x).y;
170-
totalMessageHeight += textHeight + ImGui::GetStyle().ItemSpacing.y;
171-
}
166+
std::lock_guard<std::mutex> lock(mtx);
172167

173-
// Add dummy spacing if content doesn't fill the height
174-
if (totalMessageHeight < availableHeight)
175-
ImGui::Dummy(ImVec2(0, availableHeight - totalMessageHeight));
168+
// Calculate total height of messages
169+
float totalMessageHeight = 0;
170+
for (auto it = messages.rbegin(); it != messages.rend(); ++it)
171+
{
172+
const auto& msg = *it;
173+
float textHeight = ImGui::CalcTextSize(msg.content.c_str(), nullptr, true, ImGui::GetContentRegionAvail().x).y;
174+
totalMessageHeight += textHeight + ImGui::GetStyle().ItemSpacing.y;
175+
}
176176

177-
// Draw messages
178-
for (auto it = messages.rbegin(); it != messages.rend(); ++it)
179-
{
180-
const auto& msg = *it;
177+
// Add dummy spacing if content doesn't fill the height
178+
if (totalMessageHeight < availableHeight)
179+
ImGui::Dummy(ImVec2(0, availableHeight - totalMessageHeight));
181180

182-
if (Overlay::ChatHideBackground)
183-
RenderTextWithOutlineWrapped(msg.content.c_str(), 0xFF000000, 0xFFFFFFFF);
184-
else
185-
ImGui::TextWrapped("%s", msg.content.c_str());
181+
// Draw messages
182+
for (auto it = messages.rbegin(); it != messages.rend(); ++it)
183+
{
184+
const auto& msg = *it;
185+
186+
if (Overlay::ChatHideBackground)
187+
DrawTextWithOutline(msg.content.c_str(), ImVec4(0.0f, 0.0f, 0.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 1.0f));// 0xFF000000, 0xFFFFFFFF);
188+
else
189+
ImGui::TextWrapped("%s", msg.content.c_str());
190+
}
186191
}
187192

188193
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())

0 commit comments

Comments
 (0)