105 lines
2.7 KiB
C#
105 lines
2.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using kcp2k;
|
|
using Quadtree;
|
|
using Quadtree.Items;
|
|
using UnityEngine;
|
|
using UnityEngine.Pool;
|
|
|
|
namespace BITKit.Sensors
|
|
{
|
|
public struct ClassicNoise{}
|
|
public class AudioSensorService : MonoBehaviour
|
|
{
|
|
public static readonly HashSet<int> LockHash = new();
|
|
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;
|
|
public object NoiseType;
|
|
public float ExpirationTime;
|
|
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);
|
|
|
|
private static readonly Pool<AudioSensorData> pool = new(()=>new AudioSensorData(), x=>{}, 1000);
|
|
private static readonly ConcurrentQueue<AudioSensorData> registerQueue = new();
|
|
private static int count;
|
|
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)
|
|
{
|
|
var data = pool.Take();
|
|
data.Id = count++;
|
|
data.Position = position;
|
|
data.Transform = transform;
|
|
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);
|
|
}
|
|
[SerializeReference, SubclassSelector] private ITicker ticker;
|
|
|
|
private void Start()
|
|
{
|
|
ticker.Add(OnTick);
|
|
destroyCancellationToken.Register(Dispose);
|
|
pool.Clear();
|
|
}
|
|
|
|
private void Dispose()
|
|
{
|
|
registerQueue.Clear();
|
|
ticker.Remove(OnTick);
|
|
QuadtreeRoot.Clear();
|
|
}
|
|
|
|
private void OnTick(float obj)
|
|
{
|
|
if (LockHash.Count > 0) return;
|
|
|
|
|
|
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 _);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|