using System.Collections; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; using System; using System.Text; using System.Threading; using System.Net.Http; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UIElements; namespace BITKit.HttpNet { public class NetworkRequest : BITBehavior, IAction { [SubclassSelector, SerializeReference] public References _url; public Provider onException; public Provider provider; public Provider onPing; public IntervalUpdate updater = new(); [SubclassSelector, SerializeReference] public WebProvider webProvider; public Counter counter = new(); public string result; public int requestCount; public int responsedCount; public float deltaTick; public double requestTime; public LimitTimes limit = new(64); System.Timers.Timer timer = new(); CompletionRate completionRate = new(); ValidHandle isActive = new(); float internalTime; CancellationToken cancellationToken; void Awake() { cancellationToken = gameObject.GetCancellationTokenOnDestroy(); timer.Elapsed += (x, y) => OnUpdate(); isActive.AddListener(Set); isActive.AddDisableElements(this); } void OnEnable() { isActive.AddElement(this); } void Start() { isActive.RemoveDisableElements(this); } void OnDisable() { isActive.RemoveElement(this); } void OnDestroy() { timer.Dispose(); } void SetIntervalUpdateActive(bool active) { isActive.SetDisableElements(internalTime, active is false); } void Update() { deltaTick = completionRate; } void Set(bool active) { if (timer.Enabled != active) { if (active) { var interval = TimeSpan.FromSeconds(updater.Interval).TotalMilliseconds; timer.Interval = interval; timer.AutoReset = true; timer.Start(); } else { timer.Stop(); } } } protected virtual void OnUpdate() { try { if (limit) { Excute(true); } } catch (System.Exception e) { BIT4Log.Warning(e); throw; } } public void Execute() { Excute(false); } public async void Excute(bool release = false) { try { BITAppForUnity.ThrowIfNotPlaying(); } catch (AppIsNotPlayingException) { } catch (OperationCanceledException) { } NetworkCore.Add(_url); requestCount++; internalTime += BITApp.Time.DeltaTime; completionRate.Get(); var time = BITApp.Time.TimeAsDouble; try { var result = await webProvider.GetAsync(_url, cancellationToken); responsedCount++; provider?.Set(result); completionRate.Release(); requestTime = BITApp.Time.TimeAsDouble - time; if (requestTime is not 0) onPing?.Set(((int)(requestTime * 1000)).ToString()); this.result = result; } catch (System.Exception e) { onException?.Set(e); switch (e) { case TimeoutException: case OperationCanceledException: case System.Net.WebException: case System.Net.Http.HttpRequestException: break; case InvalidOperationException operationException: Debug.LogWarning(_url.Get()); goto default; default: Debug.LogException(e, this); break; } } if (release) { limit.Release(); } } } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(NetworkRequest))] public class Inspector : BITInspector { public override VisualElement CreateInspectorGUI() { var root = base.CreateInspectorGUI(); var button = new Button(agent.Execute); button.text = "Request"; root.Add(button); return root; } } #endif }