/* Yarn Spinner is licensed to you under the terms found in the file LICENSE.md. */ using System; using Yarn.Utility; #nullable enable namespace Yarn.Unity { /// /// An interface that works with to add helper methods used /// by generated variable storage classes. /// /// /// classes that implement this interface are /// extended with the methods found in . This interface is intended /// to be used only with classes in source code that was generated by Yarn /// Spinner. /// public interface IGeneratedVariableStorage : Yarn.IVariableStorage { } public static class GeneratedVariableStorageExtensions { /// /// Gets a value for the variable from /// , or else returns the default value of /// . /// /// The type of the parameter to get a value /// for. /// The generated variable storage class to get /// the value from. /// The name of the variable to get a value /// for. /// The value of , or the /// default value of /// . public static T? GetValueOrDefault(this IGeneratedVariableStorage storage, string variableName) where T : IConvertible { if (storage.TryGetValue(variableName, out T? result)) { return result; } else { UnityEngine.Debug.Log($"Failed to get a value of type {typeof(T)} for variable {variableName}."); return default(T); } } public static void SetValue(this IGeneratedVariableStorage storage, string v, T value) where T : IConvertible { switch (value) { case string stringValue: storage.SetValue(v, stringValue); break; case float floatValue: storage.SetValue(v, floatValue); break; case bool boolValue: storage.SetValue(v, boolValue); break; default: throw new ArgumentOutOfRangeException("Unhandled value type " + value.GetType()); } } public static T? GetEnumValueOrDefault(this IGeneratedVariableStorage storage, string variableName) where T : System.Enum { if (!storage.TryGetValue(variableName, out object? result)) { UnityEngine.Debug.LogError($"Failed to get a value of type {typeof(T).Name} for variable {variableName}."); return default; } int caseValue; if (result is string stringResult) { // Convert the string value to a hash caseValue = (int)CRC32.GetChecksum(stringResult); } else if (result is float floatResult) { caseValue = (int)floatResult; } else if (result is int intResult) { caseValue = intResult; } else { UnityEngine.Debug.LogError($"Failed to get a value of type {typeof(T).Name} for variable {variableName}: received an unexpected variable type {result.GetType()} from variable storage"); return default; } if (Enum.IsDefined(typeof(T), caseValue)) { return (T)Enum.ToObject(typeof(T), caseValue); } else { UnityEngine.Debug.LogError($"Failed to get a value of type {typeof(T)} for variable {variableName}: ${caseValue} is not a valid case value."); return default; } } } }