/*
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;
}
}
}
}