This commit is contained in:
CortexCore
2023-06-19 00:41:44 +08:00
parent 073996ce6c
commit bf122c66dc
48 changed files with 683 additions and 84 deletions

View File

@@ -0,0 +1,53 @@
using System.Linq;
using Godot;
namespace BITKit;
public partial class UXMetaElement : Node3D, IMetaDisplayElement
{
[Export] private bool isEnabled=true;
[Export] private Node3D proxy;
[Export] protected string[] MetaEntries;
private bool _registered;
string IMetaDisplayElement.Text
{
get
{
var node = proxy ?? this;
return string.Join(MetaEntries?.Length>2 ? "\n" : ":", MetaEntries!
.Where(x => string.IsNullOrEmpty(x) is false)
.Where(x => node.HasMeta(x))
.Select(x => node.GetMeta(x).AsString())
.InsertOf<string>(0, node.Name)
);
}
}
Vector3 IMetaDisplayElement.Position => (proxy ?? this).GlobalPosition;
// public override void _Ready()
// {
// if (!isEnabled) return;
// UXMetaService.Register(this);
// _registered = true;
// }
public override void _Process(double delta)
{
if (_registered == isEnabled) return;
if (isEnabled)
{
UXMetaService.Register(this);
}
else
{
UXMetaService.UnRegister(this);
}
_registered = isEnabled;
}
protected override void Dispose(bool disposing)
{
if (isEnabled && _registered)
UXMetaService.UnRegister(this);
}
}

View File

@@ -0,0 +1,61 @@
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();
}
}
}

View File

@@ -0,0 +1,50 @@
using Godot;
using System;
namespace BITKit;
public partial class UXPanel : Control, IUXPanel
{
[Export] private bool isAnimate;
[Export] private bool allowCursor;
[Export] private bool allowInput;
[Export] private bool isStartPanel;
public bool IsAnimate => isAnimate;
public string Index => GetType().FullName == typeof(UXPanel).FullName ? Name : GetType().FullName;
public bool AllowCursor => allowCursor;
public bool AllowInput => allowInput;
public virtual void OnEntry(){}
public virtual void Entry()
{
Show();
OnEntry();
}
public virtual void Exit()
{
Hide();
OnExit();
}
public virtual void OnExit(){}
public override void _Ready()
{
UXService.Register(this);
if (isStartPanel)
{
UXService.Open(this as IUXPanel);
}
}
private void Open()
{
UXService.Open(this as IUXPanel);
}
protected override void Dispose(bool disposing)
{
UXService.UnRegister(this);
}
}

View File

@@ -0,0 +1,144 @@
using Godot;
using System.Collections.Generic;
using System.Xml;
using Microsoft.Extensions.DependencyInjection;
namespace BITKit;
/// <summary>
/// 基本UX面板接口,定义了基本的UX面板功能
/// </summary>
/// <para>⭐同步打开与关闭</para>
/// <para>⭐异步打开与关闭</para>
/// <para>⭐当前可见状态</para>
/// <para>⭐基本UI导航回调</para>
public interface IUXPanel
{
/// <summary>
/// 该面板是否具有动画
/// </summary>
bool IsAnimate { get; }
/// <summary>
/// 该面板的索引(入口,Key)
/// </summary>
string Index { get; }
/// <summary>
/// 该面板是否启用指针
/// </summary>
bool AllowCursor { get; }
/// <summary>
/// 该面板是否启用玩家输入
/// </summary>
bool AllowInput { get; }
void Entry();
void Exit();
}
/// <summary>
/// 基本UX服务(GUI管理器),主要通过加载叠加面板实现
/// </summary>
/// <para>使用方式:</para>
///
///
public partial class UXService : Control
{
private static UXService Singleton;
/// <summary>
/// 在构造函数中注入依赖
/// </summary>
public UXService()
{
BITApp.ServiceCollection.AddSingleton(this);
Singleton = this;
}
/// <summary>
/// 注册面板,加入注册队列
/// </summary>
/// <param name="panel">UX面板</param>
public static void Register(IUXPanel panel)
{
RegistryQueue.Enqueue(panel);
}
/// <summary>
/// 注销面板
/// </summary>
/// <param name="panel">UX面板</param>
public static void UnRegister(IUXPanel panel)
{
}
public static void Open<T>() where T : IUXPanel
{
}
public static void Open(IUXPanel panel) => EnableQueue.Push(panel);
public static void Open(Control control)
{
}
public static void Open(string name)
{
}
/// <summary>
/// 内部注册面板队列
/// </summary>
private static readonly Queue<IUXPanel> RegistryQueue = new();
/// <summary>
/// 已注册面板字典
/// </summary>
private static readonly Dictionary<string, IUXPanel> Panels = new();
/// <summary>
/// 等待启用的面板队列
/// </summary>
private static readonly Stack<IUXPanel> EnableQueue = new();
/// <summary>
/// 已启用面板
/// </summary>
private static readonly Stack<IUXPanel> EnabledPanels = new();
/// <summary>
/// 等待隐藏的面板
/// </summary>
private static readonly Stack<IUXPanel> WActivatedPanels = new();
/// <summary>
/// 正在播放过渡动画的面板
/// </summary>
private static readonly Stack<IUXPanel> TransitionPanles = new();
private void _Entry(IUXPanel panel)
{
}
public override void _Process(double delta)
{
if (TransitionPanles.Count is not 0) return;
while (RegistryQueue.TryDequeue(out var result))
{
Panels.Add(result.Index, result);
result.Exit();
}
if (EnableQueue.TryPop(out var next))
{
while (EnabledPanels.TryPop(out var enabledPanel))
{
enabledPanel.Exit();
}
next.Entry();
EnabledPanels.Push(next);
return;
}
}
}