@@ -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