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

105 lines
2.7 KiB
C#
Raw Normal View History

2024-04-16 04:06:46 +08:00
using System;
using System.Collections;
2024-05-31 01:23:15 +08:00
using System.Collections.Concurrent;
2024-04-16 04:06:46 +08:00
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using kcp2k;
using Quadtree;
using Quadtree.Items;
using UnityEngine;
using UnityEngine.Pool;
namespace BITKit.Sensors
{
2024-05-31 01:23:15 +08:00
public struct ClassicNoise{}
2024-04-16 04:06:46 +08:00
public class AudioSensorService : MonoBehaviour
{
2024-05-31 01:23:15 +08:00
public static readonly HashSet<int> LockHash = new();
2024-04-16 04:06:46 +08:00
public class AudioSensorData:IItem<AudioSensorData,Node<AudioSensorData>>
{
public int Id;
public Vector3 Position;
public float Radius;
public Transform Transform;
public Bounds Bounds;
public ITag Tag;
2024-05-31 01:23:15 +08:00
public object NoiseType;
public float ExpirationTime;
2024-04-16 04:06:46 +08:00
public Bounds GetBounds() => Bounds;
public Node<AudioSensorData> ParentNode { get; set; }
public void QuadTree_Root_Initialized(IQuadtreeRoot<AudioSensorData, Node<AudioSensorData>> root){}
}
internal static readonly QuadtreeRoot<AudioSensorData, Node<AudioSensorData>> QuadtreeRoot =
new(default, Vector3.one * 2048);
2024-05-31 01:23:15 +08:00
private static readonly Pool<AudioSensorData> pool = new(()=>new AudioSensorData(), x=>{}, 1000);
private static readonly ConcurrentQueue<AudioSensorData> registerQueue = new();
2024-04-16 04:06:46 +08:00
private static int count;
2024-05-31 01:23:15 +08:00
private static readonly Queue<int> freeIds = new();
private static readonly ConcurrentDictionary<int, AudioSensorData> dictionary = new();
public static void MakeNoise(Vector3 position, Transform transform, float radius = 1,
object noiseType = null)
2024-04-16 04:06:46 +08:00
{
var data = pool.Take();
data.Id = count++;
data.Position = position;
data.Transform = transform;
2024-05-31 01:23:15 +08:00
data.Bounds = new Bounds(position, Vector3.one * 1);
if (transform)
data.Tag = transform.GetComponent<ITag>();
data.Radius = radius;
data.ExpirationTime = Time.time + 0.5f;
registerQueue.Enqueue(data);
2024-04-16 04:06:46 +08:00
}
[SerializeReference, SubclassSelector] private ITicker ticker;
2024-05-31 01:23:15 +08:00
2024-04-16 04:06:46 +08:00
private void Start()
{
2024-05-31 01:23:15 +08:00
ticker.Add(OnTick);
2024-04-16 04:06:46 +08:00
destroyCancellationToken.Register(Dispose);
pool.Clear();
}
2024-05-31 01:23:15 +08:00
2024-04-16 04:06:46 +08:00
private void Dispose()
{
2024-05-31 01:23:15 +08:00
registerQueue.Clear();
2024-04-16 04:06:46 +08:00
ticker.Remove(OnTick);
QuadtreeRoot.Clear();
}
2024-05-31 01:23:15 +08:00
2024-04-16 04:06:46 +08:00
private void OnTick(float obj)
{
2024-05-31 01:23:15 +08:00
if (LockHash.Count > 0) return;
2024-04-16 04:06:46 +08:00
2024-05-31 01:23:15 +08:00
while (registerQueue.TryDequeue(out var data))
{
if (data.ExpirationTime < Time.time)
{
pool.Return(data);
continue;
}
QuadtreeRoot.Insert(data);
dictionary.TryAdd(data.Id, data);
}
var currentTime = Time.time;
foreach (var (id, data) in dictionary)
{
if (data.ExpirationTime > currentTime) continue;
freeIds.Enqueue(id);
QuadtreeRoot.Remove(data);
pool.Return(data);
}
while (freeIds.TryDequeue(out var id))
{
dictionary.TryRemove(id, out _);
}
2024-04-16 04:06:46 +08:00
}
}
}