1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- using System.Collections.Generic;
- namespace Animancer.FSM
- {
- /// <summary>An object with a <see cref="Priority"/>.</summary>
- /// <remarks>
- /// <strong>Documentation:</strong>
- /// <see href="https://kybernetik.com.au/animancer/docs/manual/fsm/utilities#state-selectors">
- /// State Selectors</see>
- /// </remarks>
- /// https://kybernetik.com.au/animancer/api/Animancer.FSM/IPrioritizable
- ///
- public interface IPrioritizable : IState
- {
- float Priority { get; }
- }
- /************************************************************************************************************************/
- public partial class StateMachine<TState>
- {
- /// <summary>A prioritised list of potential states for a <see cref="StateMachine{TState}"/> to enter.</summary>
- ///
- /// <remarks>
- /// <strong>Documentation:</strong>
- /// <see href="https://kybernetik.com.au/animancer/docs/manual/fsm#state-selectors">
- /// State Selectors</see>
- /// <para></para>
- /// <strong>Example:</strong><code>
- /// public StateMachine<CharacterState> stateMachine;
- /// public CharacterState run;
- /// public CharacterState idle;
- ///
- /// private readonly StateMachine<CharacterState>.StateSelector
- /// Selector = new();
- ///
- /// private void Awake()
- /// {
- /// Selector.Add(1, run);
- /// Selector.Add(0, idle);
- /// }
- ///
- /// public void RunOrIdle()
- /// {
- /// stateMachine.TrySetState(Selector.Values);
- /// // The "run" state has the highest priority so this will enter it if "run.CanEnterState" returns true.
- /// // Otherwise if "idle.CanEnterState" returns true it will enter that state instead.
- /// // If neither allows the transition, nothing happens and "stateMachine.TrySetState" returns false.
- /// }
- /// </code></remarks>
- ///
- /// https://kybernetik.com.au/animancer/api/Animancer.FSM/StateSelector
- ///
- public class StateSelector : SortedList<float, TState>
- {
- public StateSelector() : base(ReverseComparer<float>.Instance) { }
- /// <summary>Adds the `state` to this selector with its <see cref="IPrioritizable.Priority"/>.</summary>
- public void Add<TPrioritizable>(TPrioritizable state)
- where TPrioritizable : TState, IPrioritizable
- => Add(state.Priority, state);
- }
- }
- /************************************************************************************************************************/
- /// <summary>An <see cref="IComparer{T}"/> which reverses the default comparison.</summary>
- /// https://kybernetik.com.au/animancer/api/Animancer.FSM/ReverseComparer_1
- public class ReverseComparer<T> : IComparer<T>
- {
- /// <summary>The singleton instance.</summary>
- public static readonly ReverseComparer<T> Instance = new();
- /// <summary>No need to let users create other instances.</summary>
- private ReverseComparer() { }
- /// <summary>Uses <see cref="Comparer{T}.Default"/> with the parameters swapped.</summary>
- public int Compare(T x, T y) => Comparer<T>.Default.Compare(y, x);
- }
- }
|