godot-karrot-starter-theme/Common/StateMachines/State.cs
2024-11-12 18:09:47 +01:00

85 lines
2.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Godot;
using Godot.Collections;
namespace KarrotStarterTemplate.Common.StateMachines;
public abstract partial class State : Node
{
[Export] public string id { get; private set; }
// [Export] public bool queueable { get; private set; }
[Export] public bool canTransitionToSelf { get; private set; }
[Export] public float minimumStateDuration { get; private set; }
public bool checkRelevance { get; protected set; } = true;
public bool queueRelevance { get; protected set; } = true;
protected List<string> statesInQueue = new();
private double _startTime;
protected float timeElapsed => (float)(Time.GetUnixTimeFromSystem() - _startTime);
protected StateMachine parentStateMachine;
public StateInputsPackage package => parentStateMachine.package;
public bool isActive => parentStateMachine?.currentState == this;
public bool isTransitioning => parentStateMachine?.currentState == this && parentStateMachine.isTransitioning;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
parentStateMachine = GetParent<StateMachine>();
}
protected abstract Task OnEnter();
protected abstract Task OnExit();
protected virtual void OnStateProcess(double delta) {}
protected virtual void OnStatePhysicsProcess(double delta) {}
protected virtual string OnCheckRelevance()
{
return null;
}
public async Task Enter()
{
_startTime = Time.GetUnixTimeFromSystem();
await OnEnter();
}
public async Task Exit()
{
statesInQueue.Clear();
await OnExit();
}
public void StateProcess(double delta)
{
OnStateProcess(delta);
}
public void StatePhysicsProcess(double delta)
{
OnStatePhysicsProcess(delta);
}
public string CheckRelevance()
{
string value = OnCheckRelevance();
if (timeElapsed <= (minimumStateDuration <= 0 ? 0.01f : minimumStateDuration) || !checkRelevance)
{
// if (queueRelevance && value != null && parentStateMachine.states[value].queueable)
// {
// statesInQueue.Add(value);
// }
return null;
}
// if (statesInQueue.Count > 0) return statesInQueue.Last();
return value;
}
}