From 82dc128e3d8414cd0623bc40cc2f5d6469c8b07d Mon Sep 17 00:00:00 2001 From: Falki-git <72734856+Falki-git@users.noreply.github.com> Date: Wed, 20 Dec 2023 11:59:37 +0100 Subject: [PATCH] Add API for mods to register their custom module PartComponentModule for background resource processing --- Directory.Build.props | 2 +- .../API/Parts/PartComponentModuleOverride.cs | 45 +++++++++++++++ .../PartOwnerComponentOnFixedUpdate.cs | 55 +++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs create mode 100644 SpaceWarp.Core/Patching/PartOwnerComponentOnFixedUpdate.cs diff --git a/Directory.Build.props b/Directory.Build.props index a2be5c89..e2aa9f15 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 1.5.4 + 1.6.0 netstandard2.1 SpaceWarp 11 diff --git a/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs b/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs new file mode 100644 index 00000000..c549e3d7 --- /dev/null +++ b/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using KSP.Sim.impl; +using SpaceWarp.API.Logging; + +namespace SpaceWarp.API.Parts; + +[PublicAPI] +public static class PartComponentModuleOverride +{ + private static readonly ILogger _LOGGER = new UnityLogSource("SpaceWarp.PartComponentModuleOverride"); + + internal static List RegisteredPartComponentOverrides = new(); + + /// + /// Registers your custom module for background resource processing. + /// + /// Your Custom Module class that inherits from PartComponentModule + public static void RegisterModuleForBackgroundResourceProcessing() where T : PartComponentModule + { + var moduleName = typeof(T).Name; + + // Check if this Module is already registered + if (RegisteredPartComponentOverrides.Contains(typeof(T))) + { + throw new ArgumentException($"Module '{moduleName}' is already registered. Skipping.", nameof(T)); + } + + RegisteredPartComponentOverrides.Add(typeof(T)); + _LOGGER.LogInfo($"Registered '{moduleName}' for background resources processing."); + } + + /// + /// Unregisters your custom module from background resource processing. + /// + /// Your Custom Module class that inherits from PartComponentModule + public static void UnRegisterModuleForBackgroundResourceProcessing() where T : PartComponentModule + { + if (!RegisteredPartComponentOverrides.Contains(typeof(T))) return; + + RegisteredPartComponentOverrides.Remove(typeof(T)); + _LOGGER.LogInfo($"Unregistered '{typeof(T).Name}' from background resources processing."); + } +} \ No newline at end of file diff --git a/SpaceWarp.Core/Patching/PartOwnerComponentOnFixedUpdate.cs b/SpaceWarp.Core/Patching/PartOwnerComponentOnFixedUpdate.cs new file mode 100644 index 00000000..b7b87cf7 --- /dev/null +++ b/SpaceWarp.Core/Patching/PartOwnerComponentOnFixedUpdate.cs @@ -0,0 +1,55 @@ +using HarmonyLib; +using KSP.Sim.impl; +using SpaceWarp.API.Parts; + +namespace SpaceWarp.Patching; + +[HarmonyPatch] +internal class PartOwnerComponentOnFixedUpdate +{ + [HarmonyPatch(typeof(PartOwnerComponent), "OnFixedUpdate"), HarmonyPrefix] + private static bool PerformBackgroundCalculationsForRegisteredModules(double universalTime, + double deltaUniversalTime, + PartOwnerComponent __instance) + { + var isModulePresent = false; + + // Go through each registered module and check if it's present in PartOwnerComponent modules + foreach (var moduleType in PartComponentModuleOverride.RegisteredPartComponentOverrides) + { + var hasPartModuleMethod = __instance.GetType().GetMethod("HasPartModule"); + + if (hasPartModuleMethod != null) + { + var genericMethod = hasPartModuleMethod.MakeGenericMethod(moduleType); + + if ((bool)genericMethod.Invoke(__instance, null)) + { + isModulePresent = true; + break; + } + } + } + + // If registered module is present, run the original 0.1.5 method that runs background resource checks + if (isModulePresent) + { + __instance.RecalculatePhysicsStats(false); + if (__instance.PartAttachmentsDirty) + { + __instance.UpdatePartRelationships(); + } + if (__instance.ResourceFlowRequestManager != null && __instance.FlowGraph != null) + { + __instance.ResourceFlowRequestManager.UpdateFlowRequests(universalTime, deltaUniversalTime); + } + __instance.UpdateInsolation(); + __instance.UpdateHasPanelsStellarExposure(); + + return false; + } + + // No registered modules are present, resume with the current method + return true; + } +} \ No newline at end of file