Skip to content

Commit

Permalink
move IEditAssetMigrator logic into BaseRuntimeMigration
Browse files Browse the repository at this point in the history
  • Loading branch information
Pathoschild committed Feb 15, 2024
1 parent 06f3670 commit 4caad1c
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 95 deletions.
4 changes: 2 additions & 2 deletions ContentPatcher/Framework/Migrations/BaseMigration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace ContentPatcher.Framework.Migrations
internal abstract class BaseMigration : IMigration
{
/*********
** Private methods
** Fields
*********/
/// <summary>The tokens added in this format version.</summary>
protected InvariantSet? AddedTokens { get; set; }
protected InvariantSet? AddedTokens;


/*********
Expand Down
48 changes: 48 additions & 0 deletions ContentPatcher/Framework/Migrations/BaseRuntimeMigration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using ContentPatcher.Framework.Conditions;
using ContentPatcher.Framework.Migrations.Internal;
using ContentPatcher.Framework.Patches;
using StardewModdingAPI;

Expand All @@ -7,19 +10,49 @@ namespace ContentPatcher.Framework.Migrations
/// <summary>The base implementation for a format version migrator which overrides patches at runtime.</summary>
internal abstract class BaseRuntimeMigration : BaseMigration, IRuntimeMigration
{
/*********
** Fields
*********/
/// <summary>The migrators that convert older <see cref="PatchType.EditData"/> patches to a newer asset or format.</summary>
/// <remarks>For each edit, the first migrator which applies or returns errors is used.</remarks>
protected IEditAssetMigrator[] RuntimeEditDataMigrators = Array.Empty<IEditAssetMigrator>();


/*********
** Public methods
*********/
/// <inheritdoc />
public virtual IAssetName? RedirectTarget(IAssetName assetName, IPatch patch)
{
foreach (IEditAssetMigrator migrator in this.RuntimeEditDataMigrators)
{
if (migrator.AppliesTo(assetName))
{
IAssetName? newName = migrator.RedirectTarget(assetName, patch);
if (newName != null)
return newName;
}
}

return null;
}

/// <inheritdoc />
public virtual bool TryApplyLoadPatch<T>(LoadPatch patch, IAssetName assetName, [NotNullWhen(true)] ref T? asset, out string? error)
where T : notnull
{
foreach (IEditAssetMigrator migrator in this.RuntimeEditDataMigrators)
{
if (migrator.AppliesTo(patch.TargetAssetBeforeRedirection ?? assetName))
{
if (migrator.TryApplyLoadPatch(patch, assetName, ref asset, out error))
return true;

if (error != null)
return false;
}
}

error = null;
return false;
}
Expand All @@ -28,6 +61,21 @@ public virtual bool TryApplyLoadPatch<T>(LoadPatch patch, IAssetName assetName,
public virtual bool TryApplyEditPatch<T>(IPatch patch, IAssetData asset, out string? error)
where T : notnull
{
if (patch is EditDataPatch editPatch)
{
foreach (IEditAssetMigrator migrator in this.RuntimeEditDataMigrators)
{
if (migrator.AppliesTo(patch.TargetAssetBeforeRedirection ?? asset.Name))
{
if (migrator.TryApplyEditPatch<T>(editPatch, asset, out error))
return true;

if (error != null)
return false;
}
}
}

error = null;
return false;
}
Expand Down
24 changes: 24 additions & 0 deletions ContentPatcher/Framework/Migrations/Internal/IEditAssetMigrator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
using ContentPatcher.Framework.Conditions;
using ContentPatcher.Framework.Patches;
using StardewModdingAPI;

namespace ContentPatcher.Framework.Migrations.Internal
{
/// <summary>A migrator which applies older <see cref="PatchType.EditData"/> patches to a newer asset or format.</summary>
internal interface IEditAssetMigrator
{
/// <summary>Get whether this migration applies to a patch.</summary>
/// <param name="assetName">The asset name to check. If the asset was redirected, this is the asset name before redirection.</param>
bool AppliesTo(IAssetName assetName);

/// <inheritdoc cref="IRuntimeMigration.RedirectTarget" />
IAssetName? RedirectTarget(IAssetName assetName, IPatch patch);

/// <inheritdoc cref="IRuntimeMigration.TryApplyLoadPatch{T}" />
bool TryApplyLoadPatch<T>(LoadPatch patch, IAssetName assetName, [NotNullWhen(true)] ref T? asset, out string? error);

/// <inheritdoc cref="IRuntimeMigration.TryApplyEditPatch{T}" />
bool TryApplyEditPatch<T>(EditDataPatch patch, IAssetData asset, out string? error);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ internal static class RuntimeMigrationHelper
private static readonly Dictionary<string, string?> ParseObjectIdCache = new();


/*********
** Public methods
*********/
/// <summary>Get the unqualified object ID, if it's a valid object ID.</summary>
/// <param name="rawItemId">The raw item ID, which may be an item query or non-object ID.</param>
/// <returns>Returns the unqualified object ID, or <c>null</c> if it's not a valid object ID.</returns>
Expand Down
96 changes: 3 additions & 93 deletions ContentPatcher/Framework/Migrations/Migration_2_0.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using ContentPatcher.Framework.Conditions;
using ContentPatcher.Framework.ConfigModels;
using ContentPatcher.Framework.Patches;
using Pathoschild.Stardew.Common.Utilities;
using StardewModdingAPI;

Expand All @@ -11,14 +10,6 @@ namespace ContentPatcher.Framework.Migrations
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Named for clarity.")]
internal partial class Migration_2_0 : BaseRuntimeMigration
{
/*********
** Fields
*********/
/// <summary>The migrators that convert pre-1.6 edit patches to a newer asset or format.</summary>
/// <remarks>For each edit, the first migrator which applies or returns errors is used.</remarks>
private readonly IEditAssetMigrator[] Migrators;


/*********
** Public methods
*********/
Expand All @@ -29,20 +20,16 @@ public Migration_2_0()
this.AddedTokens = new InvariantSet(
nameof(ConditionType.ModId)
);
this.MigrationWarnings = [
"Some content packs haven't been updated for Stardew Valley 1.6.0. Content Patcher will try to auto-migrate them, but compatibility isn't guaranteed."
];

this.Migrators = new IEditAssetMigrator[]
{
this.MigrationWarnings = ["Some content packs haven't been updated for Stardew Valley 1.6.0. Content Patcher will try to auto-migrate them, but compatibility isn't guaranteed."];
this.RuntimeEditDataMigrators = [
new BigCraftableInformationMigrator(),
new BlueprintsMigrator(),
new BootsMigrator(),
new CropsMigrator(),
new LocationsMigrator(),
new NpcDispositionsMigrator(),
new ObjectInformationMigrator()
};
];
}

/// <inheritdoc />
Expand All @@ -63,82 +50,5 @@ public override bool TryMigrate(ref PatchConfig[] patches, [NotNullWhen(false)]

return true;
}

/// <inheritdoc />
public override IAssetName? RedirectTarget(IAssetName assetName, IPatch patch)
{
foreach (IEditAssetMigrator migrator in this.Migrators)
{
if (migrator.AppliesTo(assetName))
{
IAssetName? newName = migrator.RedirectTarget(assetName, patch);
if (newName != null)
return newName;
}
}

return base.RedirectTarget(assetName, patch);
}

/// <inheritdoc />
public override bool TryApplyLoadPatch<T>(LoadPatch patch, IAssetName assetName, [NotNullWhen(true)] ref T? asset, out string? error)
where T : default
{
foreach (IEditAssetMigrator migrator in this.Migrators)
{
if (migrator.AppliesTo(patch.TargetAssetBeforeRedirection ?? assetName))
{
if (migrator.TryApplyLoadPatch(patch, assetName, ref asset, out error))
return true;

if (error != null)
return false;
}
}

return base.TryApplyLoadPatch<T>(patch, assetName, ref asset, out error);
}

/// <inheritdoc />
public override bool TryApplyEditPatch<T>(IPatch patch, IAssetData asset, out string? error)
{
if (patch is EditDataPatch editPatch)
{
foreach (IEditAssetMigrator migrator in this.Migrators)
{
if (migrator.AppliesTo(patch.TargetAssetBeforeRedirection ?? asset.Name))
{
if (migrator.TryApplyEditPatch<T>(editPatch, asset, out error))
return true;

if (error != null)
return false;
}
}
}

return base.TryApplyEditPatch<T>(patch, asset, out error);
}


/*********
** Private methods
*********/
/// <summary>The migration logic to apply pre-1.6 edit patches to a new asset or format.</summary>
private interface IEditAssetMigrator
{
/// <summary>Get whether this migration applies to a patch.</summary>
/// <param name="assetName">The asset name to check. If the asset was redirected, this is the asset name before redirection.</param>
bool AppliesTo(IAssetName assetName);

/// <inheritdoc cref="IRuntimeMigration.RedirectTarget" />
IAssetName? RedirectTarget(IAssetName assetName, IPatch patch);

/// <inheritdoc cref="IRuntimeMigration.TryApplyLoadPatch{T}" />
bool TryApplyLoadPatch<T>(LoadPatch patch, IAssetName assetName, [NotNullWhen(true)] ref T? asset, out string? error);

/// <inheritdoc cref="IRuntimeMigration.TryApplyEditPatch{T}" />
bool TryApplyEditPatch<T>(EditDataPatch patch, IAssetData asset, out string? error);
}
}
}

0 comments on commit 4caad1c

Please sign in to comment.