using System;
namespace StardewModdingAPI.Framework.Content
{
/// Base implementation for a content helper which encapsulates access and changes to content being read from a data file.
/// The interface value type.
internal class AssetData : AssetInfo, IAssetData
{
/*********
** Fields
*********/
/// A callback to invoke when the data is replaced (if any).
private readonly Action OnDataReplaced;
/*********
** Accessors
*********/
/// The content data being read.
public TValue Data { get; protected set; }
/*********
** Public methods
*********/
/// Construct an instance.
/// The content's locale code, if the content is localised.
/// The normalised asset name being read.
/// The content data being read.
/// Normalises an asset key to match the cache key.
/// A callback to invoke when the data is replaced (if any).
public AssetData(string locale, string assetName, TValue data, Func getNormalisedPath, Action onDataReplaced)
: base(locale, assetName, data.GetType(), getNormalisedPath)
{
this.Data = data;
this.OnDataReplaced = onDataReplaced;
}
/// Replace the entire content value with the given value. This is generally not recommended, since it may break compatibility with other mods or different versions of the game.
/// The new content value.
/// The is null.
/// The 's type is not compatible with the loaded asset's type.
public void ReplaceWith(TValue value)
{
if (value == null)
throw new ArgumentNullException(nameof(value), "Can't set a loaded asset to a null value.");
if (!this.DataType.IsInstanceOfType(value))
throw new InvalidCastException($"Can't replace loaded asset of type {this.GetFriendlyTypeName(this.DataType)} with value of type {this.GetFriendlyTypeName(value.GetType())}. The new type must be compatible to prevent game errors.");
this.Data = value;
this.OnDataReplaced?.Invoke(value);
}
}
}