Skip to content

Instantly share code, notes, and snippets.

@aberloni
Created November 15, 2021 18:32
Show Gist options
  • Save aberloni/280683a0b44bb30c24473318de559cdd to your computer and use it in GitHub Desktop.
Save aberloni/280683a0b44bb30c24473318de559cdd to your computer and use it in GitHub Desktop.
State manager using generic enums
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// https://docs.microsoft.com/fr-fr/dotnet/csharp/language-reference/operators/user-defined-conversion-operators
/// </summary>
[System.Serializable]
public class EnumState<TState> where TState : System.Enum
{
System.Action<TState> binds;
[ReadOnly]
[SerializeField]
TState _state;
public EnumState()
{ }
public EnumState(IStateReactor<TState> client)
{
Debug.Assert(client != null);
Debug.Log("creating state for " + client);
bind(client);
//changeState(default(TState));
triggerState(default(TState));
}
public static implicit operator TState(EnumState<TState> v) => v.getValue();
//public static explicit operator TState(EnumState<TState> v) => v.getValue();
public void bind(IStateReactor<TState> client)
{
Debug.Assert(client != null, "no client given for binding ?");
binds += client.stateChanged;
BrainBase bb = client as BrainBase;
if (bb != null)
{
KappaAppearance kap = bb.getCapacity<KappaAppearance>();
if (kap != null)
{
IStateReactor<TState> ikap = kap as IStateReactor<TState>;
if (ikap != null) bind(ikap);
else Debug.LogWarning(kap.name + " is not a state reactor", kap);
}
else Debug.LogWarning("no kapp on " + bb, bb);
}
}
public void bind(System.Action<TState> callback)
{
binds += callback;
}
/// <summary>
/// https://stackoverflow.com/questions/6480577/how-to-compare-values-of-generic-types
/// </summary>
/// <param name="newState"></param>
public void changeState(TState newState)
{
if (newState.CompareTo(_state) == 0) return; // same value
triggerState(newState);
}
void triggerState(TState newState)
{
_state = newState;
binds?.Invoke(_state);
}
public bool same(TState other) => _state.CompareTo(other) == 0;
public TState getValue() => _state;
//public T getState() => (T)System.Enum.GetValues(typeof(T)).GetValue(_state);
}
public interface IStateReactor<TState> where TState : System.Enum
{
void stateChanged(TState state);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment