BITKit/Src/Unity/Scripts/Sensor/SensorQueue.cs

93 lines
1.9 KiB
C#
Raw Normal View History

2024-03-31 23:31:00 +08:00
using System;
using System.Collections;
2024-04-16 04:06:46 +08:00
using System.Collections.Concurrent;
2024-03-31 23:31:00 +08:00
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace BITKit.Sensors
{
public class SensorQueue : MonoBehaviour
{
2024-05-31 01:23:15 +08:00
internal static readonly ConcurrentDictionary<int,ISensor> Sensors=new();
2024-04-16 04:06:46 +08:00
internal static readonly ConcurrentDictionary<int, float> LastDetectedTime = new();
2024-03-31 23:31:00 +08:00
private static bool IsDirty;
[SerializeField,ReadOnly] private int _position;
public static void Register(int id,ISensor sensor)
{
2024-05-31 01:23:15 +08:00
Sensors.TryAdd(id,sensor);
2024-03-31 23:31:00 +08:00
MarkDirty();
}
public static void UnRegister(int id)
{
2024-05-31 01:23:15 +08:00
Sensors.TryRemove(id);
2024-03-31 23:31:00 +08:00
MarkDirty();
}
public static void MarkDirty()
{
IsDirty = true;
}
2024-04-16 04:06:46 +08:00
[SerializeReference,SubclassSelector] private ITicker ticker;
private bool _isBusy;
private void Start()
{
ticker.Add(OnTick);
destroyCancellationToken.Register(Dispose);
}
private void Dispose()
{
ticker.Remove(OnTick);
}
private async void OnTick(float obj)
2024-03-31 23:31:00 +08:00
{
2024-04-16 04:06:46 +08:00
if (_isBusy) return;
2024-03-31 23:31:00 +08:00
if (SensorGlobalSettings.Enabled is false) return;
2024-05-31 01:23:15 +08:00
try
2024-03-31 23:31:00 +08:00
{
2024-05-31 01:23:15 +08:00
_isBusy = true;
if(IsDirty)
{
_position = 0;
IsDirty = false;
}
if (Sensors.Count is 0)
{
_isBusy = false;
return;
}
2024-04-16 04:06:46 +08:00
2024-05-31 01:23:15 +08:00
var current = Sensors.ElementAt(_position++).Value;
2024-03-31 23:31:00 +08:00
2024-05-31 01:23:15 +08:00
if (current.AutoUpdate)
{
var currentUpdateTime = LastDetectedTime.GetOrAdd(current.Id,Time.time);
await current.Execute(Time.time-currentUpdateTime);
LastDetectedTime.AddOrUpdate(current.Id,Time.time,UpdateValueFactory);
if (destroyCancellationToken.IsCancellationRequested) {
_isBusy = false;
return;
}
}
_position %= Sensors.Count;
float UpdateValueFactory(int key, float old) => Time.time;
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
2024-04-16 04:06:46 +08:00
_isBusy = false;
2024-03-31 23:31:00 +08:00
}
}
2024-04-16 04:06:46 +08:00
}