// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
using UnityEngine;
using System;
using System.Runtime.CompilerServices;
using Object = UnityEngine.Object;
namespace Animancer
{
///
/// A which holds a
/// based on its .
///
/// https://kybernetik.com.au/animancer/api/Animancer/StringAsset
[AnimancerHelpUrl(typeof(StringAsset))]
[CreateAssetMenu(
menuName = Strings.MenuPrefix + "String Asset",
order = Strings.AssetMenuOrder + 2)]
public class StringAsset : ScriptableObject,
IComparable,
IConvertable,
IConvertable,
IEquatable,
IEquatable,
IEquatable,
IHasKey
{
/************************************************************************************************************************/
private StringReference _Name;
/// A to the .
///
/// This value is gathered when first accessed, but will not be automatically updated after that
/// because doing so causes some garbage allocation (except in the Unity Editor for convenience).
///
public StringReference Name
{
#if UNITY_EDITOR
// Don't do this at runtime because it allocates garbage every time.
// But in the Unity Editor things could get renamed at any time.
get => _Name = this ? name : "";
#else
get => _Name ??= name;
#endif
set => _Name = name = value;
}
///
public object Key
=> Name;
/************************************************************************************************************************/
#region Equality
/************************************************************************************************************************/
/// Compares the s.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Compare(StringAsset a, StringAsset b)
=> a == b
? 0
: a
? a.CompareTo(b)
: -1;
/// Compares the s.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(StringAsset other)
=> other
? Name.String.CompareTo(other.Name.String)
: 1;
/************************************************************************************************************************/
/// Is the equal to the `other`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(StringAsset other)
=> other is not null
&& Name == other.Name;
/// Is the equal to the `other`?
/// Uses .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(StringReference other)
=> Name == other;
/// Is the equal to the `value`?
/// Checks regular string equality because the `value` might not be interned.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(string value)
=> Name.String == value;
/// Is the equal to the `other`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object other)
{
if (other is StringAsset asset)
return Equals(asset);
if (other is StringReference reference)
return Equals(reference);
if (other is string value)
return Equals(value);
return false;
}
/************************************************************************************************************************/
/// Are the s equal?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(StringAsset a, StringAsset b)
=> a is null
? b is null
: a.Equals(b);
/// Are the s not equal?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(StringAsset a, StringAsset b)
=> a is null
? b is not null
: !a.Equals(b);
/************************************************************************************************************************/
/// Is the equal to `b`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(StringAsset a, StringReference b)
=> a?.Name == b;
/// Is the not equal to `b`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(StringAsset a, StringReference b)
=> a?.Name != b;
/// Is the equal to `a`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(StringReference a, StringAsset b)
=> a == b?.Name;
/// Is the not equal to `a`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(StringReference a, StringAsset b)
=> a != b?.Name;
/************************************************************************************************************************/
/// Is the equal to `b`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(StringAsset a, string b)
=> a?.Name.String == b;
/// Is the not equal to `b`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(StringAsset a, string b)
=> a?.Name.String != b;
/// Is the equal to `a`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(string a, StringAsset b)
=> b?.Name.String == a;
/// Is the not equal to `a`?
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(string a, StringAsset b)
=> b?.Name.String != a;
/************************************************************************************************************************/
/// Returns the hash code of the .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
=> Name.GetHashCode();
/************************************************************************************************************************/
#endregion
/************************************************************************************************************************/
#region Conversion
/************************************************************************************************************************/
/// Returns the .
public override string ToString()
=> Name;
///
StringReference IConvertable.Convert()
=> Name;
///
string IConvertable.Convert()
=> Name;
/************************************************************************************************************************/
/// Returns the .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator string(StringAsset key)
=> key?.Name;
/// Returns the .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator StringReference(StringAsset key)
=> key?.Name;
/************************************************************************************************************************/
/// Creates a new array containing the s.
public static StringReference[] ToStringReferences(params StringAsset[] keys)
{
if (keys == null)
return null;
if (keys.Length == 0)
return Array.Empty();
var strings = new StringReference[keys.Length];
for (int i = 0; i < keys.Length; i++)
strings[i] = keys[i];
return strings;
}
/// Creates a new array containing the s.
public static string[] ToStrings(params StringAsset[] keys)
{
if (keys == null)
return null;
if (keys.Length == 0)
return Array.Empty();
var strings = new string[keys.Length];
for (int i = 0; i < keys.Length; i++)
strings[i] = keys[i];
return strings;
}
/************************************************************************************************************************/
#endregion
/************************************************************************************************************************/
#if UNITY_EDITOR
/************************************************************************************************************************/
[Tooltip("An unused Editor-Only field where you can explain what this asset is used for")]
[SerializeField, TextArea(2, 25)]
private string _EditorComment;
/// [Editor-Only] []
/// An unused Editor-Only field where you can explain what this asset is used for.
///
public ref string EditorComment
=> ref _EditorComment;
/************************************************************************************************************************/
#endif
}
}