62 lines
2.1 KiB
C#
62 lines
2.1 KiB
C#
|
using Godot;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace BITKit;
|
||
|
|
||
|
public interface IMetaDisplayElement
|
||
|
{
|
||
|
string Text { get; }
|
||
|
Vector3 Position { get; }
|
||
|
}
|
||
|
public partial class UXMetaService : Control
|
||
|
{
|
||
|
#region 静态方法
|
||
|
private static readonly Queue<IMetaDisplayElement> AddQueue = new();
|
||
|
private static readonly Queue<IMetaDisplayElement> RemoveQueue = new();
|
||
|
private static readonly List<IMetaDisplayElement> Elements = new();
|
||
|
public static void Register(IMetaDisplayElement element) => AddQueue.Enqueue(element);
|
||
|
public static void UnRegister(IMetaDisplayElement element) => RemoveQueue.Enqueue(element);
|
||
|
#endregion
|
||
|
#region 实例方法
|
||
|
private readonly Dictionary<IMetaDisplayElement, Label> _dictionary = new();
|
||
|
#endregion
|
||
|
/// <summary>
|
||
|
/// 标签预制体
|
||
|
/// </summary>
|
||
|
[Export]
|
||
|
private PackedScene labelTemplate;
|
||
|
/// <summary>
|
||
|
/// 主要处理过程
|
||
|
/// </summary>
|
||
|
/// <param name="delta"></param>
|
||
|
public override void _Process(double delta)
|
||
|
{
|
||
|
//相机服务未初始化时返回
|
||
|
if(CameraService.Singleton is null)return;
|
||
|
//处理添加队列
|
||
|
while (AddQueue.TryDequeue(out var newElement))
|
||
|
{
|
||
|
if (!Elements.TryAdd(newElement)) continue;
|
||
|
var instance = labelTemplate.Instantiate<Label>();
|
||
|
_dictionary.Add(newElement,instance);
|
||
|
AddChild(instance);
|
||
|
}
|
||
|
//处理每个Element的数据
|
||
|
foreach (var element in Elements)
|
||
|
{
|
||
|
if (_dictionary.TryGetValue(element, out var label) is false) continue;
|
||
|
var pos = CameraService.Singleton.UnprojectPosition(element.Position);
|
||
|
label.Position = pos;
|
||
|
label.Text = element.Text;
|
||
|
}
|
||
|
//处理移除队列
|
||
|
while (RemoveQueue.TryDequeue(out var removeElement))
|
||
|
{
|
||
|
if (!_dictionary.TryGetValue(removeElement, out var label)) continue;
|
||
|
if (!_dictionary.TryRemove(removeElement)) continue;
|
||
|
Elements.Remove(removeElement);
|
||
|
label.QueueFree();
|
||
|
}
|
||
|
}
|
||
|
}
|