iFactory.Godot/BITKit/Scripts/UX/UXMetaService.cs

62 lines
2.1 KiB
C#
Raw Normal View History

2023-06-16 17:08:59 +08:00
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();
}
}
}