use specified nullability in reflection API (#837)
This commit is contained in:
parent
c0d0ad0282
commit
2dc20be5f7
|
@ -98,7 +98,7 @@ 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.");
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <param name="reflection">The reflection helper with which to access private fields.</param>
|
||||
public static bool IsOpen(this SpriteBatch spriteBatch, Reflector reflection)
|
||||
{
|
||||
return reflection.GetField<bool>(spriteBatch, "_beginCalled")!.GetValue();
|
||||
return reflection.GetField<bool>(spriteBatch, "_beginCalled").GetValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace StardewModdingAPI.Framework
|
|||
this.Mods.Add(metadata);
|
||||
}
|
||||
|
||||
/// <summary>Track a mod's assembly for use via <see cref="GetFrom"/>.</summary>
|
||||
/// <summary>Track a mod's assembly for use via <see cref="GetFrom(Type?)"/>.</summary>
|
||||
/// <param name="metadata">The mod metadata.</param>
|
||||
/// <param name="modAssembly">The mod assembly.</param>
|
||||
public void TrackAssemblies(IModMetadata metadata, Assembly modAssembly)
|
||||
|
|
|
@ -56,11 +56,11 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public TValue? GetValue()
|
||||
public TValue GetValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (TValue?)this.FieldInfo.GetValue(this.Parent);
|
||||
return (TValue)this.FieldInfo.GetValue(this.Parent)!;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetValue(TValue? value)
|
||||
public void SetValue(TValue value)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public TValue? Invoke<TValue>(params object?[] arguments)
|
||||
public TValue Invoke<TValue>(params object?[] arguments)
|
||||
{
|
||||
// invoke method
|
||||
object? result;
|
||||
|
@ -75,7 +75,7 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
// cast return value
|
||||
try
|
||||
{
|
||||
return (TValue?)result;
|
||||
return (TValue)result!;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
|
|
|
@ -14,10 +14,10 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
private readonly string DisplayName;
|
||||
|
||||
/// <summary>The underlying property getter.</summary>
|
||||
private readonly Func<TValue?>? GetMethod;
|
||||
private readonly Func<TValue>? GetMethod;
|
||||
|
||||
/// <summary>The underlying property setter.</summary>
|
||||
private readonly Action<TValue?>? SetMethod;
|
||||
private readonly Action<TValue>? SetMethod;
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -56,13 +56,13 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
this.PropertyInfo = property;
|
||||
|
||||
if (this.PropertyInfo.GetMethod != null)
|
||||
this.GetMethod = (Func<TValue?>)Delegate.CreateDelegate(typeof(Func<TValue?>), obj, this.PropertyInfo.GetMethod);
|
||||
this.GetMethod = (Func<TValue>)Delegate.CreateDelegate(typeof(Func<TValue>), obj, this.PropertyInfo.GetMethod);
|
||||
if (this.PropertyInfo.SetMethod != null)
|
||||
this.SetMethod = (Action<TValue?>)Delegate.CreateDelegate(typeof(Action<TValue?>), obj, this.PropertyInfo.SetMethod);
|
||||
this.SetMethod = (Action<TValue>)Delegate.CreateDelegate(typeof(Action<TValue>), obj, this.PropertyInfo.SetMethod);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public TValue? GetValue()
|
||||
public TValue GetValue()
|
||||
{
|
||||
if (this.GetMethod == null)
|
||||
throw new InvalidOperationException($"The {this.DisplayName} property has no get method.");
|
||||
|
@ -82,7 +82,7 @@ namespace StardewModdingAPI.Framework.Reflection
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetValue(TValue? value)
|
||||
public void SetValue(TValue value)
|
||||
{
|
||||
if (this.SetMethod == null)
|
||||
throw new InvalidOperationException($"The {this.DisplayName} property has no set method.");
|
||||
|
|
|
@ -113,13 +113,13 @@ namespace StardewModdingAPI.Framework
|
|||
{
|
||||
case LidgrenClient:
|
||||
{
|
||||
string address = this.Reflection.GetField<string>(client, "address").GetValue() ?? throw new InvalidOperationException("Can't initialize base networking client: no valid address found.");
|
||||
string address = this.Reflection.GetField<string?>(client, "address").GetValue() ?? throw new InvalidOperationException("Can't initialize base networking client: no valid address found.");
|
||||
return new SLidgrenClient(address, this.OnClientProcessingMessage, this.OnClientSendingMessage);
|
||||
}
|
||||
|
||||
case GalaxyNetClient:
|
||||
{
|
||||
GalaxyID address = this.Reflection.GetField<GalaxyID>(client, "lobbyId").GetValue() ?? throw new InvalidOperationException("Can't initialize GOG networking client: no valid address found.");
|
||||
GalaxyID address = this.Reflection.GetField<GalaxyID?>(client, "lobbyId").GetValue() ?? throw new InvalidOperationException("Can't initialize GOG networking client: no valid address found.");
|
||||
return new SGalaxyNetClient(address, this.OnClientProcessingMessage, this.OnClientSendingMessage);
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ namespace StardewModdingAPI.Framework
|
|||
{
|
||||
case LidgrenServer:
|
||||
{
|
||||
IGameServer gameServer = this.Reflection.GetField<IGameServer>(server, "gameServer").GetValue() ?? throw new InvalidOperationException("Can't initialize base networking client: the required 'gameServer' field wasn't found.");
|
||||
IGameServer gameServer = this.Reflection.GetField<IGameServer?>(server, "gameServer").GetValue() ?? throw new InvalidOperationException("Can't initialize base networking client: the required 'gameServer' field wasn't found.");
|
||||
return new SLidgrenServer(gameServer, this, this.OnServerProcessingMessage);
|
||||
}
|
||||
|
||||
case GalaxyNetServer:
|
||||
{
|
||||
IGameServer gameServer = this.Reflection.GetField<IGameServer>(server, "gameServer").GetValue() ?? throw new InvalidOperationException("Can't initialize GOG networking client: the required 'gameServer' field wasn't found.");
|
||||
IGameServer gameServer = this.Reflection.GetField<IGameServer?>(server, "gameServer").GetValue() ?? throw new InvalidOperationException("Can't initialize GOG networking client: the required 'gameServer' field wasn't found.");
|
||||
return new SGalaxyNetServer(gameServer, this, this.OnServerProcessingMessage);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ namespace StardewModdingAPI
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Get the field value.</summary>
|
||||
TValue? GetValue();
|
||||
TValue GetValue();
|
||||
|
||||
/// <summary>Set the field value.</summary>
|
||||
//// <param name="value">The value to set.</param>
|
||||
void SetValue(TValue? value);
|
||||
void SetValue(TValue value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace StardewModdingAPI
|
|||
/// <summary>Invoke the method.</summary>
|
||||
/// <typeparam name="TValue">The return type.</typeparam>
|
||||
/// <param name="arguments">The method arguments to pass in.</param>
|
||||
TValue? Invoke<TValue>(params object?[] arguments);
|
||||
TValue Invoke<TValue>(params object?[] arguments);
|
||||
|
||||
/// <summary>Invoke the method.</summary>
|
||||
/// <param name="arguments">The method arguments to pass in.</param>
|
||||
|
|
|
@ -17,10 +17,10 @@ namespace StardewModdingAPI
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Get the property value.</summary>
|
||||
TValue? GetValue();
|
||||
TValue GetValue();
|
||||
|
||||
/// <summary>Set the property value.</summary>
|
||||
//// <param name="value">The value to set.</param>
|
||||
void SetValue(TValue? value);
|
||||
void SetValue(TValue value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -806,7 +806,7 @@ namespace StardewModdingAPI.Metadata
|
|||
if (door?.Sprite == null)
|
||||
continue;
|
||||
|
||||
string? curKey = this.Reflection.GetField<string>(door.Sprite, "textureName").GetValue();
|
||||
string? curKey = this.Reflection.GetField<string?>(door.Sprite, "textureName").GetValue();
|
||||
if (this.IsSameBaseName(assetName, curKey))
|
||||
door.Sprite.texture = texture.Value;
|
||||
}
|
||||
|
@ -1002,7 +1002,7 @@ namespace StardewModdingAPI.Metadata
|
|||
GameLocation adventureGuild = Game1.getLocationFromName("AdventureGuild");
|
||||
if (adventureGuild != null)
|
||||
{
|
||||
NPC? gil = this.Reflection.GetField<NPC>(adventureGuild, "Gil").GetValue();
|
||||
NPC? gil = this.Reflection.GetField<NPC?>(adventureGuild, "Gil").GetValue();
|
||||
if (gil != null)
|
||||
characters.Add(new { Npc = gil, AssetName = gilKey });
|
||||
}
|
||||
|
@ -1031,7 +1031,7 @@ namespace StardewModdingAPI.Metadata
|
|||
|
||||
foreach (Farmer player in players)
|
||||
{
|
||||
this.Reflection.GetField<Dictionary<string, Dictionary<int, List<int>>>>(typeof(FarmerRenderer), "_recolorOffsets").GetValue()?.Remove(player.getTexture());
|
||||
this.Reflection.GetField<Dictionary<string, Dictionary<int, List<int>>>?>(typeof(FarmerRenderer), "_recolorOffsets").GetValue()?.Remove(player.getTexture());
|
||||
player.FarmerRenderer.MarkSpriteDirty();
|
||||
}
|
||||
|
||||
|
@ -1049,14 +1049,18 @@ namespace StardewModdingAPI.Metadata
|
|||
foreach (GameLocation location in this.GetLocations(buildingInteriors: false))
|
||||
{
|
||||
// get suspension bridges field
|
||||
var field = this.Reflection.GetField<IEnumerable<SuspensionBridge>>(location, nameof(IslandNorth.suspensionBridges), required: false);
|
||||
var field = this.Reflection.GetField<IEnumerable<SuspensionBridge>?>(location, nameof(IslandNorth.suspensionBridges), required: false);
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse -- field is nullable when required: false
|
||||
if (field == null || !typeof(IEnumerable<SuspensionBridge>).IsAssignableFrom(field.FieldInfo.FieldType))
|
||||
continue;
|
||||
|
||||
// update textures
|
||||
foreach (SuspensionBridge bridge in field.GetValue()!)
|
||||
this.Reflection.GetField<Texture2D>(bridge, "_texture").SetValue(texture.Value);
|
||||
IEnumerable<SuspensionBridge>? bridges = field.GetValue();
|
||||
if (bridges != null)
|
||||
{
|
||||
foreach (SuspensionBridge bridge in bridges)
|
||||
this.Reflection.GetField<Texture2D>(bridge, "_texture").SetValue(texture.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return texture.IsValueCreated;
|
||||
|
@ -1134,7 +1138,7 @@ namespace StardewModdingAPI.Metadata
|
|||
{
|
||||
// reload schedule
|
||||
this.Reflection.GetField<bool>(villager, "_hasLoadedMasterScheduleData").SetValue(false);
|
||||
this.Reflection.GetField<Dictionary<string, string>>(villager, "_masterScheduleData").SetValue(null);
|
||||
this.Reflection.GetField<Dictionary<string, string>?>(villager, "_masterScheduleData").SetValue(null);
|
||||
villager.Schedule = villager.getSchedule(Game1.dayOfMonth);
|
||||
|
||||
// switch to new schedule if needed
|
||||
|
@ -1161,7 +1165,7 @@ namespace StardewModdingAPI.Metadata
|
|||
Game1.samBandName = content.LoadString("Strings/StringsFromCSFiles:Game1.cs.2156");
|
||||
Game1.elliottBookName = content.LoadString("Strings/StringsFromCSFiles:Game1.cs.2157");
|
||||
|
||||
string[] dayNames = this.Reflection.GetField<string[]>(typeof(Game1), "_shortDayDisplayName").GetValue()!;
|
||||
string[] dayNames = this.Reflection.GetField<string[]>(typeof(Game1), "_shortDayDisplayName").GetValue();
|
||||
dayNames[0] = content.LoadString("Strings/StringsFromCSFiles:Game1.cs.3042");
|
||||
dayNames[1] = content.LoadString("Strings/StringsFromCSFiles:Game1.cs.3043");
|
||||
dayNames[2] = content.LoadString("Strings/StringsFromCSFiles:Game1.cs.3044");
|
||||
|
|
Loading…
Reference in New Issue