summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ContentManagers
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/ContentManagers')
-rw-r--r--src/SMAPI/Framework/ContentManagers/BaseContentManager.cs21
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs21
2 files changed, 24 insertions, 18 deletions
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index f1ccab48..5ae5313d 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@@ -99,11 +97,13 @@ namespace StardewModdingAPI.Framework.ContentManagers
this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations;
// get asset data
- this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue();
+ this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue()
+ ?? throw new InvalidOperationException("Can't initialize content manager: the required 'disposableAssets' field wasn't found.");
}
/// <inheritdoc />
public virtual bool DoesAssetExist<T>(IAssetName assetName)
+ where T : notnull
{
return this.Cache.ContainsKey(assetName.Name);
}
@@ -131,6 +131,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <inheritdoc />
public T LoadLocalized<T>(IAssetName assetName, LanguageCode language, bool useCache)
+ where T : notnull
{
// ignore locale in English (or if disabled)
if (!this.TryLocalizeKeys || language == LocalizedContentManager.LanguageCode.en)
@@ -172,11 +173,12 @@ namespace StardewModdingAPI.Framework.ContentManagers
}
/// <inheritdoc />
- public abstract T LoadExact<T>(IAssetName assetName, bool useCache);
+ public abstract T LoadExact<T>(IAssetName assetName, bool useCache)
+ where T : notnull;
/// <inheritdoc />
[SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local", Justification = "Parameter is only used for assertion checks by design.")]
- public string AssertAndNormalizeAssetName(string assetName)
+ public string AssertAndNormalizeAssetName(string? assetName)
{
// NOTE: the game checks for ContentLoadException to handle invalid keys, so avoid
// throwing other types like ArgumentException here.
@@ -253,7 +255,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
// dispose uncached assets
foreach (WeakReference<IDisposable> reference in this.Disposables)
{
- if (reference.TryGetTarget(out IDisposable disposable))
+ if (reference.TryGetTarget(out IDisposable? disposable))
{
try
{
@@ -285,7 +287,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
*********/
/// <summary>Apply initial normalization to a raw asset name before it's parsed.</summary>
/// <param name="assetName">The asset name to normalize.</param>
- private string PrenormalizeRawAssetName(string assetName)
+ [return: NotNullIfNotNull("assetName")]
+ private string? PrenormalizeRawAssetName(string? assetName)
{
// trim
assetName = assetName?.Trim();
@@ -301,7 +304,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <summary>Normalize path separators in a file path. For asset keys, see <see cref="AssertAndNormalizeAssetName"/> instead.</summary>
/// <param name="path">The file path to normalize.</param>
[Pure]
- protected string NormalizePathSeparators(string path)
+ [return: NotNullIfNotNull("path")]
+ protected string? NormalizePathSeparators(string? path)
{
return this.Cache.NormalizePathSeparators(path);
}
@@ -323,6 +327,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="value">The asset value.</param>
/// <param name="useCache">Whether to save the asset to the asset cache.</param>
protected virtual void TrackAsset<T>(IAssetName assetName, T value, bool useCache)
+ where T : notnull
{
// track asset key
if (value is Texture2D texture)
diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
index 8051c296..f0f4bce9 100644
--- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
using System;
using System.Globalization;
using System.IO;
@@ -92,7 +90,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
// resolve managed asset key
{
- if (this.Coordinator.TryParseManagedAssetKey(assetName.Name, out string contentManagerID, out IAssetName relativePath))
+ if (this.Coordinator.TryParseManagedAssetKey(assetName.Name, out string? contentManagerID, out IAssetName? relativePath))
{
if (contentManagerID != this.Name)
throw this.GetLoadError(assetName, "can't load a different mod's managed asset key through this mod content manager.");
@@ -173,7 +171,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="file">The file to load.</param>
private T LoadDataFile<T>(IAssetName assetName, FileInfo file)
{
- if (!this.JsonHelper.ReadJsonFileIfExists(file.FullName, out T asset))
+ if (!this.JsonHelper.ReadJsonFileIfExists(file.FullName, out T? asset))
throw this.GetLoadError(assetName, "the JSON file is invalid."); // should never happen since we check for file existence before calling this method
return asset;
@@ -249,7 +247,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="assetName">The asset name that failed to load.</param>
/// <param name="reasonPhrase">The reason the file couldn't be loaded.</param>
/// <param name="exception">The underlying exception, if applicable.</param>
- private SContentLoadException GetLoadError(IAssetName assetName, string reasonPhrase, Exception exception = null)
+ private SContentLoadException GetLoadError(IAssetName assetName, string reasonPhrase, Exception? exception = null)
{
return new($"Failed loading asset '{assetName}' from {this.Name}: {reasonPhrase}", exception);
}
@@ -338,13 +336,16 @@ namespace StardewModdingAPI.Framework.ContentManagers
// load best match
try
{
- if (!this.TryGetTilesheetAssetName(relativeMapFolder, imageSource, out IAssetName assetName, out string error))
+ if (!this.TryGetTilesheetAssetName(relativeMapFolder, imageSource, out IAssetName? assetName, out string? error))
throw new SContentLoadException($"{errorPrefix} {error}");
- if (!assetName.IsEquivalentTo(tilesheet.ImageSource))
- this.Monitor.VerboseLog($" Mapped tilesheet '{tilesheet.ImageSource}' to '{assetName}'.");
+ if (assetName is not null)
+ {
+ if (!assetName.IsEquivalentTo(tilesheet.ImageSource))
+ this.Monitor.VerboseLog($" Mapped tilesheet '{tilesheet.ImageSource}' to '{assetName}'.");
- tilesheet.ImageSource = assetName.Name;
+ tilesheet.ImageSource = assetName.Name;
+ }
}
catch (Exception ex) when (ex is not SContentLoadException)
{
@@ -360,7 +361,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="error">A message indicating why the file couldn't be loaded.</param>
/// <returns>Returns whether the asset name was found.</returns>
/// <remarks>See remarks on <see cref="FixTilesheetPaths"/>.</remarks>
- private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relativePath, out IAssetName assetName, out string error)
+ private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relativePath, out IAssetName? assetName, out string? error)
{
assetName = null;
error = null;