Unhappy interaction with Deep Freeze?
Lisias opened this issue · 5 comments
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.
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!
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 KSP-CKAN/NetKAN#9076 .
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:
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:
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!
A pull request was issued to the maintainer fixing the issue.