summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-06-20 18:01:48 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-06-20 18:01:48 -0400
commitdab1ef6acc243726247cee57877c3b3100106522 (patch)
tree627610696a998621327fb019586f956b9360bb95
parente0ef8a20a5e7ccf1de32ff1a06f1aa62e37eb1db (diff)
downloadSMAPI-dab1ef6acc243726247cee57877c3b3100106522.tar.gz
SMAPI-dab1ef6acc243726247cee57877c3b3100106522.tar.bz2
SMAPI-dab1ef6acc243726247cee57877c3b3100106522.zip
add flag to disable deprecated code
-rw-r--r--build/common.targets18
-rw-r--r--docs/technical/smapi.md1
-rw-r--r--src/SMAPI.Toolkit/Framework/ModData/ModWarning.cs4
-rw-r--r--src/SMAPI/Constants.cs4
-rw-r--r--src/SMAPI/Framework/Content/AssetInfo.cs12
-rw-r--r--src/SMAPI/Framework/Content/AssetInterceptorChange.cs3
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs20
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs24
-rw-r--r--src/SMAPI/Framework/ContentPack.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/CommandHelper.cs4
-rw-r--r--src/SMAPI/Framework/ModHelpers/ContentHelper.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModHelper.cs17
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs4
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs2
-rw-r--r--src/SMAPI/Framework/SCore.cs22
-rw-r--r--src/SMAPI/GameFramework.cs4
-rw-r--r--src/SMAPI/IAssetEditor.cs2
-rw-r--r--src/SMAPI/IAssetInfo.cs16
-rw-r--r--src/SMAPI/IAssetLoader.cs2
-rw-r--r--src/SMAPI/ICommandHelper.cs2
-rw-r--r--src/SMAPI/IContentHelper.cs2
-rw-r--r--src/SMAPI/IContentPack.cs4
-rw-r--r--src/SMAPI/IModHelper.cs4
-rw-r--r--src/SMAPI/Metadata/InstructionMetadata.cs2
-rw-r--r--src/SMAPI/Utilities/PerScreen.cs49
26 files changed, 173 insertions, 55 deletions
diff --git a/build/common.targets b/build/common.targets
index 8b17c45a..92fd9a9a 100644
--- a/build/common.targets
+++ b/build/common.targets
@@ -5,6 +5,7 @@
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
+ <DefineConstants>$(DefineConstants);SMAPI_DEPRECATED</DefineConstants>
<!--enable nullable annotations, except in .NET Standard 2.0 where they aren't supported-->
<Nullable Condition="'$(TargetFramework)' != 'netstandard2.0'">enable</Nullable>
@@ -20,14 +21,17 @@
<!--
suppress warnings that don't apply, so it's easier to spot actual issues.
- warning | builds | summary | rationale
- ┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
- CS0436 | all | local type conflicts with imported type | SMAPI needs to use certain low-level code during very early compatibility checks, before it's safe to load any other DLLs.
- CA1416 | all | platform code available on all platforms | Compiler doesn't recognize the #if constants used by SMAPI.
- CS0809 | all | obsolete overload for non-onsolete member | This is deliberate to signal to mods that certain APIs are only implemented for the game and shouldn't be called by mods.
- NU1701 | all | NuGet package targets older .NET version | All such packages are carefully tested to make sure they do work.
+ warning | builds | summary | rationale
+ ┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
+ CS0436 | all | local type conflicts with imported type | SMAPI needs to use certain low-level code during very early compatibility checks, before it's safe to load any other DLLs.
+ CS0612 | deprecated | member is obsolete | internal references to deprecated code when deprecated code is enabled.
+ CS0618 | deprecated | member is obsolete (with message) | internal references to deprecated code when deprecated code is enabled.
+ CA1416 | all | platform code available on all platforms | Compiler doesn't recognize the #if constants used by SMAPI.
+ CS0809 | all | obsolete overload for non-obsolete member | This is deliberate to signal to mods that certain APIs are only implemented for the game and shouldn't be called by mods.
+ NU1701 | all | NuGet package targets older .NET version | All such packages are carefully tested to make sure they do work.
-->
- <NoWarn>$(NoWarn);CS0436;CA1416;CS0809;NU1701</NoWarn>
+ <NoWarn Condition="$(DefineConstants.Contains(SMAPI_DEPRECATED))">$(NoWarn);CS0612;CS0618</NoWarn>
+ <NoWarn>$(NoWarn);CS0436;CA1416;CS0809;NU1701</NoWarn>
</PropertyGroup>
<!--find game folder-->
diff --git a/docs/technical/smapi.md b/docs/technical/smapi.md
index 44b6e49f..90990ee4 100644
--- a/docs/technical/smapi.md
+++ b/docs/technical/smapi.md
@@ -62,6 +62,7 @@ SMAPI uses a small number of conditional compilation constants, which you can se
flag | purpose
---- | -------
`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled for Windows; if not set, the code assumes Linux/macOS. Set automatically in `common.targets`.
+`SMAPI_DEPRECATED` | Whether to include deprecated code in the build.
## Compile from source code
### Main project
diff --git a/src/SMAPI.Toolkit/Framework/ModData/ModWarning.cs b/src/SMAPI.Toolkit/Framework/ModData/ModWarning.cs
index 32c2ed6d..338192af 100644
--- a/src/SMAPI.Toolkit/Framework/ModData/ModWarning.cs
+++ b/src/SMAPI.Toolkit/Framework/ModData/ModWarning.cs
@@ -18,9 +18,11 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
/// <summary>The mod patches the game in a way that may impact stability.</summary>
PatchesGame = 4,
+#if SMAPI_FOR_WINDOWS
/// <summary>The mod uses the <c>dynamic</c> keyword which won't work on Linux/macOS.</summary>
[Obsolete("This value is no longer used by SMAPI and will be removed in the upcoming SMAPI 4.0.0.")]
UsesDynamic = 8,
+#endif
/// <summary>The mod references specialized 'unvalidated update tick' events which may impact stability.</summary>
UsesUnvalidatedUpdateTick = 16,
@@ -37,6 +39,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
/// <summary>Uses .NET APIs for shell or process access.</summary>
AccessesShell = 256,
+#if SMAPI_DEPRECATED
/// <summary>References the legacy <c>System.Configuration.ConfigurationManager</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary>
DetectedLegacyConfigurationDll = 512,
@@ -45,5 +48,6 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
/// <summary>References the legacy <c>System.Security.Permissions</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary>
DetectedLegacyPermissionsDll = 2048
+#endif
}
}
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index db88563e..33468717 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -6,7 +6,9 @@ using System.Reflection;
using Mono.Cecil;
using StardewModdingAPI.Enums;
using StardewModdingAPI.Framework;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework.Deprecations;
+#endif
using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Toolkit.Framework;
using StardewModdingAPI.Toolkit.Utilities;
@@ -77,6 +79,7 @@ namespace StardewModdingAPI
/// <summary>The game framework running the game.</summary>
public static GameFramework GameFramework { get; } = EarlyConstants.GameFramework;
+#if SMAPI_DEPRECATED
/// <summary>The path to the game folder.</summary>
[Obsolete($"Use {nameof(Constants)}.{nameof(GamePath)} instead. This property will be removed in SMAPI 4.0.0.")]
public static string ExecutionPath
@@ -93,6 +96,7 @@ namespace StardewModdingAPI
return Constants.GamePath;
}
}
+#endif
/// <summary>The path to the game folder.</summary>
public static string GamePath { get; } = EarlyConstants.GamePath;
diff --git a/src/SMAPI/Framework/Content/AssetInfo.cs b/src/SMAPI/Framework/Content/AssetInfo.cs
index 773e3126..43feed27 100644
--- a/src/SMAPI/Framework/Content/AssetInfo.cs
+++ b/src/SMAPI/Framework/Content/AssetInfo.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework.Deprecations;
+#endif
namespace StardewModdingAPI.Framework.Content
{
@@ -30,6 +32,10 @@ namespace StardewModdingAPI.Framework.Content
public IAssetName NameWithoutLocale => this.NameWithoutLocaleImpl ??= this.Name.GetBaseAssetName();
/// <inheritdoc />
+ public Type DataType { get; }
+
+#if SMAPI_DEPRECATED
+ /// <inheritdoc />
[Obsolete($"Use {nameof(AssetInfo.Name)} or {nameof(AssetInfo.NameWithoutLocale)} instead. This property will be removed in SMAPI 4.0.0.")]
public string AssetName
{
@@ -50,9 +56,7 @@ namespace StardewModdingAPI.Framework.Content
return this.NameWithoutLocale.Name;
}
}
-
- /// <inheritdoc />
- public Type DataType { get; }
+#endif
/*********
@@ -71,6 +75,7 @@ namespace StardewModdingAPI.Framework.Content
this.GetNormalizedPath = getNormalizedPath;
}
+#if SMAPI_DEPRECATED
/// <inheritdoc />
[Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} or {nameof(AssetInfo.NameWithoutLocale)}.{nameof(IAssetName.IsEquivalentTo)} instead. This method will be removed in SMAPI 4.0.0.")]
public bool AssetNameEquals(string path)
@@ -90,6 +95,7 @@ namespace StardewModdingAPI.Framework.Content
return this.NameWithoutLocale.IsEquivalentTo(path);
}
+#endif
/*********
diff --git a/src/SMAPI/Framework/Content/AssetInterceptorChange.cs b/src/SMAPI/Framework/Content/AssetInterceptorChange.cs
index f3d4f3f4..3b5068dc 100644
--- a/src/SMAPI/Framework/Content/AssetInterceptorChange.cs
+++ b/src/SMAPI/Framework/Content/AssetInterceptorChange.cs
@@ -1,8 +1,8 @@
+#if SMAPI_DEPRECATED
using System;
using System.Reflection;
using StardewModdingAPI.Internal;
-#pragma warning disable CS0618 // obsolete asset interceptors deliberately supported here
namespace StardewModdingAPI.Framework.Content
{
/// <summary>A wrapper for <see cref="IAssetEditor"/> and <see cref="IAssetLoader"/> for internal cache invalidation.</summary>
@@ -103,3 +103,4 @@ namespace StardewModdingAPI.Framework.Content
}
}
}
+#endif
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 3e09ac62..9e044b44 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -12,7 +12,9 @@ using StardewModdingAPI.Framework.Content;
using StardewModdingAPI.Framework.ContentManagers;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Utilities;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Internal;
+#endif
using StardewModdingAPI.Metadata;
using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Toolkit.Utilities.PathLookups;
@@ -84,6 +86,7 @@ namespace StardewModdingAPI.Framework
/// <summary>The cached asset load/edit operations to apply, indexed by asset name.</summary>
private readonly TickCacheDictionary<IAssetName, AssetOperationGroup?> AssetOperationsByKey = new();
+#if SMAPI_DEPRECATED
/// <summary>A cache of asset operation groups created for legacy <see cref="IAssetLoader"/> implementations.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
private readonly Dictionary<IAssetLoader, Dictionary<Type, AssetLoadOperation>> LegacyLoaderCache = new(ReferenceEqualityComparer.Instance);
@@ -91,6 +94,7 @@ namespace StardewModdingAPI.Framework
/// <summary>A cache of asset operation groups created for legacy <see cref="IAssetEditor"/> implementations.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
private readonly Dictionary<IAssetEditor, Dictionary<Type, AssetEditOperation>> LegacyEditorCache = new(ReferenceEqualityComparer.Instance);
+#endif
/*********
@@ -102,6 +106,7 @@ namespace StardewModdingAPI.Framework
/// <summary>The current language as a constant.</summary>
public LocalizedContentManager.LanguageCode Language => this.MainContentManager.Language;
+#if SMAPI_DEPRECATED
/// <summary>Interceptors which provide the initial versions of matching assets.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
public IList<ModLinked<IAssetLoader>> Loaders { get; } = new List<ModLinked<IAssetLoader>>();
@@ -109,6 +114,7 @@ namespace StardewModdingAPI.Framework
/// <summary>Interceptors which edit matching assets after they're loaded.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
public IList<ModLinked<IAssetEditor>> Editors { get; } = new List<ModLinked<IAssetEditor>>();
+#endif
/// <summary>The absolute path to the <see cref="ContentManager.RootDirectory"/>.</summary>
public string FullRootDirectory { get; }
@@ -498,15 +504,25 @@ namespace StardewModdingAPI.Framework
return invalidatedAssets.Keys;
}
+#if SMAPI_DEPRECATED
/// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now.</summary>
/// <typeparam name="T">The asset type.</typeparam>
/// <param name="info">The asset info to load or edit.</param>
public AssetOperationGroup? GetAssetOperations<T>(IAssetInfo info)
where T : notnull
+#else
+ /// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now.</summary>
+ /// <param name="info">The asset info to load or edit.</param>
+ public AssetOperationGroup? GetAssetOperations(IAssetInfo info)
+#endif
{
return this.AssetOperationsByKey.GetOrSet(
info.Name,
+#if SMAPI_DEPRECATED
() => this.GetAssetOperationsWithoutCache<T>(info)
+#else
+ () => this.RequestAssetOperations(info)
+#endif
);
}
@@ -629,6 +645,7 @@ namespace StardewModdingAPI.Framework
return map;
}
+#if SMAPI_DEPRECATED
/// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now, ignoring the <see cref="AssetOperationsByKey"/> cache.</summary>
/// <typeparam name="T">The asset type.</typeparam>
/// <param name="info">The asset info to load or edit.</param>
@@ -639,7 +656,6 @@ namespace StardewModdingAPI.Framework
AssetOperationGroup? group = this.RequestAssetOperations(info);
// legacy load operations
-#pragma warning disable CS0612, CS0618 // deprecated code
if (this.Editors.Count > 0 || this.Loaders.Count > 0)
{
IAssetInfo legacyInfo = this.GetLegacyAssetInfo(info);
@@ -738,7 +754,6 @@ namespace StardewModdingAPI.Framework
);
}
}
-#pragma warning restore CS0612, CS0618
return group;
}
@@ -818,5 +833,6 @@ namespace StardewModdingAPI.Framework
// else no change needed
return asset;
}
+#endif
}
}
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 446f4a67..df7bdc59 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -76,7 +76,11 @@ namespace StardewModdingAPI.Framework.ContentManagers
// custom asset from a loader
string locale = this.GetLocale();
IAssetInfo info = new AssetInfo(locale, assetName, typeof(T), this.AssertAndNormalizeAssetName);
- AssetOperationGroup? operations = this.Coordinator.GetAssetOperations<T>(info);
+ AssetOperationGroup? operations = this.Coordinator.GetAssetOperations
+#if SMAPI_DEPRECATED
+ <T>
+#endif
+ (info);
if (operations?.LoadOperations.Count > 0)
{
if (!this.AssertMaxOneRequiredLoader(info, operations.LoadOperations, out string? error))
@@ -129,7 +133,11 @@ namespace StardewModdingAPI.Framework.ContentManagers
data = this.AssetsBeingLoaded.Track(assetName.Name, () =>
{
IAssetInfo info = new AssetInfo(assetName.LocaleCode, assetName, typeof(T), this.AssertAndNormalizeAssetName);
- AssetOperationGroup? operations = this.Coordinator.GetAssetOperations<T>(info);
+ AssetOperationGroup? operations = this.Coordinator.GetAssetOperations
+#if SMAPI_DEPRECATED
+ <T>
+#endif
+ (info);
IAssetData asset =
this.ApplyLoader<T>(info, operations?.LoadOperations)
?? new AssetDataForObject(info, this.RawLoad<T>(assetName, useCache), this.AssertAndNormalizeAssetName, this.Reflection);
@@ -294,7 +302,11 @@ namespace StardewModdingAPI.Framework.ContentManagers
? $"Multiple mods want to provide the '{info.Name}' asset: {string.Join(", ", loaderNames)}"
: $"The '{loaderNames[0]}' mod wants to provide the '{info.Name}' asset multiple times";
- error = $"{errorPhrase}. An asset can't be loaded multiple times, so SMAPI will use the default asset instead. Uninstall one of the mods to fix this. (Message for modders: you should avoid {nameof(AssetLoadPriority)}.{nameof(AssetLoadPriority.Exclusive)} and {nameof(IAssetLoader)} if possible to avoid conflicts.)";
+ error = $"{errorPhrase}. An asset can't be loaded multiple times, so SMAPI will use the default asset instead. Uninstall one of the mods to fix this. (Message for modders: you should avoid {nameof(AssetLoadPriority)}.{nameof(AssetLoadPriority.Exclusive)}"
+#if SMAPI_DEPRECATED
+ + " and {nameof(IAssetLoader)}"
+#endif
+ + " if possible to avoid conflicts.)";
return false;
}
@@ -349,6 +361,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
// handle mismatch
if (loadedMap.TileSheets.Count <= vanillaSheet.Index || loadedMap.TileSheets[vanillaSheet.Index].Id != vanillaSheet.Id)
{
+#if SMAPI_DEPRECATED
// only show warning if not farm map
// This is temporary: mods shouldn't do this for any vanilla map, but these are the ones we know will crash. Showing a warning for others instead gives modders time to update their mods, while still simplifying troubleshooting.
bool isFarmMap = info.Name.IsEquivalentTo("Maps/Farm") || info.Name.IsEquivalentTo("Maps/Farm_Combat") || info.Name.IsEquivalentTo("Maps/Farm_Fishing") || info.Name.IsEquivalentTo("Maps/Farm_Foraging") || info.Name.IsEquivalentTo("Maps/Farm_FourCorners") || info.Name.IsEquivalentTo("Maps/Farm_Island") || info.Name.IsEquivalentTo("Maps/Farm_Mining");
@@ -361,7 +374,12 @@ namespace StardewModdingAPI.Framework.ContentManagers
mod.LogAsMod($"SMAPI blocked a '{info.Name}' map load: {reason}", LogLevel.Error);
return false;
}
+
mod.LogAsMod($"SMAPI found an issue with a '{info.Name}' map load: {reason}", LogLevel.Warn);
+#else
+ mod.LogAsMod($"SMAPI found an issue with a '{info.Name}' map load: {this.GetOnBehalfOfLabel(loader.OnBehalfOf, parenthetical: false) ?? "mod"} reordered the original tilesheets, which often causes crashes.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help.", LogLevel.Error);
+ return false;
+#endif
}
}
}
diff --git a/src/SMAPI/Framework/ContentPack.cs b/src/SMAPI/Framework/ContentPack.cs
index 70fe51f8..a1d977e4 100644
--- a/src/SMAPI/Framework/ContentPack.cs
+++ b/src/SMAPI/Framework/ContentPack.cs
@@ -96,6 +96,7 @@ namespace StardewModdingAPI.Framework
}
}
+#if SMAPI_DEPRECATED
/// <inheritdoc />
[Obsolete($"Use {nameof(IContentPack.ModContent)}.{nameof(IModContentHelper.Load)} instead. This method will be removed in SMAPI 4.0.0.")]
public T LoadAsset<T>(string key)
@@ -110,6 +111,7 @@ namespace StardewModdingAPI.Framework
{
return this.ModContent.GetInternalAssetName(key).Name;
}
+#endif
/*********
diff --git a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
index ddbd618a..21435f62 100644
--- a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs
@@ -1,5 +1,7 @@
using System;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework.Deprecations;
+#endif
namespace StardewModdingAPI.Framework.ModHelpers
{
@@ -32,6 +34,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
return this;
}
+#if SMAPI_DEPRECATED
/// <inheritdoc />
[Obsolete("Use mod-provided APIs to integrate with mods instead. This method will be removed in SMAPI 4.0.0.")]
public bool Trigger(string name, string[] arguments)
@@ -45,5 +48,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
return this.CommandManager.Trigger(name, arguments);
}
+#endif
}
}
diff --git a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs
index 427adac2..9992cb52 100644
--- a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs
@@ -1,3 +1,4 @@
+#if SMAPI_DEPRECATED
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -249,3 +250,4 @@ namespace StardewModdingAPI.Framework.ModHelpers
}
}
}
+#endif
diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs
index 48973691..9ac3b6f7 100644
--- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs
@@ -1,7 +1,9 @@
using System;
using System.IO;
using StardewModdingAPI.Events;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework.Deprecations;
+#endif
using StardewModdingAPI.Framework.Input;
namespace StardewModdingAPI.Framework.ModHelpers
@@ -9,12 +11,14 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>Provides simplified APIs for writing mods.</summary>
internal class ModHelper : BaseHelper, IModHelper, IDisposable
{
+#if SMAPI_DEPRECATED
/*********
** Fields
*********/
/// <summary>The backing field for <see cref="Content"/>.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
private readonly ContentHelper ContentImpl;
+#endif
/*********
@@ -26,6 +30,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <inheritdoc />
public IModEvents Events { get; }
+#if SMAPI_DEPRECATED
/// <inheritdoc />
[Obsolete($"Use {nameof(IGameContentHelper)} or {nameof(IModContentHelper)} instead.")]
public IContentHelper Content
@@ -42,6 +47,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
return this.ContentImpl;
}
}
+#endif
/// <inheritdoc />
public IGameContentHelper GameContent { get; }
@@ -82,7 +88,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="modDirectory">The full path to the mod's folder.</param>
/// <param name="currentInputState">Manages the game's input state for the current player instance. That may not be the main player in split-screen mode.</param>
/// <param name="events">Manages access to events raised by SMAPI.</param>
- /// <param name="contentHelper">An API for loading content assets.</param>
/// <param name="gameContentHelper">An API for loading content assets from the game's <c>Content</c> folder or via <see cref="IModEvents.Content"/>.</param>
/// <param name="modContentHelper">An API for loading content assets from your mod's files.</param>
/// <param name="contentPackHelper">An API for managing content packs.</param>
@@ -96,9 +101,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception>
public ModHelper(
IModMetadata mod, string modDirectory, Func<SInputState> currentInputState, IModEvents events,
-#pragma warning disable CS0612 // deprecated code
+#if SMAPI_DEPRECATED
ContentHelper contentHelper,
-#pragma warning restore CS0612
+#endif
IGameContentHelper gameContentHelper, IModContentHelper modContentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper
)
: base(mod)
@@ -111,9 +116,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
// initialize
this.DirectoryPath = modDirectory;
-#pragma warning disable CS0612 // deprecated code
+#if SMAPI_DEPRECATED
this.ContentImpl = contentHelper ?? throw new ArgumentNullException(nameof(contentHelper));
-#pragma warning restore CS0612
+#endif
this.GameContent = gameContentHelper ?? throw new ArgumentNullException(nameof(gameContentHelper));
this.ModContent = modContentHelper ?? throw new ArgumentNullException(nameof(modContentHelper));
this.ContentPacks = contentPackHelper ?? throw new ArgumentNullException(nameof(contentPackHelper));
@@ -127,12 +132,14 @@ namespace StardewModdingAPI.Framework.ModHelpers
this.Events = events;
}
+#if SMAPI_DEPRECATED
/// <summary>Get the underlying instance for <see cref="IContentHelper"/>.</summary>
[Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")]
public ContentHelper GetLegacyContentHelper()
{
return this.ContentImpl;
}
+#endif
/****
** Mod config file
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index e5aaa8ee..eb940c41 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -163,6 +163,7 @@ namespace StardewModdingAPI.Framework.ModLoading
this.AssemblyDefinitionResolver.Add(assembly.Definition);
}
+#if SMAPI_DEPRECATED
// special case: clear legacy-DLL warnings if the mod bundles a copy
if (mod.Warnings.HasFlag(ModWarning.DetectedLegacyCachingDll))
{
@@ -185,6 +186,7 @@ namespace StardewModdingAPI.Framework.ModLoading
if (File.Exists(Path.Combine(mod.DirectoryPath, "System.Security.Permissions.dll")))
mod.RemoveWarning(ModWarning.DetectedLegacyPermissionsDll);
}
+#endif
// throw if incompatibilities detected
if (!assumeCompatible && mod.Warnings.HasFlag(ModWarning.BrokenCodeLoaded))
@@ -452,6 +454,7 @@ namespace StardewModdingAPI.Framework.ModLoading
mod.SetWarning(ModWarning.AccessesShell);
break;
+#if SMAPI_DEPRECATED
case InstructionHandleResult.DetectedLegacyCachingDll:
template = $"{logPrefix}Detected reference to System.Runtime.Caching.dll, which will be removed in SMAPI 4.0.0.";
mod.SetWarning(ModWarning.DetectedLegacyCachingDll);
@@ -466,6 +469,7 @@ namespace StardewModdingAPI.Framework.ModLoading
template = $"{logPrefix}Detected reference to System.Security.Permissions.dll, which will be removed in SMAPI 4.0.0.";
mod.SetWarning(ModWarning.DetectedLegacyPermissionsDll);
break;
+#endif
case InstructionHandleResult.None:
break;
diff --git a/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs
index d3437b05..77380907 100644
--- a/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs
+++ b/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs
@@ -1,3 +1,4 @@
+#if SMAPI_DEPRECATED
using Mono.Cecil;
using StardewModdingAPI.Framework.ModLoading.Framework;
@@ -47,3 +48,4 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
}
}
}
+#endif
diff --git a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs
index 476c30d0..189ca64e 100644
--- a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs
+++ b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs
@@ -32,6 +32,7 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>The instruction accesses the OS shell or processes directly.</summary>
DetectedShellAccess,
+#if SMAPI_DEPRECATED
/// <summary>The module references the legacy <c>System.Configuration.ConfigurationManager</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary>
DetectedLegacyConfigurationDll,
@@ -40,5 +41,6 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>The module references the legacy <c>System.Security.Permissions</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary>
DetectedLegacyPermissionsDll
+#endif
}
}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 385a94ea..ff3eadf5 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -32,7 +32,9 @@ using StardewModdingAPI.Framework.Networking;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Rendering;
using StardewModdingAPI.Framework.Serialization;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework.StateTracking.Comparers;
+#endif
using StardewModdingAPI.Framework.StateTracking.Snapshots;
using StardewModdingAPI.Framework.Utilities;
using StardewModdingAPI.Internal;
@@ -139,8 +141,10 @@ namespace StardewModdingAPI.Framework
/// <summary>The maximum number of consecutive attempts SMAPI should make to recover from an update error.</summary>
private readonly Countdown UpdateCrashTimer = new(60); // 60 ticks = roughly one second
+#if SMAPI_DEPRECATED
/// <summary>Asset interceptors added or removed since the last tick.</summary>
private readonly List<AssetInterceptorChange> ReloadAssetInterceptorsQueue = new();
+#endif
/// <summary>A list of queued commands to parse and execute.</summary>
/// <remarks>This property must be thread-safe, since it's accessed from a separate console input thread.</remarks>
@@ -483,6 +487,7 @@ namespace StardewModdingAPI.Framework
return;
}
+#if SMAPI_DEPRECATED
/*********
** Reload assets when interceptors are added/removed
*********/
@@ -515,6 +520,7 @@ namespace StardewModdingAPI.Framework
// reload affected assets
this.ContentCore.InvalidateCache(asset => interceptors.Any(p => p.CanIntercept(asset)));
}
+#endif
/*********
** Parse commands
@@ -1646,9 +1652,9 @@ namespace StardewModdingAPI.Framework
// initialize loaded non-content-pack mods
this.Monitor.Log("Launching mods...", LogLevel.Debug);
-#pragma warning disable CS0612, CS0618 // deprecated code
foreach (IModMetadata metadata in loadedMods)
{
+#if SMAPI_DEPRECATED
// add interceptors
if (metadata.Mod?.Helper is ModHelper helper)
{
@@ -1684,7 +1690,6 @@ namespace StardewModdingAPI.Framework
content.ObservableAssetEditors.CollectionChanged += (_, e) => this.OnAssetInterceptorsChanged(metadata, e.NewItems?.Cast<IAssetEditor>(), e.OldItems?.Cast<IAssetEditor>(), this.ContentCore.Editors);
content.ObservableAssetLoaders.CollectionChanged += (_, e) => this.OnAssetInterceptorsChanged(metadata, e.NewItems?.Cast<IAssetLoader>(), e.OldItems?.Cast<IAssetLoader>(), this.ContentCore.Loaders);
}
-#pragma warning restore CS0612, CS0618
// log deprecation warnings
if (metadata.HasWarnings(ModWarning.DetectedLegacyCachingDll, ModWarning.DetectedLegacyConfigurationDll, ModWarning.DetectedLegacyPermissionsDll))
@@ -1710,6 +1715,7 @@ namespace StardewModdingAPI.Framework
);
}
}
+#endif
// call entry method
Context.HeuristicModsRunningCode.Push(metadata);
@@ -1750,6 +1756,7 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log("Mods loaded and ready!", LogLevel.Debug);
}
+#if SMAPI_DEPRECATED
/// <summary>Raised after a mod adds or removes asset interceptors.</summary>
/// <typeparam name="T">The asset interceptor type (one of <see cref="IAssetEditor"/> or <see cref="IAssetLoader"/>).</typeparam>
/// <param name="mod">The mod metadata.</param>
@@ -1772,6 +1779,7 @@ namespace StardewModdingAPI.Framework
list.Remove(entry);
}
}
+#endif
/// <summary>Load a given mod.</summary>
/// <param name="mod">The mod to load.</param>
@@ -1915,9 +1923,9 @@ namespace StardewModdingAPI.Framework
{
IModEvents events = new ModEvents(mod, this.EventManager);
ICommandHelper commandHelper = new CommandHelper(mod, this.CommandManager);
-#pragma warning disable CS0612 // deprecated code
+#if SMAPI_DEPRECATED
ContentHelper contentHelper = new(contentCore, mod.DirectoryPath, mod, monitor, this.Reflection);
-#pragma warning restore CS0612
+#endif
GameContentHelper gameContentHelper = new(contentCore, mod, mod.DisplayName, monitor, this.Reflection);
IModContentHelper modContentHelper = new ModContentHelper(contentCore, mod.DirectoryPath, mod, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), this.Reflection);
IContentPackHelper contentPackHelper = new ContentPackHelper(
@@ -1930,7 +1938,11 @@ namespace StardewModdingAPI.Framework
IModRegistry modRegistryHelper = new ModRegistryHelper(mod, this.ModRegistry, proxyFactory, monitor);
IMultiplayerHelper multiplayerHelper = new MultiplayerHelper(mod, this.Multiplayer);
- modHelper = new ModHelper(mod, mod.DirectoryPath, () => this.GetCurrentGameInstance().Input, events, contentHelper, gameContentHelper, modContentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
+ modHelper = new ModHelper(mod, mod.DirectoryPath, () => this.GetCurrentGameInstance().Input, events,
+#if SMAPI_DEPRECATED
+ contentHelper,
+#endif
+ gameContentHelper, modContentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
}
// init mod
diff --git a/src/SMAPI/GameFramework.cs b/src/SMAPI/GameFramework.cs
index 60fbe56e..009865fe 100644
--- a/src/SMAPI/GameFramework.cs
+++ b/src/SMAPI/GameFramework.cs
@@ -1,13 +1,17 @@
+#if SMAPI_DEPRECATED
using System;
+#endif
namespace StardewModdingAPI
{
/// <summary>The game framework running the game.</summary>
public enum GameFramework
{
+#if SMAPI_DEPRECATED
/// <summary>The XNA Framework, previously used on Windows.</summary>
[Obsolete("Stardew Valley no longer uses XNA Framework on any supported platform. This value will be removed in SMAPI 4.0.0.")]
Xna,
+#endif
/// <summary>The MonoGame framework.</summary>
MonoGame
diff --git a/src/SMAPI/IAssetEditor.cs b/src/SMAPI/IAssetEditor.cs
index 9f22ed83..f3238ba9 100644
--- a/src/SMAPI/IAssetEditor.cs
+++ b/src/SMAPI/IAssetEditor.cs
@@ -1,3 +1,4 @@
+#if SMAPI_DEPRECATED
using System;
using StardewModdingAPI.Events;
@@ -19,3 +20,4 @@ namespace StardewModdingAPI
void Edit<T>(IAssetData asset);
}
}
+#endif
diff --git a/src/SMAPI/IAssetInfo.cs b/src/SMAPI/IAssetInfo.cs
index 44fd91a5..20064946 100644
--- a/src/SMAPI/IAssetInfo.cs
+++ b/src/SMAPI/IAssetInfo.cs
@@ -8,25 +8,34 @@ namespace StardewModdingAPI
/*********
** Accessors
*********/
+#if SMAPI_DEPRECATED
/// <summary>The content's locale code, if the content is localized.</summary>
/// <remarks>LEGACY NOTE: when reading this field from an <see cref="IAssetLoader"/> or <see cref="IAssetEditor"/> implementation, for non-localized assets it will return the current game locale (or an empty string for English) instead of null.</remarks>
+#else
+ /// <summary>The content's locale code, if the content is localized.</summary>
+#endif
string? Locale { get; }
+#if SMAPI_DEPRECATED
/// <summary>The asset name being read.</summary>
/// <remarks>LEGACY NOTE: when reading this field from an <see cref="IAssetLoader"/> or <see cref="IAssetEditor"/> implementation, it's always equivalent to <see cref="NameWithoutLocale"/> for backwards compatibility.</remarks>
+#else
+ /// <summary>The asset name being read.</summary>
+#endif
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 content data type.</summary>
+ Type DataType { get; }
+
+#if SMAPI_DEPRECATED
/// <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)} or {nameof(NameWithoutLocale)} instead. This property will be removed in SMAPI 4.0.0.")]
string AssetName { get; }
- /// <summary>The content data type.</summary>
- Type DataType { get; }
-
/*********
** Public methods
@@ -35,5 +44,6 @@ namespace StardewModdingAPI
/// <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)} or {nameof(NameWithoutLocale)}.{nameof(IAssetName.IsEquivalentTo)} instead. This method will be removed in SMAPI 4.0.0.")]
bool AssetNameEquals(string path);
+#endif
}
}
diff --git a/src/SMAPI/IAssetLoader.cs b/src/SMAPI/IAssetLoader.cs
index 96b98793..205980a7 100644
--- a/src/SMAPI/IAssetLoader.cs
+++ b/src/SMAPI/IAssetLoader.cs
@@ -1,3 +1,4 @@
+#if SMAPI_DEPRECATED
using System;
using StardewModdingAPI.Events;
@@ -19,3 +20,4 @@ namespace StardewModdingAPI
T Load<T>(IAssetInfo asset);
}
}
+#endif
diff --git a/src/SMAPI/ICommandHelper.cs b/src/SMAPI/ICommandHelper.cs
index 9f1c345c..c92a09c2 100644
--- a/src/SMAPI/ICommandHelper.cs
+++ b/src/SMAPI/ICommandHelper.cs
@@ -17,11 +17,13 @@ namespace StardewModdingAPI
/// <exception cref="ArgumentException">There's already a command with that name.</exception>
ICommandHelper Add(string name, string documentation, Action<string, string[]> callback);
+#if SMAPI_DEPRECATED
/// <summary>Trigger a command.</summary>
/// <param name="name">The command name.</param>
/// <param name="arguments">The command arguments.</param>
/// <returns>Returns whether a matching command was triggered.</returns>
[Obsolete("Use mod-provided APIs to integrate with mods instead. This method will be removed in SMAPI 4.0.0.")]
bool Trigger(string name, string[] arguments);
+#endif
}
}
diff --git a/src/SMAPI/IContentHelper.cs b/src/SMAPI/IContentHelper.cs
index 7637edf0..b0e30a82 100644
--- a/src/SMAPI/IContentHelper.cs
+++ b/src/SMAPI/IContentHelper.cs
@@ -1,3 +1,4 @@
+#if SMAPI_DEPRECATED
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
@@ -80,3 +81,4 @@ namespace StardewModdingAPI
where T : notnull;
}
}
+#endif
diff --git a/src/SMAPI/IContentPack.cs b/src/SMAPI/IContentPack.cs
index 73b1a860..5047b172 100644
--- a/src/SMAPI/IContentPack.cs
+++ b/src/SMAPI/IContentPack.cs
@@ -1,7 +1,9 @@
using System;
+#if SMAPI_DEPRECATED
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using xTile;
+#endif
namespace StardewModdingAPI
{
@@ -47,6 +49,7 @@ namespace StardewModdingAPI
void WriteJsonFile<TModel>(string path, TModel data)
where TModel : class;
+#if SMAPI_DEPRECATED
/// <summary>Load content from the content pack folder (if not already cached), and return it. When loading a <c>.png</c> file, this must be called outside the game's draw loop.</summary>
/// <typeparam name="T">The expected data type. The main supported types are <see cref="Map"/>, <see cref="Texture2D"/>, <see cref="IRawTextureData"/>, and data structures; other types may be supported by the game's content pipeline.</typeparam>
/// <param name="key">The relative file path within the content pack (case-insensitive).</param>
@@ -61,5 +64,6 @@ namespace StardewModdingAPI
/// <exception cref="ArgumentException">The <paramref name="key"/> is empty or contains invalid characters.</exception>
[Obsolete($"Use {nameof(IContentPack.ModContent)}.{nameof(IModContentHelper.GetInternalAssetName)} instead. This method will be removed in SMAPI 4.0.0.")]
string GetActualAssetKey(string key);
+#endif
}
}
diff --git a/src/SMAPI/IModHelper.cs b/src/SMAPI/IModHelper.cs
index 15e4ed8d..a44d92c1 100644
--- a/src/SMAPI/IModHelper.cs
+++ b/src/SMAPI/IModHelper.cs
@@ -1,4 +1,6 @@
+#if SMAPI_DEPRECATED
using System;
+#endif
using StardewModdingAPI.Events;
namespace StardewModdingAPI
@@ -25,9 +27,11 @@ namespace StardewModdingAPI
/// <remarks>This API is intended for reading content assets from the mod files (like game data, images, etc); see also <see cref="Data"/> which is intended for persisting internal mod data.</remarks>
IModContentHelper ModContent { get; }
+#if SMAPI_DEPRECATED
/// <summary>An API for loading content assets.</summary>
[Obsolete($"Use {nameof(IGameContentHelper)} or {nameof(IModContentHelper)} instead.")]
IContentHelper Content { get; }
+#endif
/// <summary>An API for managing content packs.</summary>
IContentPackHelper ContentPacks { get; }
diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs
index dce0c6b1..efa91d20 100644
--- a/src/SMAPI/Metadata/InstructionMetadata.cs
+++ b/src/SMAPI/Metadata/InstructionMetadata.cs
@@ -54,8 +54,10 @@ namespace StardewModdingAPI.Metadata
// detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update)
yield return new HarmonyRewriter();
+#if SMAPI_DEPRECATED
// detect issues for SMAPI 4.0.0
yield return new LegacyAssemblyFinder();
+#endif
}
else
yield return new HarmonyRewriter(shouldRewrite: false);
diff --git a/src/SMAPI/Utilities/PerScreen.cs b/src/SMAPI/Utilities/PerScreen.cs
index b86310b8..54657ade 100644
--- a/src/SMAPI/Utilities/PerScreen.cs
+++ b/src/SMAPI/Utilities/PerScreen.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
+#if SMAPI_DEPRECATED
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Deprecations;
+#endif
namespace StardewModdingAPI.Utilities
{
@@ -41,12 +43,31 @@ namespace StardewModdingAPI.Utilities
/// <summary>Construct an instance.</summary>
/// <remarks><strong>Limitation with nullable reference types:</strong> when the underlying type <typeparamref name="T"/> is nullable, this sets the default value to null regardless of whether you marked the type parameter nullable. To avoid that, set the default value with the 'createNewState' argument instead.</remarks>
public PerScreen()
- : this(null, nullExpected: true) { }
+ {
+ this.CreateNewState = (() => default!);
+ }
/// <summary>Construct an instance.</summary>
/// <param name="createNewState">Create the initial state for a screen.</param>
public PerScreen(Func<T> createNewState)
- : this(createNewState, nullExpected: false) { }
+ {
+ if (createNewState is null)
+ {
+#if SMAPI_DEPRECATED
+ createNewState = (() => default!);
+ SCore.DeprecationManager.Warn(
+ null,
+ $"calling the {nameof(PerScreen<T>)} constructor with null",
+ "3.14.0",
+ DeprecationLevel.Notice
+ );
+#else
+ throw new ArgumentNullException(nameof(createNewState));
+#endif
+ }
+
+ this.CreateNewState = createNewState;
+ }
/// <summary>Get all active values by screen ID. This doesn't initialize the value for a screen ID if it's not created yet.</summary>
public IEnumerable<KeyValuePair<int, T>> GetActiveValues()
@@ -84,30 +105,6 @@ namespace StardewModdingAPI.Utilities
/*********
** Private methods
*********/
- /// <summary>Construct an instance.</summary>
- /// <param name="createNewState">Create the initial state for a screen.</param>
- /// <param name="nullExpected">Whether a null <paramref name="createNewState"/> value is expected.</param>
- /// <remarks>This constructor only exists to maintain backwards compatibility. In SMAPI 4.0.0, the overload that passes <c>nullExpected: false</c> should throw an exception instead.</remarks>
- private PerScreen(Func<T>? createNewState, bool nullExpected)
- {
- if (createNewState is null)
- {
- createNewState = (() => default!);
-
- if (!nullExpected)
- {
- SCore.DeprecationManager.Warn(
- null,
- $"calling the {nameof(PerScreen<T>)} constructor with null",
- "3.14.0",
- DeprecationLevel.Notice
- );
- }
- }
-
- this.CreateNewState = createNewState;
- }
-
/// <summary>Remove screens which are no longer active.</summary>
private void RemoveDeadScreens()
{