mirror of
https://github.com/Pathoschild/SMAPI.git
synced 2026-10-12 02:08:51 +00:00
split up extension files
This commit is contained in:
@@ -9,6 +9,7 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
using StardewModdingAPI.Web.Framework;
|
||||
using StardewModdingAPI.Web.Framework.Extensions;
|
||||
using StardewModdingAPI.Web.Framework.Storage;
|
||||
using StardewModdingAPI.Web.ViewModels.JsonValidator;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using StardewModdingAPI.Web.Framework;
|
||||
using StardewModdingAPI.Web.Framework.Extensions;
|
||||
using StardewModdingAPI.Web.Framework.LogParsing;
|
||||
using StardewModdingAPI.Web.Framework.LogParsing.Models;
|
||||
using StardewModdingAPI.Web.Framework.Storage;
|
||||
|
||||
@@ -23,6 +23,7 @@ using StardewModdingAPI.Web.Framework.Clients.ModDrop;
|
||||
using StardewModdingAPI.Web.Framework.Clients.Nexus;
|
||||
using StardewModdingAPI.Web.Framework.Clients.UpdateManifest;
|
||||
using StardewModdingAPI.Web.Framework.ConfigModels;
|
||||
using StardewModdingAPI.Web.Framework.Extensions;
|
||||
using StardewModdingAPI.Web.Framework.Metrics;
|
||||
|
||||
namespace StardewModdingAPI.Web.Controllers;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StardewModdingAPI.Web.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides extensions for <see cref="RazorPageBase"/>.</summary>
|
||||
public static class RazorPageBaseExtensions
|
||||
{
|
||||
/// <param name="page">The page to extend.</param>
|
||||
extension(RazorPageBase page)
|
||||
{
|
||||
/// <summary>Get a serialized JSON representation of the value.</summary>
|
||||
/// <param name="value">The value to serialize.</param>
|
||||
/// <returns>The serialized JSON.</returns>
|
||||
/// <remarks>This bypasses unnecessary validation (e.g. not allowing null values) in <see cref="IJsonHelper.Serialize"/>.</remarks>
|
||||
public IHtmlContent ForJson(object? value)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(value);
|
||||
return new HtmlString(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-27
@@ -1,24 +1,14 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StardewModdingAPI.Web.Framework;
|
||||
namespace StardewModdingAPI.Web.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides extensions on ASP.NET Core types.</summary>
|
||||
public static class Extensions
|
||||
/// <summary>Provides extensions for <see cref="IUrlHelper"/>.</summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/****
|
||||
** View helpers
|
||||
****/
|
||||
/// <param name="helper">The URL helper to extend.</param>
|
||||
extension(IUrlHelper helper)
|
||||
{
|
||||
@@ -60,18 +50,4 @@ public static class Extensions
|
||||
return helper.Content($"{url}{delimiter}v={Program.CacheBustValue}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <param name="page">The page to extend.</param>
|
||||
extension(RazorPageBase page)
|
||||
{
|
||||
/// <summary>Get a serialized JSON representation of the value.</summary>
|
||||
/// <param name="value">The value to serialize.</param>
|
||||
/// <returns>The serialized JSON.</returns>
|
||||
/// <remarks>This bypasses unnecessary validation (e.g. not allowing null values) in <see cref="IJsonHelper.Serialize"/>.</remarks>
|
||||
public IHtmlContent ForJson(object? value)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(value);
|
||||
return new HtmlString(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@model StardewModdingAPI.Web.ViewModels.IndexModel
|
||||
@{
|
||||
ViewData["Title"] = "SMAPI";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@{
|
||||
ViewData["Title"] = "SMAPI privacy notes";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@using Humanizer
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@using StardewModdingAPI.Web.ViewModels.JsonValidator
|
||||
@model JsonValidatorModel
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@using Humanizer
|
||||
@using StardewModdingAPI.Toolkit.Utilities
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@using StardewModdingAPI.Web.Framework.LogParsing.Models
|
||||
@using StardewModdingAPI.Web.ViewModels
|
||||
@model StardewModdingAPI.Web.ViewModels.LogParserModel
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@using Humanizer
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@model StardewModdingAPI.Web.ViewModels.ModListModel
|
||||
@{
|
||||
ViewData["Title"] = "Mod compatibility";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@using Microsoft.Extensions.Options
|
||||
@using StardewModdingAPI.Web.Framework
|
||||
@using StardewModdingAPI.Web.Framework.ConfigModels
|
||||
@using StardewModdingAPI.Web.Framework.Extensions
|
||||
@inject IOptions<SiteConfig> SiteConfig
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Buffers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Content;
|
||||
|
||||
@@ -11,6 +11,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.Content;
|
||||
using StardewModdingAPI.Framework.ContentManagers;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Framework.Utilities;
|
||||
using StardewModdingAPI.Metadata;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Framework.Content;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewValley;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.Content;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Framework.Utilities;
|
||||
using StardewModdingAPI.Internal;
|
||||
|
||||
@@ -12,6 +12,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using SkiaSharp;
|
||||
using StardewModdingAPI.Framework.Content;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Internal;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Events;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using StardewValley.Menus;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="IClickableMenu"/>.</summary>
|
||||
internal static class ClickableMenuExtensions
|
||||
{
|
||||
/// <param name="menu">The clickable menu to extend.</param>
|
||||
extension(IClickableMenu menu)
|
||||
{
|
||||
/// <summary>Get a string representation of the menu chain to the given menu (including the specified menu), in parent to child order.</summary>
|
||||
public string GetMenuChainLabel()
|
||||
{
|
||||
static IEnumerable<IClickableMenu> GetAncestors(IClickableMenu menu)
|
||||
{
|
||||
for (; menu != null; menu = menu.GetParentMenu())
|
||||
yield return menu;
|
||||
}
|
||||
|
||||
return string.Join(" > ", GetAncestors(menu).Reverse().Select(p => p.GetType().FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using StardewModdingAPI.Framework.Events;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="ManagedEvent{T}"/>.</summary>
|
||||
internal static class ManagedEventExtensions
|
||||
{
|
||||
/// <typeparam name="TEventArgs">The event args type to construct.</typeparam>
|
||||
/// <param name="event">The event to extend.</param>
|
||||
extension<TEventArgs>(ManagedEvent<TEventArgs> @event)
|
||||
where TEventArgs : new()
|
||||
{
|
||||
/// <summary>Raise the event using the default event args and notify all handlers.</summary>
|
||||
public void RaiseEmpty()
|
||||
{
|
||||
if (@event.HasListeners)
|
||||
@event.Raise(Singleton<TEventArgs>.Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="IModMetadata"/>.</summary>
|
||||
internal static class ModMetadataExtensions
|
||||
{
|
||||
/// <param name="metadata">The mod metadata to extend.</param>
|
||||
extension(IModMetadata metadata)
|
||||
{
|
||||
/// <summary>Log a message using the mod's monitor.</summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogAsMod(string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
if (metadata.Monitor is null)
|
||||
throw new InvalidOperationException($"Can't log as mod {metadata.DisplayName}: mod is broken or a content pack. Logged message:\n[{level}] {message}");
|
||||
|
||||
metadata.Monitor.Log(message, level);
|
||||
}
|
||||
|
||||
/// <summary>Log a message using the mod's monitor, but only if it hasn't already been logged since the last game launch.</summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogAsModOnce(string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
metadata.Monitor?.LogOnce(message, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="IMonitor"/>.</summary>
|
||||
internal static class MonitorExtensions
|
||||
{
|
||||
/// <param name="monitor">The monitor to extend.</param>
|
||||
extension(IMonitor monitor)
|
||||
{
|
||||
/// <summary>Log a message for the player or developer the first time it occurs.</summary>
|
||||
/// <param name="hash">The hash of logged messages.</param>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogOnce(HashSet<string> hash, string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
if (!hash.Contains(message))
|
||||
{
|
||||
monitor.Log(message, level);
|
||||
hash.Add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="ReaderWriterLockSlim"/>.</summary>
|
||||
internal static class ReaderWriterLockSlimExtensions
|
||||
{
|
||||
/// <param name="lock">The lock to extend.</param>
|
||||
extension(ReaderWriterLockSlim @lock)
|
||||
{
|
||||
/// <summary>Run code within a read lock.</summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public void InReadLock(Action action)
|
||||
{
|
||||
@lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a read lock.</summary>
|
||||
/// <typeparam name="TReturn">The action's return value.</typeparam>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public TReturn InReadLock<TReturn>(Func<TReturn> action)
|
||||
{
|
||||
@lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a write lock.</summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public void InWriteLock(Action action)
|
||||
{
|
||||
@lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a write lock.</summary>
|
||||
/// <typeparam name="TReturn">The action's return value.</typeparam>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public TReturn InWriteLock<TReturn>(Func<TReturn> action)
|
||||
{
|
||||
@lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="SpriteBatch"/>.</summary>
|
||||
internal static class SpriteBatchExtensions
|
||||
{
|
||||
/// <param name="spriteBatch">The sprite batch to extend.</param>
|
||||
extension(SpriteBatch spriteBatch)
|
||||
{
|
||||
/// <summary>Get whether the sprite batch is between a begin and end pair.</summary>
|
||||
/// <param name="reflection">The reflection helper with which to access private fields.</param>
|
||||
public bool IsOpen(Reflector reflection)
|
||||
{
|
||||
return reflection.GetField<bool>(spriteBatch, "_beginCalled").GetValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace StardewModdingAPI.Framework.Extensions;
|
||||
|
||||
/// <summary>Provides internal extensions for <see cref="Texture2D"/>.</summary>
|
||||
internal static class Texture2dExtensions
|
||||
{
|
||||
/// <param name="texture">The texture to extend.</param>
|
||||
extension(Texture2D? texture)
|
||||
{
|
||||
/// <summary>Set the texture name field.</summary>
|
||||
/// <param name="assetName">The asset name to set.</param>
|
||||
/// <returns>Returns the texture for chaining.</returns>
|
||||
[return: NotNullIfNotNull(nameof(texture))]
|
||||
public Texture2D? SetName(IAssetName assetName)
|
||||
{
|
||||
texture?.Name = assetName.Name;
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/// <summary>Set the texture name field.</summary>
|
||||
/// <param name="assetName">The asset name to set.</param>
|
||||
/// <returns>Returns the texture for chaining.</returns>
|
||||
[return: NotNullIfNotNull(nameof(texture))]
|
||||
public Texture2D? SetName(string assetName)
|
||||
{
|
||||
texture?.Name = assetName;
|
||||
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Framework.Events;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewValley.Menus;
|
||||
|
||||
namespace StardewModdingAPI.Framework;
|
||||
|
||||
/// <summary>Provides extension methods for SMAPI's internal use.</summary>
|
||||
internal static class InternalExtensions
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/****
|
||||
** IMonitor
|
||||
****/
|
||||
/// <param name="monitor">The monitor to extend.</param>
|
||||
extension(IMonitor monitor)
|
||||
{
|
||||
/// <summary>Log a message for the player or developer the first time it occurs.</summary>
|
||||
/// <param name="hash">The hash of logged messages.</param>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogOnce(HashSet<string> hash, string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
if (!hash.Contains(message))
|
||||
{
|
||||
monitor.Log(message, level);
|
||||
hash.Add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** IModMetadata
|
||||
****/
|
||||
/// <param name="metadata">The mod metadata to extend.</param>
|
||||
extension(IModMetadata metadata)
|
||||
{
|
||||
/// <summary>Log a message using the mod's monitor.</summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogAsMod(string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
if (metadata.Monitor is null)
|
||||
throw new InvalidOperationException($"Can't log as mod {metadata.DisplayName}: mod is broken or a content pack. Logged message:\n[{level}] {message}");
|
||||
|
||||
metadata.Monitor.Log(message, level);
|
||||
}
|
||||
|
||||
/// <summary>Log a message using the mod's monitor, but only if it hasn't already been logged since the last game launch.</summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log severity level.</param>
|
||||
public void LogAsModOnce(string message, LogLevel level = LogLevel.Trace)
|
||||
{
|
||||
metadata.Monitor?.LogOnce(message, level);
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** ManagedEvent
|
||||
****/
|
||||
/// <typeparam name="TEventArgs">The event args type to construct.</typeparam>
|
||||
/// <param name="event">The event to extend.</param>
|
||||
extension<TEventArgs>(ManagedEvent<TEventArgs> @event)
|
||||
where TEventArgs : new()
|
||||
{
|
||||
/// <summary>Raise the event using the default event args and notify all handlers.</summary>
|
||||
public void RaiseEmpty()
|
||||
{
|
||||
if (@event.HasListeners)
|
||||
@event.Raise(Singleton<TEventArgs>.Instance);
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** ReaderWriterLockSlim
|
||||
****/
|
||||
/// <param name="lock">The lock to extend.</param>
|
||||
extension(ReaderWriterLockSlim @lock)
|
||||
{
|
||||
/// <summary>Run code within a read lock.</summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public void InReadLock(Action action)
|
||||
{
|
||||
@lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a read lock.</summary>
|
||||
/// <typeparam name="TReturn">The action's return value.</typeparam>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public TReturn InReadLock<TReturn>(Func<TReturn> action)
|
||||
{
|
||||
@lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a write lock.</summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public void InWriteLock(Action action)
|
||||
{
|
||||
@lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Run code within a write lock.</summary>
|
||||
/// <typeparam name="TReturn">The action's return value.</typeparam>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
public TReturn InWriteLock<TReturn>(Func<TReturn> action)
|
||||
{
|
||||
@lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
@lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** IActiveClickableMenu
|
||||
****/
|
||||
/// <param name="menu">The clickable menu to extend.</param>
|
||||
extension(IClickableMenu menu)
|
||||
{
|
||||
/// <summary>Get a string representation of the menu chain to the given menu (including the specified menu), in parent to child order.</summary>
|
||||
public string GetMenuChainLabel()
|
||||
{
|
||||
static IEnumerable<IClickableMenu> GetAncestors(IClickableMenu menu)
|
||||
{
|
||||
for (; menu != null; menu = menu.GetParentMenu())
|
||||
yield return menu;
|
||||
}
|
||||
|
||||
return string.Join(" > ", GetAncestors(menu).Reverse().Select(p => p.GetType().FullName));
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** Sprite batch
|
||||
****/
|
||||
/// <param name="spriteBatch">The sprite batch to extend.</param>
|
||||
extension(SpriteBatch spriteBatch)
|
||||
{
|
||||
/// <summary>Get whether the sprite batch is between a begin and end pair.</summary>
|
||||
/// <param name="reflection">The reflection helper with which to access private fields.</param>
|
||||
public bool IsOpen(Reflector reflection)
|
||||
{
|
||||
return reflection.GetField<bool>(spriteBatch, "_beginCalled").GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** Texture2D
|
||||
****/
|
||||
/// <param name="texture">The texture to extend.</param>
|
||||
extension(Texture2D? texture)
|
||||
{
|
||||
/// <summary>Set the texture name field.</summary>
|
||||
/// <param name="assetName">The asset name to set.</param>
|
||||
/// <returns>Returns the texture for chaining.</returns>
|
||||
[return: NotNullIfNotNull(nameof(texture))]
|
||||
public Texture2D? SetName(IAssetName assetName)
|
||||
{
|
||||
texture?.Name = assetName.Name;
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/// <summary>Set the texture name field.</summary>
|
||||
/// <param name="assetName">The asset name to set.</param>
|
||||
/// <returns>Returns the texture for chaining.</returns>
|
||||
[return: NotNullIfNotNull(nameof(texture))]
|
||||
public Texture2D? SetName(string assetName)
|
||||
{
|
||||
texture?.Name = assetName;
|
||||
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using System.Reflection;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.ModLoading.Framework;
|
||||
using StardewModdingAPI.Framework.ModLoading.Symbols;
|
||||
using StardewModdingAPI.Metadata;
|
||||
|
||||
@@ -26,6 +26,7 @@ using StardewModdingAPI.Framework.ContentManagers;
|
||||
using StardewModdingAPI.Framework.Deprecations;
|
||||
using StardewModdingAPI.Framework.Events;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Input;
|
||||
using StardewModdingAPI.Framework.Logging;
|
||||
using StardewModdingAPI.Framework.Models;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Enums;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Framework.Input;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Framework.Rendering;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Enums;
|
||||
using StardewModdingAPI.Framework.Extensions;
|
||||
using StardewModdingAPI.Internal;
|
||||
using StardewModdingAPI.Utilities;
|
||||
using StardewValley;
|
||||
|
||||
Reference in New Issue
Block a user