From 8aa6ba71b6426940889c8a57dd524d8fa35a0754 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 3 Jul 2017 19:07:54 +0300 Subject: [PATCH] Another attempt to fix the "Destination array was not long enough" errors in AddToGUIUpdateList: The errors seem to be caused by adding messages to the debug console from another thread, which may happen if an OpenAL error occurs during sound streaming. Now the debug console queues the messages and creates the necessary UI elements in the main thread, which should(?) make it thread-safe. (TODO: figure out what's causing the OpenAL errors) --- .../BarotraumaClient/Source/DebugConsole.cs | 49 ++++++++++++++++++- .../Source/Sounds/OggStream.cs | 5 +- .../BarotraumaShared/Source/DebugConsole.cs | 39 +++------------ 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs index b453ead64..11e2858c6 100644 --- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs @@ -15,6 +15,8 @@ namespace Barotrauma { static bool isOpen; + private static Queue queuedMessages = new Queue(); + //used for keeping track of the message entered when pressing up/down static int selectedIndex; @@ -68,6 +70,11 @@ namespace Barotrauma public static void Update(GameMain game, float deltaTime) { + while (queuedMessages.Count > 0) + { + AddMessage(queuedMessages.Dequeue()); + } + if (PlayerInput.KeyHit(Keys.F3)) { isOpen = !isOpen; @@ -81,8 +88,6 @@ namespace Barotrauma GUIComponent.ForceMouseOn(null); textBox.Deselect(); } - - //keyboardDispatcher.Subscriber = (isOpen) ? textBox : null; } if (isOpen) @@ -149,6 +154,46 @@ namespace Barotrauma } } + private static void AddMessage(ColoredText msg) + { + //listbox not created yet, don't attempt to add + if (listBox == null) return; + + if (listBox.children.Count > MaxMessages) + { + listBox.children.RemoveRange(0, listBox.children.Count - MaxMessages); + } + + Messages.Add(msg); + if (Messages.Count > MaxMessages) + { + Messages.RemoveRange(0, Messages.Count - MaxMessages); + } + + try + { + var textBlock = new GUITextBlock(new Rectangle(0, 0, listBox.Rect.Width, 0), msg.Text, "", Alignment.TopLeft, Alignment.Left, null, true, GUI.SmallFont); + textBlock.CanBeFocused = false; + textBlock.TextColor = msg.Color; + + listBox.AddChild(textBlock); + listBox.BarScroll = 1.0f; + } + catch (Exception e) + { + ThrowError("Failed to add a message to the debug console.", e); + } + + selectedIndex = listBox.children.Count; + + if (activeQuestionText != null) + { + //make sure the active question stays at the bottom of the list + listBox.children.Remove(activeQuestionText); + listBox.children.Add(activeQuestionText); + } + } + private static bool ExecProjSpecific(string[] commands) { switch (commands[0].ToLowerInvariant()) diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/OggStream.cs b/Barotrauma/BarotraumaClient/Source/Sounds/OggStream.cs index c2a3cb18e..c94fd491c 100644 --- a/Barotrauma/BarotraumaClient/Source/Sounds/OggStream.cs +++ b/Barotrauma/BarotraumaClient/Source/Sounds/OggStream.cs @@ -51,10 +51,9 @@ namespace Barotrauma.Sounds if ((error = AL.GetError()) != ALError.NoError) { #if DEBUG - DebugConsole.ThrowError("OpenAL error: " + AL.GetErrorString(error)); + DebugConsole.ThrowError("OpenAL error: " + AL.GetErrorString(error) + "\n" + Environment.StackTrace); #else - - DebugConsole.NewMessage("OpenAL error: " + AL.GetErrorString(error), Microsoft.Xna.Framework.Color.Red); + DebugConsole.NewMessage("OpenAL error: " + AL.GetErrorString(error) + "\n" + Environment.StackTrace, Microsoft.Xna.Framework.Color.Red); #endif } } diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 2a005af27..105cc6482 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -659,51 +659,24 @@ namespace Barotrauma public static void NewMessage(string msg, Color color) { - if (String.IsNullOrEmpty((msg))) return; + if (string.IsNullOrEmpty((msg))) return; - Messages.Add(new ColoredText(msg, color)); #if SERVER + Messages.Add(new ColoredText(msg, color)); + //TODO: REMOVE Console.ForegroundColor = XnaToConsoleColor.Convert(color); Console.WriteLine(msg); Console.ForegroundColor = ConsoleColor.White; -#endif if (Messages.Count > MaxMessages) { Messages.RemoveRange(0, Messages.Count - MaxMessages); } - -#if CLIENT - //listbox not created yet, don't attempt to add - if (listBox == null) return; - - if (listBox.children.Count > MaxMessages) +#elif CLIENT + lock (queuedMessages) { - listBox.children.RemoveRange(0, listBox.children.Count - MaxMessages); - } - - try - { - var textBlock = new GUITextBlock(new Rectangle(0, 0, listBox.Rect.Width, 0), msg, "", Alignment.TopLeft, Alignment.Left, null, true, GUI.SmallFont); - textBlock.CanBeFocused = false; - textBlock.TextColor = color; - - listBox.AddChild(textBlock); - listBox.BarScroll = 1.0f; - } - catch - { - return; - } - - selectedIndex = listBox.children.Count; - - if (activeQuestionText != null) - { - //make sure the active question stays at the bottom of the list - listBox.children.Remove(activeQuestionText); - listBox.children.Add(activeQuestionText); + queuedMessages.Enqueue(new ColoredText(msg, color)); } #endif }