// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Animancer
{
/// [Pro-Only] An object that can be updated during Animancer's animation updates.
///
///
/// Example:
/// Register to receive updates using or
/// and stop
/// receiving updates using or
/// .
///
/// public sealed class MyUpdatable : IUpdatable
/// {
/// // Implement IUpdatable.
/// // You can avoid this by inheriting from Updatable instead.
/// int IUpdatable.UpdatableIndex { get; set; } = IUpdatable.List.NotInList;
///
/// private AnimancerComponent _Animancer;
///
/// public void StartUpdating(AnimancerComponent animancer)
/// {
/// _Animancer = animancer;
///
/// // If you want Update to be called before the playables get updated.
/// _Animancer.Graph.RequirePreUpdate(this);
///
/// // If you want Update to be called after the playables get updated.
/// _Animancer.Graph.RequirePostUpdate(this);
/// }
///
/// public void StopUpdating()
/// {
/// // If you used RequirePreUpdate.
/// _Animancer.Graph.CancelPreUpdate(this);
///
/// // If you used RequirePostUpdate.
/// _Animancer.Graph.CancelPostUpdate(this);
/// }
///
/// void IUpdatable.Update()
/// {
/// // Called during every animation update.
///
/// // AnimancerGraph.Current can be used to access the system it is being updated by.
/// }
/// }
///
///
/// https://kybernetik.com.au/animancer/api/Animancer/IUpdatable
///
public interface IUpdatable
{
/************************************************************************************************************************/
/// The index of this object in its .
/// Should be initialized to -1 to indicate that this object is not yet in a list.
int UpdatableIndex { get; set; }
/// Updates this object.
void Update();
/************************************************************************************************************************/
/// An for .
public readonly struct Indexer : IIndexer
{
/************************************************************************************************************************/
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int GetIndex(IUpdatable item)
=> item.UpdatableIndex;
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void SetIndex(IUpdatable item, int index)
=> item.UpdatableIndex = index;
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void ClearIndex(IUpdatable item)
=> item.UpdatableIndex = -1;
/************************************************************************************************************************/
}
/************************************************************************************************************************/
/// An of .
public class List : IndexedList
{
/************************************************************************************************************************/
/// The default for newly created lists.
/// Default value is 4.
public static new int DefaultCapacity { get; set; } = 4;
/************************************************************************************************************************/
/// Creates a new with the .
public List()
: base(DefaultCapacity, new())
{ }
/************************************************************************************************************************/
/// Calls on all items in this list.
///
/// Uses to handle exceptions and continues executing
/// the remaining items if any occur.
///
public void UpdateAll()
{
BeginEnumeraton();
ContinueEnumeration:
try
{
while (TryEnumerateNext())
{
Current.Update();
}
}
catch (Exception exception)
{
Debug.LogException(exception, AnimancerGraph.Current?.Component as Object);
goto ContinueEnumeration;
}
}
/************************************************************************************************************************/
/// Clones any items.
public void CloneFrom(
List copyFrom,
CloneContext context)
{
var count = copyFrom.Count;
for (int i = 0; i < count; i++)
if (copyFrom[i] is ICloneable