net-lisias-ksp / KSP-Recall

Recall for KSP blunders, screw ups and borks.
GNU General Public License v2.0
25 stars 2 forks source link

Unhappy interaction with Deep Freeze? #40

Closed Lisias closed 2 years ago

Lisias commented 2 years ago

Fellow Kerbonaut ttr reported some problems on his rig on TweakScale's thread.

Apparently we have a toe-stomping-fest with DeepFreeze:

[LOG 15:37:04.951] [KSP-Recall-AttachedOnEditor] TRACE: OnAwake <NO VESSEL>-CRY-0300Freezer(Clone):FFF6DA6C
[LOG 15:37:04.952] DeepFreezer OnDestroy
[EXC 15:37:04.954] NullReferenceException: Object reference not set to an instance of an object
        DF.DeepFreezer.OnDestroy () (at <72233efaa3ee4936a15201f98fac7b68>:0)
        UnityEngine.DebugLogHandler:LogException(Exception, Object)
        ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
        UnityEngine.Object:DestroyImmediate(Object)
        PartLoader:StripComponent(GameObject)
        PartLoader:CreatePartIcon(GameObject, Single&)
        PartLoader:ParsePart(UrlConfig, ConfigNode)
        <CompileParts>d__56:MoveNext()
        UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[LOG 15:37:04.964] [KSP-Recall-Refunding] TRACE: OnDestroy CRY-0300Freezer(Clone):0

Further investigate this.

2022.04.09 - tweakscale - KSP.log.zip

Lisias commented 2 years ago

I had forgot about this one. Tackling it on 0.2.2.4, since I had to postpone the release for further testing Procedural Parts, as agreed on https://github.com/KSP-CKAN/NetKAN/pull/9076 .

Lisias commented 2 years ago

~This problem is COMPLETELY unrelated to KSP-Recall or TweakScale. On a KSP 1.12.3 without any of them, this exception also happened:~

[LOG 20:05:21.374] PartLoader: Compiling Part 'REPOSoftTech/DeepFreeze/Parts/CRY0300Freezer/CRY-0300Freezer'
[LOG 20:05:21.401] DeepFreezer OnDestroy
[EXC 20:05:21.409] NullReferenceException: Object reference not set to an instance of an object
        DF.DeepFreezer.OnDestroy () (at <72233efaa3ee4936a15201f98fac7b68>:0)
        UnityEngine.DebugLogHandler:LogException(Exception, Object)
        KSPe.Util.Log.UnityLogDecorator:UnityEngine.ILogHandler.LogException(Exception, Object)
        ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
        UnityEngine.Object:DestroyImmediate(Object)
        PartLoader:StripComponent(GameObject)
        PartLoader:CreatePartIcon(GameObject, Single&)
        PartLoader:ParsePart(UrlConfig, ConfigNode)
        <CompileParts>d__56:MoveNext()
        UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

Checking on the Deep Freeze [source code](https://github.com/JPLRepo/DeepFreeze/blob/9f509f75f1da3f79684b309da69c340c46bfa003/Source/DeepFreeze.cs#L214

):

        protected void OnDestroy()
        {
            Utilities.Log("OnDestroy");
            Instance = null;
            APIReady = false;
            foreach (Component child in children)
            {
                Utilities.Log("DeepFreeze Child Destroy for " + child.name);
                Destroy(child);
            }
            children.Clear();
            DeepFreezeEventRem();
            GameEvents.onGameSceneLoadRequested.Remove(OnGameSceneLoadRequested);
            GameEvents.OnGameSettingsApplied.Remove(ApplySettings);
        }

~I came to the conclusion that something changed on KSP 1.12 (as this code war working fine at least on KSP 1.9.1, in which I also teste it) that children is now null on while loading KSP (the point in which this exception happened). I think that checking for null will solve this issue.

In a way or another, it's a KSP 1.12.x induced problem on Deep Freeze, and it need to be tackled down by code on DF itself.~

EDIT: I WAS WRONG!

Lisias commented 2 years ago

Setting it as unrelated by obvious reasons, and closing this.

Lisias commented 2 years ago

KSP is not at fault here. This is what was really happening.

The DeepFreezePart.OnDestroy (the PartModule) was the code borking, not the DeepFreeze.OnDestroy (the Scenario Module).

That log message completely misguided me. The real problem is on this code:

https://github.com/JPLRepo/DeepFreeze/blob/9f509f75f1da3f79684b309da69c340c46bfa003/Source/DeepFreezerPart.cs#L1813

        private void OnDestroy()
        {
            //Remove GameEvent callbacks.
            Debug.Log("DeepFreezer OnDestroy");

                GameEvents.onCrewTransferPartListCreated.Remove(onCrewTransferPartListCreated);
                GameEvents.onCrewTransferred.Remove(onCrewTransferred);
                GameEvents.onVesselChange.Remove(OnVesselChange);
                GameEvents.onCrewBoardVessel.Remove(OnCrewBoardVessel);
                GameEvents.onCrewOnEva.Remove(onCrewOnEva);
                GameEvents.onVesselDestroy.Remove(onVesselDestroy);
                GameEvents.OnCameraChange.Remove(OnCameraChange);
                GameEvents.onVesselGoOffRails.Remove(onVesselGoOffRails);
                GameEvents.onVesselCrewWasModified.Remove(OnVesselCrewModified);
                DFGameEvents.onKerbalFrozen.Remove(OnKerbalFreezeThaw);     // <— HERE!!!
                DFGameEvents.onKerbalThaw.Remove(OnKerbalFreezeThaw);
                GameEvents.onVesselSwitching.Remove(OnVesselSwitching);
                if (onATPPodSettingChanged != null)
                {
                    onATPPodSettingChanged.Remove(OnATPPodSettingChanged);
                }

            Debug.Log("DeepFreezer END OnDestroy");
        }

The DGGameEvents structure os initialised only on the class Textures (whatahell??) on the Start method, here:

https://github.com/JPLRepo/DeepFreeze/blob/9f509f75f1da3f79684b309da69c340c46bfa003/Source/Textures.cs#L33

Problem. Besides Textures being completely unrelated to the DFGameEvents, the Texture MonoBehaviour is started only on the Main Menu : [KSPAddon(KSPAddon.Startup.MainMenu, false)]. So it's not a surprise that the DeepFreezePart's OnDestroy is borking, as the DFGameEvents are all still NULL at that point!

The easiest way out of this huge mess is to initialise DFGameEvents on the class loading, guaranteeing that the data structures will be immediately available for using.

The big question is not why DF started to throw exceptions now, but why it wasn't doing it before!

Lisias commented 2 years ago

A pull request was issued to the maintainer fixing the issue.

https://github.com/JPLRepo/DeepFreeze/pull/110