supervisor-simulator/addons/autosaver_editor/Services/TimerService.cs
2024-11-19 00:32:10 +08:00

92 lines
2.2 KiB
C#

using System;
using AutoSaverPlugin.Contracts;
using AutoSaverPlugin.Shared;
using Godot;
namespace AutoSaverPlugin.Services
{
internal sealed class TimerService : ITimerService
{
private Timer _timer;
private AutoSaverEditorPlugin _plugin;
private Action _timeoutAction;
private ILoggerService _logger;
public TimerService(ILoggerService loggerService)
{
_logger = loggerService ?? throw new ArgumentNullException(nameof(loggerService));
}
public ITimerService AttachTo(AutoSaverEditorPlugin plugin)
{
_plugin = plugin ?? throw new ArgumentNullException(nameof(plugin));
return this;
}
public ITimerService OnTimeout(Action action, bool oneShot = false)
{
_timeoutAction = action ?? throw new ArgumentNullException(nameof(action));
SetupTimer(oneShot);
return this;
}
public ITimerService Begin(float intervalSeconds)
{
if (_timer == null)
{
_logger.LogError("Timer is not initialized. Call OnTimeout first.");
return this;
}
_timer.WaitTime = intervalSeconds;
if (!_timer.IsInsideTree())
{
_plugin.AddChild(_timer);
}
_timer.Start();
return this;
}
public ITimerService End()
{
DisposeTimer();
return this;
}
private void SetupTimer(bool oneShot)
{
DisposeTimer();
_timer = new Timer
{
OneShot = oneShot
};
_timer.Timeout += OnTimerTimeout;
}
private void OnTimerTimeout()
{
_timeoutAction?.Invoke();
}
private void DisposeTimer()
{
if (_timer != null)
{
_timer.Stop();
if (_timer.IsInsideTree())
{
_plugin.RemoveChild(_timer);
}
_timer.Timeout -= OnTimerTimeout;
_timer.QueueFree();
_timer = null;
}
}
}
}