// MIT License - Copyright (c) 2023 wallstop
// Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE
namespace WallstopStudios.UnityHelpers.Utils
{
using System;
using System.Collections.Generic;
using UnityEngine;
using WallstopStudios.UnityHelpers.Core.Helper;
///
/// Provides value and ordering comparisons for instances and
/// offers helpers for duplicating them without mutating the original event.
///
///
/// Unity does not expose an implementation for
/// . This comparer inspects the fields Unity uses for dispatching
/// events (time, function name, parameters, and message options) and treats two events as equal
/// only when all of those values match.
///
public sealed class AnimationEventEqualityComparer
: EqualityComparer,
IComparer
{
///
/// Gets a globally shared comparer instance to avoid unnecessary allocations.
///
public static readonly AnimationEventEqualityComparer Instance = new();
private AnimationEventEqualityComparer() { }
///
/// Creates a shallow copy of the supplied by cloning its
/// equatable values.
///
/// Event instance to duplicate, or null to skip copying.
/// A new carrying the same values, or null.
public AnimationEvent Copy(AnimationEvent instance)
{
if (instance == null)
{
return null;
}
AnimationEvent copy = new();
CopyInto(copy, instance);
return copy;
}
///
/// Copies all equatable values from into
/// without creating a new .
///
/// Destination instance that receives the values.
/// Source instance that provides the values.
public void CopyInto(AnimationEvent into, AnimationEvent parameters)
{
if (into == null || parameters == null)
{
return;
}
into.time = parameters.time;
into.functionName = parameters.functionName;
into.intParameter = parameters.intParameter;
into.floatParameter = parameters.floatParameter;
into.stringParameter = parameters.stringParameter;
into.objectReferenceParameter = parameters.objectReferenceParameter;
into.messageOptions = parameters.messageOptions;
}
///
public override bool Equals(AnimationEvent lhs, AnimationEvent rhs)
{
if (ReferenceEquals(lhs, rhs))
{
return true;
}
if (lhs == null || rhs == null)
{
return false;
}
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (lhs.time != rhs.time)
{
return false;
}
if (lhs.functionName != rhs.functionName)
{
return false;
}
if (lhs.intParameter != rhs.intParameter)
{
return false;
}
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (lhs.floatParameter != rhs.floatParameter)
{
return false;
}
if (lhs.stringParameter != rhs.stringParameter)
{
return false;
}
if (lhs.objectReferenceParameter != rhs.objectReferenceParameter)
{
return false;
}
if (lhs.messageOptions != rhs.messageOptions)
{
return false;
}
return true;
}
///
public override int GetHashCode(AnimationEvent instance)
{
return Objects.HashCode(
instance.time,
instance.functionName,
instance.intParameter,
instance.floatParameter,
instance.stringParameter,
instance.objectReferenceParameter,
instance.messageOptions
);
}
///
/// Orders two instances using their firing time followed by the
/// textual and numeric parameters.
///
/// First event to compare.
/// Second event to compare.
///
/// An integer less than zero when should come before
/// , zero when they are equivalent, or greater than zero otherwise.
///
public int Compare(AnimationEvent lhs, AnimationEvent rhs)
{
if (ReferenceEquals(lhs, rhs))
{
return 0;
}
if (ReferenceEquals(null, rhs))
{
return 1;
}
if (ReferenceEquals(null, lhs))
{
return -1;
}
int timeComparison = lhs.time.CompareTo(rhs.time);
if (timeComparison != 0)
{
return timeComparison;
}
int functionNameComparison = string.Compare(
lhs.functionName,
rhs.functionName,
StringComparison.Ordinal
);
if (functionNameComparison != 0)
{
return functionNameComparison;
}
int intParameterComparison = lhs.intParameter.CompareTo(rhs.intParameter);
if (intParameterComparison != 0)
{
return intParameterComparison;
}
int stringParameterComparison = string.Compare(
lhs.stringParameter,
rhs.stringParameter,
StringComparison.Ordinal
);
if (stringParameterComparison != 0)
{
return stringParameterComparison;
}
return lhs.floatParameter.CompareTo(rhs.floatParameter);
}
}
}