Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Editor/PrefabPatchPlayModeCleanup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using PatchManager.PrefabPatching;
using UnityEditor;

namespace PatchManager.Editor;

[InitializeOnLoad]
internal static class PrefabPatchPlayModeCleanup
{
static PrefabPatchPlayModeCleanup()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}

private static void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.ExitingPlayMode)
PrefabPatchRuntime.ReleaseSessionResources();
}
}
2 changes: 2 additions & 0 deletions Editor/PrefabPatchPlayModeCleanup.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, nit, but this should just link to modding.ksp2redux.org, the documentation here is out of data

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Patch Manager
A mod for generic patching needs similar to KSP 1's Module Manager.

Documentation: https://ksp2community.github.io/PatchManagerDocs/
Documentation: https://modding.ksp2redux.org
24 changes: 24 additions & 0 deletions Runtime/CSharpPatching/PrefabPatchingCSharpPatching.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using PatchManager.PrefabPatching;

namespace PatchManager.CSharpPatching
{
/// <summary>
/// Mod-scoped C# frontend for declarative prefab patches.
/// </summary>
public static class PrefabPatchingCSharpPatching
{
/// <summary>
/// Creates a prefab patch owned by the calling mod's swinfo identity.
/// </summary>
/// <summary>
/// Creates a prefab patch targeting a stock Addressables key.
/// Canonical bundle and CAB metadata are not part of imperative
/// authoring.
/// </summary>
public static PrefabPatchBuilder PatchPrefab(
this PmScope scope,
string name,
string address
) => new(scope.ModId, name, address);
}
}
2 changes: 2 additions & 0 deletions Runtime/CSharpPatching/PrefabPatchingCSharpPatching.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 21 additions & 3 deletions Runtime/Core/Assets/Locators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,33 @@ public static void Register(IResourceLocator locator)
/// <param name="locations">List of locations of the found assets.</param>
/// <returns>True if any assets were found, false otherwise.</returns>
public static bool LocateAll(object label, out List<IResourceLocation> locations)
{
return LocateAll(label, typeof(TextAsset), out locations);
}

/// <summary>
/// Locate assets by key and requested type across every Patch Manager
/// asset-domain locator.
/// </summary>
public static bool LocateAll(
object key,
System.Type type,
out List<IResourceLocation> locations
)
{
locations = new List<IResourceLocation>();
foreach (var locator in ResourceLocators)
{
locator.Locate(label, typeof(TextAsset), out var foundLocations);
locations.AddRange(foundLocations);
if (
locator.Locate(key, type, out var foundLocations)
&& foundLocations != null
)
{
locations.AddRange(foundLocations);
}
}

return locations.Count > 0;
}
}
}
}
3 changes: 2 additions & 1 deletion Runtime/Core/Cache/CacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Reflection;
using PatchManager.Core.Cache.Json;
using PatchManager.PrefabPatching;
using PatchManager.Shared;

namespace PatchManager.Core.Cache
Expand Down Expand Up @@ -200,7 +201,7 @@ public static void SaveInventory()

public static void SaveSummary(Summary universeSummary)
{
File.WriteAllText("./pm_summary.log", universeSummary.Dump());
PatchManagerSummaryLog.UpdateCoreSummary(universeSummary.Dump());
}
}
}
49 changes: 49 additions & 0 deletions Runtime/Core/CoreModule.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using KSP.Game;
using KSP.Game.Flow;
using PatchManager.Core.Assets;
using PatchManager.Core.Cache;
using PatchManager.LuaPatching;
using PatchManager.PrefabPatching;
using PatchManager.Shared;
using PatchManager.Shared.Modules;
using ReduxLib.Configuration;
using ReduxLib.Configuration.Attributes;
using SpaceWarp2.API.Mods;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UIElements;
Expand Down Expand Up @@ -81,6 +84,12 @@ private void DecideCacheValidity(Action resolve, Action<string> reject)
tail.Add(new GenericFlowAction("Patch Manager: Saving Patch Summary", SavePatchSummary));
}

tail.Add(
new GenericFlowAction(
"Patch Manager: Resolving Prefab Patch Plans",
ResolvePrefabPatchPlans
)
);
tail.Add(new GenericFlowAction("Patch Manager: Registering Resource Locator", RegisterResourceLocator));

// Splice the tail in right after this step. Insert back-to-front so each Insert at the same index
Expand All @@ -97,9 +106,39 @@ private void DecideCacheValidity(Action resolve, Action<string> reject)
private static void CloseRegistration(Action resolve, Action<string> reject)
{
PatchingManager.Universe.RegistrationOpen = false;
PrefabPatchRuntime.CloseRegistration();
resolve();
}

private static void ResolvePrefabPatchPlans(
Action resolve,
Action<string> reject
)
{
var manifestSources =
PluginList.AllEnabledAndActivePlugins
.Where(descriptor =>
!string.IsNullOrWhiteSpace(
descriptor.AddressablePrefabPatchLabel
)
)
.Select(descriptor =>
new PrefabPatchManifestSource
{
OwnerModId = descriptor.Guid,
AddressablesLabel =
descriptor.AddressablePrefabPatchLabel
}
)
.ToArray();
PrefabPatchRuntime.DiscoverAndResolve(
PatchingManager.Universe.AllMods,
manifestSources,
resolve,
reject
);
}

private void SavePatchSummary(Action resolve, Action<string> reject)
{
PatchingManager.Universe.Summary.RecognizedModIds = PatchingManager.Universe.AllMods;
Expand Down Expand Up @@ -146,6 +185,7 @@ private void RegisterResourceLocator(Action resolve, Action<string> reject)
}

Locators.Register(new ArchiveResourceLocator());
Locators.Register(PrefabPatchRuntime.RegisterResourceProvider());
GameManager.Instance.Game.UI.UitkLoadingCurtain.Data.PatchManagerDefinitionsModifiedCount =
CacheManager.Inventory.DefinitionCount;
GameManager.Instance.Game.UI.UitkLoadingCurtain.Data.PatchManagerNewAssetCount =
Expand Down Expand Up @@ -189,6 +229,15 @@ public override VisualElement GetDetails()
text.text += $"\n- {label}";
}

var prefabMetrics = PrefabPatchRuntime.CurrentMetrics;
text.text +=
$"\nPrefab plans: {prefabMetrics.ResolvedPlanCount}"
+ $" ({prefabMetrics.CacheHitCount} cache hit(s), "
+ $"{prefabMetrics.CacheMissCount} miss(es))";
text.text +=
$"\nRetained prefab handles: "
+ $"{prefabMetrics.RetainedAddressablesHandles}";

text.visible = true;
text.style.display = DisplayStyle.Flex;
foldout.Add(text);
Expand Down
38 changes: 38 additions & 0 deletions Runtime/LuaPatching/Builtin/PatchManagerCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,44 @@ public PatchDefinition Patch(ScriptExecutionContext context, string converter, s
return newPatch;
}

/// <summary>
/// Begins a declarative prefab patch for one stock Addressables key.
/// </summary>
public PrefabPatchLuaBuilder Prefab(
ScriptExecutionContext context,
string name,
DynValue target
)
{
if (!_universe.RegistrationOpen)
{
throw new ScriptRuntimeException(
$"PM:Prefab('{name}') can only be called during patch "
+ "registration."
);
}

var modId = context.CurrentGlobalEnv
.Get("ModId")
.CastToString();
if (target.Type != DataType.String)
{
throw new ScriptRuntimeException(
"PM:Prefab expects the stock prefab's Addressables key."
);
}
var identity =
global::PatchManager.PrefabPatching.PrefabPatchPrefabIdentity
.FromAddress(target.String);
return new PrefabPatchLuaBuilder(
new global::PatchManager.PrefabPatching.PrefabPatchBuilder(
modId,
name,
identity
)
);
}

/// <summary>
/// Queues a brand-new asset for creation under the given label and address.
/// </summary>
Expand Down
Loading