From e6a73b1211426cb39649e5e8e6e17888444019ae Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Tue, 11 Oct 2022 22:56:01 +0200 Subject: [PATCH] Options value set - threading fix --- TLM/TLM/UI/Helpers/CheckboxOption.cs | 16 +++++++++++++++- TLM/TLM/UI/Helpers/DropDownOption.cs | 15 +++++++++++++-- TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs | 3 +-- TLM/TLM/UI/Helpers/SliderOption.cs | 18 +++++++++++++++--- TLM/TLM/Util/Shortcuts.cs | 3 +++ 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/TLM/TLM/UI/Helpers/CheckboxOption.cs b/TLM/TLM/UI/Helpers/CheckboxOption.cs index 1ba90f23d..fff5123c7 100644 --- a/TLM/TLM/UI/Helpers/CheckboxOption.cs +++ b/TLM/TLM/UI/Helpers/CheckboxOption.cs @@ -4,7 +4,9 @@ namespace TrafficManager.UI.Helpers { using TrafficManager.State; using CSUtil.Commons; using System.Collections.Generic; + using ColossalFramework.Threading; using JetBrains.Annotations; + using TrafficManager.Util; using UnityEngine; public class CheckboxOption : SerializableUIOptionBase { @@ -74,7 +76,19 @@ public CheckboxOption(string fieldName, Options.PersistTo scope = Options.Persis if (!value && _propagatesFalseTo != null) PropagateTo(_propagatesFalseTo, false); - if (HasUI) _ui.isChecked = value; + if (Shortcuts.IsMainThread()) { + if (HasUI) { + _ui.isChecked = value; + } + } else { + SimulationManager.instance + .m_ThreadingWrapper + .QueueMainThread(() => { + if (HasUI) { + _ui.isChecked = value; + } + }); + } } } diff --git a/TLM/TLM/UI/Helpers/DropDownOption.cs b/TLM/TLM/UI/Helpers/DropDownOption.cs index 208825987..570491264 100644 --- a/TLM/TLM/UI/Helpers/DropDownOption.cs +++ b/TLM/TLM/UI/Helpers/DropDownOption.cs @@ -6,6 +6,7 @@ namespace TrafficManager.UI.Helpers { using System; using System.Linq; using TrafficManager.API.Traffic.Enums; + using TrafficManager.Util; public class DropDownOption : SerializableUIOptionBase> where TEnum : struct, Enum, IConvertible { @@ -50,8 +51,18 @@ public DropDownOption(string fieldName, Options.PersistTo scope = Options.Persis set { if (values_.Contains(value)) { base.Value = value; - if (HasUI) { - _ui.selectedIndex = IndexOf(value); + if (Shortcuts.IsMainThread()) { + if (HasUI) { + _ui.selectedIndex = IndexOf(value); + } + } else { + SimulationManager.instance + .m_ThreadingWrapper + .QueueMainThread(() => { + if (HasUI) { + _ui.selectedIndex = IndexOf(value); + } + }); } } else { Log.Error($"unrecognised value:{value} for enum:{typeof(TEnum).Name}"); diff --git a/TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs b/TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs index accb21025..9994106bf 100644 --- a/TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs +++ b/TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs @@ -105,8 +105,7 @@ public abstract class SerializableUIOptionBase : ILegacyS /* UI: */ - // TODO FIX - temporary solution! - public bool HasUI => _ui != null && Thread.CurrentThread != SimulationManager.instance.m_simulationThread; + public bool HasUI => _ui != null; protected TUI _ui; protected string _label; diff --git a/TLM/TLM/UI/Helpers/SliderOption.cs b/TLM/TLM/UI/Helpers/SliderOption.cs index 578da6f09..930474616 100644 --- a/TLM/TLM/UI/Helpers/SliderOption.cs +++ b/TLM/TLM/UI/Helpers/SliderOption.cs @@ -6,6 +6,7 @@ namespace TrafficManager.UI.Helpers { using CSUtil.Commons; using UnityEngine; using System; + using TrafficManager.Util; public class SliderOption : SerializableUIOptionBase { @@ -70,9 +71,20 @@ public byte FloatToByte(float val) Log.Info($"SliderOption.Value: `{FieldName}` changed to {value}"); - if (HasUI) { - _ui.value = value; - UpdateTooltip(); + if (Shortcuts.IsMainThread()) { + if (HasUI) { + _ui.value = value; + UpdateTooltip(); + } + } else { + SimulationManager.instance + .m_ThreadingWrapper + .QueueMainThread(() => { + if (HasUI) { + _ui.value = value; + UpdateTooltip(); + } + }); } } } diff --git a/TLM/TLM/Util/Shortcuts.cs b/TLM/TLM/Util/Shortcuts.cs index b8e022237..d9e7a3de0 100644 --- a/TLM/TLM/Util/Shortcuts.cs +++ b/TLM/TLM/Util/Shortcuts.cs @@ -13,11 +13,14 @@ namespace TrafficManager.Util { using UnityEngine; using ColossalFramework.UI; using System.Diagnostics; + using ColossalFramework.Threading; internal static class Shortcuts { internal static bool InSimulationThread() => System.Threading.Thread.CurrentThread == SimulationManager.instance.m_simulationThread; + internal static bool IsMainThread() => Dispatcher.currentSafe == Dispatcher.mainSafe; + /// /// returns a new calling Clone() on all items. ///