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); } } }