worldbox-observer-mod/IdleSpectator/InterestCollector.cs
2026-07-14 14:23:11 -05:00

127 lines
2.9 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace IdleSpectator;
public static class InterestCollector
{
private static readonly object Gate = new object();
private static readonly List<InterestEvent> Pending = new List<InterestEvent>();
public static void OnWorldLogMessage(WorldLogMessage message)
{
if (message == null)
{
return;
}
if (!WorldLogInterestTable.TryGetTier(message.asset_id, out InterestTier tier))
{
return;
}
Vector3 position = message.getLocation();
Actor unit = null;
if (message.hasFollowLocation())
{
unit = message.unit;
}
if (unit == null && position == Vector3.zero)
{
return;
}
EnqueueDirect(new InterestEvent
{
Tier = tier,
Score = (float)tier * 100f + Time.unscaledTime * 0.001f,
Position = position,
FollowUnit = unit,
Label = WorldLogInterestTable.MakeLabel(message),
CreatedAt = Time.unscaledTime,
AssetId = message.asset_id
});
}
public static void EnqueueDirect(InterestEvent interest)
{
if (interest == null || !interest.HasValidPosition)
{
return;
}
lock (Gate)
{
Pending.Add(interest);
if (Pending.Count > 64)
{
Pending.RemoveRange(0, Pending.Count - 64);
}
}
}
public static bool TryGetBest(out InterestEvent best)
{
lock (Gate)
{
best = null;
if (Pending.Count == 0)
{
return false;
}
int bestIndex = 0;
for (int i = 1; i < Pending.Count; i++)
{
InterestEvent candidate = Pending[i];
InterestEvent current = Pending[bestIndex];
if (candidate.Tier > current.Tier
|| (candidate.Tier == current.Tier && candidate.CreatedAt > current.CreatedAt))
{
bestIndex = i;
}
}
best = Pending[bestIndex];
return true;
}
}
public static void Remove(InterestEvent interest)
{
if (interest == null)
{
return;
}
lock (Gate)
{
Pending.Remove(interest);
}
}
public static void Clear()
{
lock (Gate)
{
Pending.Clear();
}
}
public static bool HasPendingAtLeast(InterestTier minTier)
{
lock (Gate)
{
for (int i = 0; i < Pending.Count; i++)
{
if (Pending[i] != null && Pending[i].Tier >= minTier)
{
return true;
}
}
return false;
}
}
}