using System; using UnityEngine.InputSystem.Utilities; namespace UnityEngine.XR.Interaction.Toolkit.Inputs.Simulation.Hands { /// /// A name for a hand expression in the XR Interaction Simulator. /// This struct wraps the struct from the Input System to allow for strings to be compared by reference /// for better performance. /// When compared, the strings are case-insensitive and culture-insensitive. /// When converting back to a string, the original casing will be preserved. /// readonly struct HandExpressionName : IEquatable { /// /// The name for a default hand name, represents a natural resting hand shape. /// public static readonly HandExpressionName Default = new HandExpressionName("Default"); readonly InternedString m_InternedString; /// /// Constructs a new name from a string value to be used with the XR Interaction Simulator. /// This allows for strings to be compared by reference and will only allocate memory if the string is not already interned. /// /// The string value for the name. public HandExpressionName(string value) { m_InternedString = new InternedString(value); } /// /// Compares the name to another object. The strings used when creating the names are compared case-insensitive and culture-insensitive. /// If the other object is not another , this will always return false. /// Otherwise this will compare the interned strings for equality, avoiding a costly string comparison. /// /// The other object to compare with. /// True if the other object is a name with the same string value ignoring case and culture. Otherwise false. public override bool Equals(object obj) { if (obj is HandExpressionName name) return Equals(name); return false; } /// /// Compares the name to another name. The strings used when creating the names are compared case-insensitive and culture-insensitive. /// This compares the interned strings for equality, avoiding a costly string comparison. /// /// The other name to compare with. /// True if the other name has the same string value, ignoring case and culture. Otherwise false. public bool Equals(HandExpressionName other) { return m_InternedString.Equals(other.m_InternedString); } /// /// Converts the name to a string. This will preserve the original casing of the string. /// /// The original string used to create the name. public override string ToString() { return m_InternedString.ToString(); } /// public override int GetHashCode() { return m_InternedString.GetHashCode(); } /// /// Compares two names for equality using the == operator. /// /// The left-hand side of the == operator. /// The right-hand side of the == operator. /// True if the other name has the same string value, ignoring case and culture. Otherwise false. public static bool operator ==(HandExpressionName lhs, HandExpressionName rhs) { return lhs.m_InternedString == rhs.m_InternedString; } /// /// Compares two names for inequality using the != operator. /// /// The left-hand side of the != operator. /// The right-hand side of the != operator. /// True if the other name has a different string value, ignoring case and culture. Otherwise false. public static bool operator !=(HandExpressionName lhs, HandExpressionName rhs) { return lhs.m_InternedString != rhs.m_InternedString; } /// /// Implicitly converts the name to a string. This will preserve the original casing of the string. /// /// The name that contains the string value. /// The original string used to create the name. public static implicit operator string(HandExpressionName value) { return value.m_InternedString.ToString(); } /// /// Implicitly converts a string to a name. /// /// The string value for the name. /// The name object that contains the string that can be compared while avoiding costly string comparison. public static implicit operator HandExpressionName(string value) { return new HandExpressionName(value); } } }