From e532592f86d77d779a38b9096bbc6320a62a03e6 Mon Sep 17 00:00:00 2001 From: Lisias Date: Sun, 1 Mar 2020 22:58:46 -0300 Subject: [PATCH] Giving the finger to Unity's serialization and doing it by brute force. Don't try to read my mind right now, XXX rated to say the least. Implements https://github.com/net-lisias-ksp/KSP-Recall/issues/2 --- Source/Resourceful/PartModule.cs | 79 ++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/Source/Resourceful/PartModule.cs b/Source/Resourceful/PartModule.cs index d6ea70c..3111958 100644 --- a/Source/Resourceful/PartModule.cs +++ b/Source/Resourceful/PartModule.cs @@ -39,7 +39,6 @@ public class Resourceful : PartModule #endregion - [Serializable] private struct Resource_t { [SerializeField] private PartResource node; @@ -59,31 +58,60 @@ internal static Resource_t From(PartResource pr) } } - [Serializable] - private class Resource_List : ScriptableObject + private class Resource_List { - private List list = null; - public List List => this.list ?? (this.list = new List()); + private readonly Dictionary> map = new Dictionary>(); + + public void Clear(Part part) + { + this.map[part.GetInstanceID()].Clear(); + } + + public void Destroy(Part part) + { + this.map.Remove(part.GetInstanceID()); + } + + public List List(Part part) + { + if (!this.map.ContainsKey(part.GetInstanceID())) this.map[part.GetInstanceID()] = new List(); + return this.map[part.GetInstanceID()]; + } + + public bool HasSomething(Part part) => 0 != this.List(part).Count; + + internal void Copy(Part from, Part to) + { + List l = this.List(to); + l.Clear(); + l.AddRange(this.List(from)); + } } - [SerializeField] - private Resource_List resource; + private static readonly Resource_List RESOURCE_POOL = new Resource_List(); - #region KSP Events + #region KSP Life Cycle public override void OnAwake() { Log.dbg("OnAwake {0}:{1:X}", this.name, this.part.GetInstanceID()); base.OnAwake(); - if (null == this.resource) this.resource = new Resource_List(); + if (RESOURCE_POOL.HasSomething(this.part)) this.RestoreResourceList(); } public override void OnStart(StartState state) { Log.dbg("OnStart {0}:{1:X} {2} {3}", this.name, this.part.GetInstanceID(), state, this.active); base.OnStart(state); - if (0 != this.resource.List.Count) this.RestoreResourceList(); + } + + public override void OnCopy(PartModule fromModule) + { + Log.dbg("OnCopy {0}:{1:X} from {2:X}", this.name, this.part.GetInstanceID(), fromModule.part.GetInstanceID()); + base.OnCopy(fromModule); + RESOURCE_POOL.Copy(fromModule.part, this.part); + if (RESOURCE_POOL.HasSomething(this.part)) this.RestoreResourceList(); } public override void OnLoad(ConfigNode node) @@ -92,6 +120,22 @@ public override void OnLoad(ConfigNode node) base.OnLoad(node); } + public override void OnSave(ConfigNode node) + { + Log.dbg("OnLoad {0}:{1:X} {2}", this.name, this.part.GetInstanceID(), null != node); + base.OnSave(node); + } + + #endregion + + #region Unity Life Cycle + + private void OnDestroy() + { + Log.dbg("OnDestroy {0}:{1:X}", this.name, this.part.GetInstanceID()); + RESOURCE_POOL.Destroy(this.part); + } + #endregion #region Part Events Handlers @@ -109,18 +153,23 @@ void OnPartResourceChanged(BaseEventDetails data) private void UpdateResourceList() { - this.resource.List.Clear(); + RESOURCE_POOL.List(this.part).Clear(); foreach (PartResource pr in this.part.Resources) - this.resource.List.Add(Resource_t.From(pr)); - Log.dbg("Updated {0} resources for {1}", this.resource.List.Count, this.name); + RESOURCE_POOL.List(this.part).Add(Resource_t.From(pr)); + Log.dbg("Updated {0} resources for {1}:{2:X}", RESOURCE_POOL.List(this.part).Count, this.name, this.part.GetInstanceID()); } private void RestoreResourceList() { - Log.dbg("Restoring {0} resources from {1}", this.resource.List.Count, this.name); + if (!this.active) + { + Log.dbg("Ignoring {0} resources from {1}:{2:X}", RESOURCE_POOL.List(this.part).Count, this.name, this.part.GetInstanceID()); + return; + } + Log.dbg("Restoring {0} resources from {1}:{2:X}", RESOURCE_POOL.List(this.part).Count, this.name, this.part.GetInstanceID()); this.part.Resources.Clear(); - foreach (Resource_t resource in this.resource.List) + foreach (Resource_t resource in RESOURCE_POOL.List(this.part)) this.part.Resources.Add(resource.ToPartResource(this.part)); }