CitiesSkylinesMods / TMPE

Cities: Skylines Traffic Manager: President Edition
https://steamcommunity.com/sharedfiles/filedetails/?id=1637663252
MIT License
574 stars 85 forks source link

Possible issue with `vehicle restrictions aggression` mod option #1468

Closed originalfoo closed 2 years ago

originalfoo commented 2 years ago

Originally posted by @krzychu124 in https://github.com/CitiesSkylinesMods/TMPE/issues/1464#issuecomment-1068439262 :

Warning 3.9198840: Skipping invalid value 1 for vehicle restrictions aggression
   at CSUtil.Commons.Log.LogToFile(System.String log, LogLevel level)
   at CSUtil.Commons.Log.Warning(System.String s)
   at TrafficManager.Manager.Impl.OptionsManager.LoadData(System.Byte[] data)
   at TrafficManager.Lifecycle.SerializableDataExtension.Load()
   at TrafficManager.Lifecycle.TMPELifecycle.Awake()
   at UnityEngine.GameObject.Internal_AddComponentWithType(System.Type )
   at UnityEngine.GameObject.AddComponent(System.Type componentType)
   at UnityEngine.GameObject..ctor(System.String name, System.Type[] components)
   at TrafficManager.Lifecycle.TMPELifecycle.StartMod()
   at TrafficManager.Lifecycle.TrafficManagerMod.OnEnabled()
   at System.Reflection.MonoMethod.InternalInvoke(System.Object , System.Object[] , System.Exception ByRef )
   at System.Reflection.MonoMethod.Invoke(System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(System.Object obj, System.Object[] parameters)
   at ColossalFramework.Plugins.PluginManager.AddPlugins(System.Collections.Generic.Dictionary`2 plugins)
   at ColossalFramework.Plugins.PluginManager.LoadPluginAtPath(System.String path, Boolean builtin, PublishedFileId id)
   at ColossalFramework.Plugins.PluginManager.OnPluginAdded(System.String path)
   at ColossalFramework.Plugins.PluginManager+<>c__DisplayClass20.<OnFileWatcherEventChanged>b__1a()
   at ColossalFramework.Threading.Dispatcher+<>c__DisplayClass4.<CreateSafeAction>b__3()
   at ColossalFramework.Threading.Task`1+<>c__DisplayClassa[[ColossalFramework.Threading.Task+VoidTask, ColossalManaged, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null]].<.ctor>b__8(ColossalFramework.Threading.Task t)
   at ColossalFramework.Threading.Task`1[[ColossalFramework.Threading.Task+VoidTask, ColossalManaged, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null]].Execute()
   at ColossalFramework.Threading.Task.InternalExecute()
   at ColossalFramework.Threading.Dispatcher.RunTask(ColossalFramework.Threading.Task task)
   at ColossalFramework.Threading.Dispatcher.ProcessSingleTask(ColossalFramework.Threading.Task task)
   at ColossalFramework.Threading.Dispatcher.InternalProcessTasks()
   at ColossalFramework.Threading.Dispatcher.ProcessTasks()
   at ColossalFramework.Threading.ThreadHelper.FpsBoosterUpdate()
   at BehaviourUpdater.Updater.Update()
originalfoo commented 2 years ago

1 is a valid value given the enum it's linked to:

    public enum VehicleRestrictionsAggression {
        Low = 0,
        Medium = 1,
        High = 2,
        Strict = 3,
    }

Code in LoadData():

                if (data.Length > 35) {
                    try {
                        PoliciesTab_OnRoadsGroup.SetVehicleRestrictionsAggression(
                            (VehicleRestrictionsAggression)data[35]); // `1` -> `Medium`
                    }
                    catch (Exception e) {
                        Log.Warning(
                            $"Skipping invalid value {data[35]} for vehicle restrictions aggression");
                    }
                }

Code for SetVehicleRestrictionsAggression():

        public static void SetVehicleRestrictionsAggression(VehicleRestrictionsAggression val) {
            _vehicleRestrictionsAggressionDropDown.selectedIndex = (int)val; // `Medium` -> `1`
        }

The dropdown itself is essentially unaltered from original code before I started refactoring mod options. All I did was move the items out of the AddDropDown() to make code easier to read:

        private static void AddVehicleRestrictionsDropDown(UIHelperBase group) {
            var items = new[]
            {
                T("VR.Dropdown.Option:Low Aggression"),
                T("VR.Dropdown.Option:Medium Aggression"),
                T("VR.Dropdown.Option:High Aggression"),
                T("VR.Dropdown.Option:Strict"),
            };

            _vehicleRestrictionsAggressionDropDown = group.AddDropdown(
                T("VR.Dropdown:Vehicle restrictions aggression") + ":",
                items,
                (int)Options.vehicleRestrictionsAggression, // this will default to `0` currently
                OnVehicleRestrictionsAggressionChanged) as UIDropDown;
        }
krzychu124 commented 2 years ago

Hot-reload issue

Warning 0.7822867: Skipping invalid value 3 for vehicle restrictions aggression, 
System.NullReferenceException: Object reference not set to an instance of an object
  at TrafficManager.State.PoliciesTab_OnRoadsGroup.SetVehicleRestrictionsAggression (VehicleRestrictionsAggression val) [0x00000] in <filename unknown>:0 
  at TrafficManager.Manager.Impl.OptionsManager.LoadData (System.Byte[] data) [0x00000] in <filename unknown>:0 
   at CSUtil.Commons.Log.LogToFile(System.String log, LogLevel level)
   at CSUtil.Commons.Log.Warning(System.String s)
   at TrafficManager.Manager.Impl.OptionsManager.LoadData(System.Byte[] data)
   at TrafficManager.Lifecycle.SerializableDataExtension.Load()
   at TrafficManager.Lifecycle.TMPELifecycle.Awake()
   at UnityEngine.GameObject.Internal_AddComponentWithType(System.Type )
   at UnityEngine.GameObject.AddComponent(System.Type componentType)
   at UnityEngine.GameObject..ctor(System.String name, System.Type[] components)
   at TrafficManager.Lifecycle.TMPELifecycle.StartMod()
   at TrafficManager.Lifecycle.TrafficManagerMod.OnEnabled()
   at System.Reflection.MonoMethod.InternalInvoke(System.Object , System.Object[] , System.Exception ByRef )
   at System.Reflection.MonoMethod.Invoke(System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(System.Object obj, System.Object[] parameters)
   at ColossalFramework.Plugins.PluginManager.AddPlugins(System.Collections.Generic.Dictionary`2 plugins)
   at ColossalFramework.Plugins.PluginManager.LoadPluginAtPath(System.String path, Boolean builtin, PublishedFileId id)
   at ColossalFramework.Plugins.PluginManager.OnPluginAdded(System.String path)
   at ColossalFramework.Plugins.PluginManager+<>c__DisplayClass20.<OnFileWatcherEventChanged>b__1a()
   at ColossalFramework.Threading.Dispatcher+<>c__DisplayClass4.<CreateSafeAction>b__3()
   at ColossalFramework.Threading.Task`1+<>c__DisplayClassa[[ColossalFramework.Threading.Task+VoidTask, ColossalManaged, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null]].<.ctor>b__8(ColossalFramework.Threading.Task t)
   at ColossalFramework.Threading.Task`1[[ColossalFramework.Threading.Task+VoidTask, ColossalManaged, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null]].Execute()
   at ColossalFramework.Threading.Task.InternalExecute()
   at ColossalFramework.Threading.Dispatcher.RunTask(ColossalFramework.Threading.Task task)
   at ColossalFramework.Threading.Dispatcher.ProcessSingleTask(ColossalFramework.Threading.Task task)
   at ColossalFramework.Threading.Dispatcher.InternalProcessTasks()
   at ColossalFramework.Threading.Dispatcher.ProcessTasks()
   at ColossalFramework.Threading.ThreadHelper.Update()
originalfoo commented 2 years ago

Is it only hot reload that causes the issue? Did it do that on hot reload prior to the recent changes?

originalfoo commented 2 years ago

System.NullReferenceException on hot reload is likely caused by UI not being recreated when the options are loaded. That issue will be resolved when I create a UI wrapper for the drop-downs.

originalfoo commented 2 years ago

@krzychu124 Do you still run in to this issue in master? Kian's updates to drop-downs (#1512 and #1510) should have resolved the issue.

krzychu124 commented 2 years ago

Hmm, I think I spotted that yesterday again but I'll test

krzychu124 commented 2 years ago

@aubergine10 I performed few test hot-reloads, multiple savegame reloads without restarting and it works. Closing.