diff --git a/src/RealAntennasProject/ModuleRealAntenna.cs b/src/RealAntennasProject/ModuleRealAntenna.cs index ad49256..c941952 100644 --- a/src/RealAntennasProject/ModuleRealAntenna.cs +++ b/src/RealAntennasProject/ModuleRealAntenna.cs @@ -1,4 +1,5 @@ -using System; +using KSPCommunityFixes; +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; @@ -173,7 +174,7 @@ public override void OnStart(StartState state) Events[nameof(AntennaTargetGUI)].active = false; } - deployableAntenna = part.FindModuleImplementing(); + deployableAntenna = part.FindModuleImplementingFast(); ApplyGameSettings(); SetupUICallbacks(); diff --git a/src/RealAntennasProject/RACommNetVessel.cs b/src/RealAntennasProject/RACommNetVessel.cs index b08150c..7566ff2 100644 --- a/src/RealAntennasProject/RACommNetVessel.cs +++ b/src/RealAntennasProject/RACommNetVessel.cs @@ -1,8 +1,10 @@ using Expansions.Serenity.DeployedScience.Runtime; using Experience.Effects; +using KSPCommunityFixes; using System; using System.Collections.Generic; using System.Linq; +using UnityEngine.Profiling; namespace RealAntennas { @@ -124,40 +126,51 @@ private int CountControllingCrew() private void DetermineControlUnloaded() { + Profiler.BeginSample("DetermineControlUnloaded"); int numControl = CountControllingCrew(); int index = 0; foreach (ProtoPartSnapshot protoPartSnapshot in vessel.protoVessel.protoPartSnapshots) { index++; Part part = protoPartSnapshot.partInfo.partPrefab; - foreach (PartModule module in part.Modules) + if (part.FindModuleImplementingFast() is CommNet.ModuleProbeControlPoint pcp && + pcp.CanControlUnloaded(protoPartSnapshot.FindModule(pcp, index))) { - if ((module is CommNet.ModuleProbeControlPoint probeControlPoint) && probeControlPoint.CanControlUnloaded(protoPartSnapshot.FindModule(module, index))) - { - if (numControl >= probeControlPoint.minimumCrew || probeControlPoint.minimumCrew <= 0) - comm.isControlSource = true; - if (probeControlPoint.multiHop) - comm.isControlSourceMultiHop = true; - } + if (numControl >= pcp.minimumCrew || pcp.minimumCrew <= 0) + comm.isControlSource = true; + if (pcp.multiHop) + comm.isControlSourceMultiHop = true; + + // Assume that control parts are closer to root than leaf nodes. + // If both fields are true then no point in looking any further. + if (comm.isControlSource && comm.isControlSourceMultiHop) + break; } } + Profiler.EndSample(); } + private void DetermineControlLoaded() { + Profiler.BeginSample("DetermineControlLoaded"); int numControl = CountControllingCrew(); foreach (Part part in vessel.Parts) { - foreach (PartModule module in part.Modules) + if (part.FindModuleImplementingFast() is CommNet.ModuleProbeControlPoint pcp && + pcp.CanControl()) { - if ((module is CommNet.ModuleProbeControlPoint probeControlPoint) && probeControlPoint.CanControl()) - { - if (numControl >= probeControlPoint.minimumCrew || probeControlPoint.minimumCrew <= 0) - comm.isControlSource = true; - if (probeControlPoint.multiHop) - comm.isControlSourceMultiHop = true; - } + if (numControl >= pcp.minimumCrew || pcp.minimumCrew <= 0) + comm.isControlSource = true; + if (pcp.multiHop) + comm.isControlSourceMultiHop = true; + + // Assume that control parts are closer to root than leaf nodes. + // If both fields are true then no point in looking any further. + if (comm.isControlSource && comm.isControlSourceMultiHop) + break; } } + Profiler.EndSample(); } protected void OnVesselModified(Vessel data) @@ -173,14 +186,18 @@ protected List DiscoverAntennas() if (Vessel == null) return antennaList; if (Vessel.loaded) { - foreach (ModuleRealAntenna ant in Vessel.FindPartModulesImplementing().ToList()) + foreach (Part part in vessel.parts) { - if (ant.Condition == AntennaCondition.Enabled) + var moduleList = part.FindModulesImplementingReadOnly(); + foreach (ModuleRealAntenna ant in moduleList) { - ant.RAAntenna.ParentNode = Comm; - if (DeployedLoaded(ant.part)) antennaList.Add(ant.RAAntenna); - else inactiveAntennas.Add(ant.RAAntenna); - ValidateAntennaTarget(ant.RAAntenna); + if (ant.Condition == AntennaCondition.Enabled) + { + ant.RAAntenna.ParentNode = Comm; + if (DeployedLoaded(ant.part)) antennaList.Add(ant.RAAntenna); + else inactiveAntennas.Add(ant.RAAntenna); + ValidateAntennaTarget(ant.RAAntenna); + } } } return antennaList; @@ -197,7 +214,8 @@ protected List DiscoverAntennas() _enabled = sState == AntennaCondition.Enabled.ToString(); // Doesn't get the correct PartModule if multiple, but the only impact is the name, which defaults to the part anyway. - if (_enabled && part.partInfo.partPrefab.FindModuleImplementing() is ModuleRealAntenna mra && mra.CanCommUnloaded(snap)) + if (_enabled && part.partInfo.partPrefab.FindModuleImplementingFast() is ModuleRealAntenna mra && + mra.CanCommUnloaded(snap)) { RealAntenna ra = new RealAntennaDigital(part.partPrefab.partInfo.title) { ParentNode = Comm, ParentSnapshot = snap }; ra.LoadFromConfigNode(snap.moduleValues); @@ -226,7 +244,7 @@ public static bool DeployedUnloaded(ProtoPartSnapshot part) return true; } public static bool DeployedLoaded(Part part) => - (part.FindModuleImplementing() is ModuleDeployableAntenna mda) ? + (part.FindModuleImplementingFast() is ModuleDeployableAntenna mda) ? mda.deployState == ModuleDeployablePart.DeployState.EXTENDED : true; private bool IsDeployedScienceCluster(Vessel v) => GetDeployedScienceCluster(v) != null; diff --git a/src/RealAntennasProject/RealAntennas.csproj b/src/RealAntennasProject/RealAntennas.csproj index e19f7cb..7e59c28 100644 --- a/src/RealAntennasProject/RealAntennas.csproj +++ b/src/RealAntennasProject/RealAntennas.csproj @@ -94,6 +94,7 @@ +