Code/ActionTimer.cs
using System;
using Sandbox;
[Title( "ActionTimer" )]
[Icon("timer")]
public class ActionTimer : Component
{
[Property] public float Duration { get; set; } = 1.0f;
[Property] public bool TimerLoops { get; set; } = false;
[Property] public bool AutoStart { get; set; } = false;
[Property] public bool UseThreading { get; set; } = false;
// This generates a unique ID for the internal Timer class to prevent collisions
private string TimerId => $"FatesTimer_{GameObject.Id}";
public string PrintTimerID()
{
return $"FatesTimer_{TimerId}";
}
public new bool IsRunning => Timer.Exists( TimerId ) && Timer.All()[TimerId].status == Timer.Process.Continue;
public float TimeRemaining => Timer.TimeLeft( TimerId );
[Property] public Action OnTimerElapsed;
protected override void OnStart()
{
if ( AutoStart ) StartTimer();
}
[Button, Group("Buttons")]
public void StartTimer()
{
// Repetitions: 0 for infinite (mapped to -1 in Timer), 1 for single run
int reps = TimerLoops ? 0 : 1;
Timer.Create( TimerId, Duration, reps, () => {
OnTimerElapsed?.Invoke();
}, UseThreading );
}
[Button, Group("Buttons")]
public void Pause()
{
Timer.Pause( TimerId );
}
[Button, Group("Buttons")]
public void Resume()
{
Timer.UnPause( TimerId );
}
[Button, Group("Buttons")]
public void Stop()
{
Timer.Remove( TimerId );
}
protected override void OnDestroy()
{
// Clean up the static dictionary entry when the component is removed
Timer.Remove( TimerId );
}
public void Debug()
{
Log.Info("ActionTimer Elapsed");
}
}