using Godot;
using System;
using System.Threading;
using BITKit.Packages.Core.LazyLoad;
using HttpClient = System.Net.Http.HttpClient;
namespace BITKit;
public partial class HttpGet : Node,IActivable
{
///
/// 访问的Url
///
[Export] private string url;
///
/// 是否启用
///
[Export]
public bool Enabled { get; set; } = true;
[Signal]
public delegate void OnGetEventHandler(string httpContext);
[Signal]
public delegate void OnExceptionEventHandler(string exception);
///
/// 请求数据的间隔
///
private readonly IntervalTimer _intervalTimer = new(1);
///
/// http客户端
///
private readonly HttpClient httpClient=new();
///
/// 取消令牌,用于取消Http Get
///
private CancellationToken _cancellationToken;
private bool allowNextRequest = true;
public override void _Ready()
{
_cancellationToken = new CancellationToken();
}
///
/// 物理帧用于控制并发和间隔的同时请求数据
///
///
public override void _PhysicsProcess(double delta)
{
if (Enabled is false) return;
//等待依赖加载
//请求间隔控制+请求并发控制
if (_intervalTimer.Allow is false) return;
//如果url为空
if (string.IsNullOrEmpty(url)) return;
//发送请求
if (allowNextRequest)
Request();
}
private async void Request()
{
allowNextRequest = false;
//获取json
try
{
var json = await httpClient.GetStringAsync(url, _cancellationToken);
//取消执行,如果已取消令牌
_cancellationToken.ThrowIfCancellationRequested();
//调用回调
EmitSignal(nameof(OnGet), json);
}
catch (InvalidOperationException)
{
BIT4Log.Warning(url);
}
catch (OperationCanceledException)
{
}
catch (Exception e)
{
EmitSignal(nameof(OnException), e.Message);
}
allowNextRequest = true;
}
public void SetActive(bool active) => Enabled=active;
}