add NameWithoutLocale fields (#766)

This commit is contained in:
Jesse Plamondon-Willard 2022-03-26 01:19:44 -04:00
parent 4da38e1317
commit e40907ab8b
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
9 changed files with 54 additions and 17 deletions

View File

@ -11,15 +11,21 @@ namespace StardewModdingAPI.Events
/// <summary>The name of the asset being requested.</summary>
public IAssetName Name { get; }
/// <summary>The <see cref="Name"/> with any locale codes stripped.</summary>
/// <remarks>For example, if <see cref="Name"/> contains a locale like <c>Data/Bundles.fr-FR</c>, this will be the name without locale like <c>Data/Bundles</c>. If the name has no locale, this field is equivalent.</remarks>
public IAssetName NameWithoutLocale { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="name">The name of the asset being requested.</param>
internal AssetReadyEventArgs(IAssetName name)
/// <param name="nameWithoutLocale">The <paramref name="name"/> with any locale codes stripped.</param>
internal AssetReadyEventArgs(IAssetName name, IAssetName nameWithoutLocale)
{
this.Name = name;
this.NameWithoutLocale = nameWithoutLocale;
}
}
}

View File

@ -26,6 +26,10 @@ namespace StardewModdingAPI.Events
/// <summary>The name of the asset being requested.</summary>
public IAssetName Name { get; }
/// <summary>The <see cref="Name"/> with any locale codes stripped.</summary>
/// <remarks>For example, if <see cref="Name"/> contains a locale like <c>Data/Bundles.fr-FR</c>, this will be the name without locale like <c>Data/Bundles</c>. If the name has no locale, this field is equivalent.</remarks>
public IAssetName NameWithoutLocale { get; }
/// <summary>The load operations requested by the event handler.</summary>
internal IList<AssetLoadOperation> LoadOperations { get; } = new List<AssetLoadOperation>();
@ -39,11 +43,13 @@ namespace StardewModdingAPI.Events
/// <summary>Construct an instance.</summary>
/// <param name="mod">The mod handling the event.</param>
/// <param name="name">The name of the asset being requested.</param>
/// <param name="nameWithoutLocale">The <paramref name="name"/> with any locale codes stripped.</param>
/// <param name="getOnBehalfOf">Get the mod metadata for a content pack, if it's a valid content pack for the mod.</param>
internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, Func<IModMetadata, string, string, IModMetadata> getOnBehalfOf)
internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Func<IModMetadata, string, string, IModMetadata> getOnBehalfOf)
{
this.Mod = mod;
this.Name = name;
this.NameWithoutLocale = nameWithoutLocale;
this.GetOnBehalfOf = getOnBehalfOf;
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace StardewModdingAPI.Events
{
@ -14,15 +13,21 @@ namespace StardewModdingAPI.Events
/// <summary>The asset names that were invalidated.</summary>
public IReadOnlySet<IAssetName> Names { get; }
/// <summary>The <see cref="Names"/> with any locale codes stripped.</summary>
/// <remarks>For example, if <see cref="Names"/> contains a locale like <c>Data/Bundles.fr-FR</c>, this will have the name without locale like <c>Data/Bundles</c>. If the name has no locale, this field is equivalent.</remarks>
public IReadOnlySet<IAssetName> NamesWithoutLocale { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="names">The asset names that were invalidated.</param>
internal AssetsInvalidatedEventArgs(IEnumerable<IAssetName> names)
/// <param name="namesWithoutLocale">The <paramref name="names"/> with any locale codes stripped.</param>
internal AssetsInvalidatedEventArgs(IEnumerable<IAssetName> names, IEnumerable<IAssetName> namesWithoutLocale)
{
this.Names = names.ToImmutableHashSet();
this.NamesWithoutLocale = namesWithoutLocale.ToImmutableHashSet();
}
}
}

View File

@ -23,8 +23,11 @@ namespace StardewModdingAPI.Framework.Content
public IAssetName Name { get; }
/// <inheritdoc />
[Obsolete($"Use {nameof(Name)} instead.")]
public string AssetName => this.Name.Name;
public IAssetName NameWithoutLocale { get; }
/// <inheritdoc />
[Obsolete($"Use {nameof(Name)} or {nameof(NameWithoutLocale)} instead.")]
public string AssetName => this.NameWithoutLocale.Name;
/// <inheritdoc />
public Type DataType { get; }
@ -42,15 +45,16 @@ namespace StardewModdingAPI.Framework.Content
{
this.Locale = locale;
this.Name = assetName;
this.NameWithoutLocale = assetName.GetBaseAssetName();
this.DataType = type;
this.GetNormalizedPath = getNormalizedPath;
}
/// <inheritdoc />
[Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} instead.")]
[Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} or {nameof(NameWithoutLocale)}.{nameof(IAssetName.IsEquivalentTo)} instead.")]
public bool AssetNameEquals(string path)
{
return this.Name.IsEquivalentTo(path);
return this.NameWithoutLocale.IsEquivalentTo(path);
}

View File

@ -142,11 +142,20 @@ namespace StardewModdingAPI.Framework.Content
}
/// <inheritdoc />
public bool IsDirectlyUnderPath(string assetFolder)
{
return this.StartsWith(assetFolder + "/", allowPartialWord: false, allowSubfolder: false);
}
/// <inheritdoc />
IAssetName IAssetName.GetBaseAssetName()
{
return this.LocaleCode == null
? this
: new AssetName(this.BaseName, null, null);
}
/// <inheritdoc />
public bool Equals(IAssetName other)
{

View File

@ -53,7 +53,7 @@ namespace StardewModdingAPI.Framework
private readonly Action<BaseContentManager, IAssetName> OnAssetLoaded;
/// <summary>A callback to invoke when any asset names have been invalidated from the cache.</summary>
private readonly Action<IEnumerable<IAssetName>> OnAssetsInvalidated;
private readonly Action<IList<IAssetName>> OnAssetsInvalidated;
/// <summary>Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</summary>
private readonly Func<IAssetInfo, IList<AssetOperationGroup>> RequestAssetOperations;
@ -118,7 +118,7 @@ namespace StardewModdingAPI.Framework
/// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
/// <param name="onAssetsInvalidated">A callback to invoke when any asset names have been invalidated from the cache.</param>
/// <param name="requestAssetOperations">Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</param>
public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations, Action<IEnumerable<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations)
public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations, Action<IList<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations)
{
this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations;
this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
@ -414,7 +414,7 @@ namespace StardewModdingAPI.Framework
this.AssetOperationsByKey.Remove(name);
// raise event
this.OnAssetsInvalidated(invalidatedAssets.Keys);
this.OnAssetsInvalidated(invalidatedAssets.Keys.ToArray());
// propagate changes to the game
this.CoreAssets.Propagate(

View File

@ -1113,15 +1113,15 @@ namespace StardewModdingAPI.Framework
private void OnAssetLoaded(IContentManager contentManager, IAssetName assetName)
{
if (this.EventManager.AssetReady.HasListeners())
this.EventManager.AssetReady.Raise(new AssetReadyEventArgs(assetName));
this.EventManager.AssetReady.Raise(new AssetReadyEventArgs(assetName, assetName.GetBaseAssetName()));
}
/// <summary>A callback invoked after assets have been invalidated from the content cache.</summary>
/// <param name="assetNames">The invalidated asset names.</param>
private void OnAssetsInvalidated(IEnumerable<IAssetName> assetNames)
private void OnAssetsInvalidated(IList<IAssetName> assetNames)
{
if (this.EventManager.AssetsInvalidated.HasListeners())
this.EventManager.AssetsInvalidated.Raise(new AssetsInvalidatedEventArgs(assetNames));
this.EventManager.AssetsInvalidated.Raise(new AssetsInvalidatedEventArgs(assetNames, assetNames.Select(p => p.GetBaseAssetName())));
}
/// <summary>Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</summary>
@ -1133,7 +1133,7 @@ namespace StardewModdingAPI.Framework
this.EventManager.AssetRequested.Raise(
invoke: (mod, invoke) =>
{
AssetRequestedEventArgs args = new(mod, asset.Name, this.GetOnBehalfOfContentPack);
AssetRequestedEventArgs args = new(mod, asset.Name, asset.NameWithoutLocale, this.GetOnBehalfOfContentPack);
invoke(args);

View File

@ -14,8 +14,12 @@ namespace StardewModdingAPI
/// <summary>The asset name being read.</summary>
public IAssetName Name { get; }
/// <summary>The <see cref="Name"/> with any locale codes stripped.</summary>
/// <remarks>For example, if <see cref="Name"/> contains a locale like <c>Data/Bundles.fr-FR</c>, this will be the name without locale like <c>Data/Bundles</c>. If the name has no locale, this field is equivalent.</remarks>
public IAssetName NameWithoutLocale { get; }
/// <summary>The normalized asset name being read. The format may change between platforms; see <see cref="AssetNameEquals"/> to compare with a known path.</summary>
[Obsolete($"Use {nameof(Name)} instead.")]
[Obsolete($"Use {nameof(Name)} or {nameof(NameWithoutLocale)} instead.")]
string AssetName { get; }
/// <summary>The content data type.</summary>
@ -27,7 +31,7 @@ namespace StardewModdingAPI
*********/
/// <summary>Get whether the asset name being loaded matches a given name after normalization.</summary>
/// <param name="path">The expected asset path, relative to the game's content folder and without the .xnb extension or locale suffix (like 'Data\ObjectInformation').</param>
[Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} instead.")]
[Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} or {nameof(NameWithoutLocale)}.{nameof(IAssetName.IsEquivalentTo)} instead.")]
bool AssetNameEquals(string path);
}
}

View File

@ -40,5 +40,8 @@ namespace StardewModdingAPI
/// <remarks>For example, <c>Characters/Dialogue/Abigail</c> is directly under <c>Characters/Dialogue</c> but not <c>Characters</c> or <c>Characters/Dialogue/Ab</c>. To allow sub-paths, use <see cref="StartsWith"/> instead.</remarks>
/// <param name="assetFolder">The asset path to check. This doesn't need a trailing slash.</param>
bool IsDirectlyUnderPath(string assetFolder);
/// <summary>Get an asset name representing the <see cref="BaseName"/> without locale.</summary>
internal IAssetName GetBaseAssetName();
}
}