breakpoint

This commit is contained in:
CortexCore
2023-09-15 23:02:46 +08:00
parent f6bf8fffe3
commit eabf0c6188
43 changed files with 1701 additions and 1582 deletions

View File

@@ -1,6 +1,8 @@
using System.Threading;
using Cysharp.Threading.Tasks;
using Godot;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using HttpClient = System.Net.Http.HttpClient;
namespace BITKit;
@@ -24,7 +26,7 @@ public partial class BITAppForGodot : Node
BIT4Log.OnException += x=>GD.PrintErr(x.ToString());
//启动BITApp
BITApp.Start(ProjectSettings.GetSetting("application/config/name").AsString());
BITApp.Start(ProjectSettings.GetSetting("application/config/name").AsString()).Forget();
BIT4Log.Log<BITAppForGodot>("已创建BITApp");
}
@@ -36,9 +38,10 @@ public partial class BITAppForGodot : Node
//添加测试用HttpClient
BITApp.ServiceCollection.AddSingleton<HttpClient>();
BITApp.ServiceCollection.AddLogging();
//构造依赖服务提供接口
BITApp.BuildService();
//BITApp.BuildService();
//设置光标状态
AllowCursor.AddListener(SetCursor);
@@ -49,10 +52,8 @@ public partial class BITAppForGodot : Node
}
protected override void Dispose(bool disposing)
{
#pragma warning disable CS4014
//停止BITApp
BITApp.Stop();
#pragma warning restore CS4014
BIT4Log.Log<BITAppForGodot>("已安全退出App");
}
private void Exit()

View File

@@ -0,0 +1,11 @@
using Godot;
using System;
namespace BITKit.Display;
public partial class DisplayService : Node
{
public void SetDisplay(string resolution)
{
}
}

View File

@@ -2,7 +2,10 @@ using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BITKit.Core.Entites;
using Microsoft.Extensions.DependencyInjection;
namespace BITKit;
/// <summary>
/// 用于Godot的ECS.Entity实现
@@ -12,7 +15,7 @@ public partial class Entity : Node,IEntity
/// <summary>
/// 类型组件的缓存
/// </summary>
private readonly Dictionary<Type,IEntityComponent> TypeComponents=new ();
private readonly Dictionary<Type,object> TypeComponents=new ();
/// <summary>
/// IEntityService的缓存
/// </summary>
@@ -27,6 +30,11 @@ public partial class Entity : Node,IEntity
/// </summary>
public ulong Id { get; private set; }
/// <summary>
/// 服务提供者
/// </summary>
public IServiceProvider ServiceProvider { get; private set; }
private IServiceCollection _serviceCollection;
/// <summary>
/// 加载所有EntityComponent的内部实现
/// </summary>
public override void _Ready()
@@ -34,9 +42,26 @@ public partial class Entity : Node,IEntity
List<IEntityComponent> entityComponents = new();
Id = GetInstanceId();
_entitiesService = DI.Get<IEntitiesService>();
_serviceCollection = new ServiceCollection();
_serviceCollection.AddLogging();
foreach (var x in MathNode.GetAllNode(this))
{
GetInstanceId();
if (x is IEntityComponent entityComponent)
{
entityComponent.BuildService(_serviceCollection);
}
foreach (var customType in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
{
_serviceCollection.AddSingleton(customType.Type,x);
}
ServiceProvider = _serviceCollection.BuildServiceProvider();
if (x is not IEntityComponent component) continue;
component.Entity = this;
TypeComponents.TryAdd(component.BaseType,component);
@@ -44,7 +69,7 @@ public partial class Entity : Node,IEntity
component.OnAwake();
entityComponents.Add(component);
}
foreach (var component in TypeComponents.Values)
foreach (var component in TypeComponents.Values.OfType<IEntityComponent>())
{
component.OnStart();
}
@@ -52,7 +77,7 @@ public partial class Entity : Node,IEntity
this._components = entityComponents.ToArray();
SetMeta("Components",Variant.From(_components.Select(x=>x.GetType().Name).ToArray()));
}
public bool TryGetComponent<T>(out T component) where T : IEntityComponent
public bool TryGetComponent<T>(out T component)
{
if (TypeComponents.TryGetValue(typeof(T), out var iComponent) && iComponent is T _component)
{
@@ -71,8 +96,10 @@ public partial class Entity : Node,IEntity
}
}
public bool RegisterComponent<T>(T component) where T : IEntityComponent
public bool RegisterComponent<T>(T component)
{
return TypeComponents.TryAdd(typeof(T), component);
}
}

View File

@@ -1,6 +1,7 @@
using System;
using BITKit.Core.Entites;
using Godot;
using Microsoft.Extensions.DependencyInjection;
namespace BITKit;
/// <summary>
@@ -10,6 +11,7 @@ public partial class EntityComponent : Node,IEntityComponent
{
public virtual Type BaseType => GetType();
public IEntity Entity { get; set; }
public virtual void BuildService(IServiceCollection serviceCollection){}
public virtual void OnStart(){}
public virtual void OnAwake(){}
}

View File

@@ -47,7 +47,7 @@ public partial class GodotEntitiesService : Node,IEntitiesService
throw new NotImplementedException();
}
public IEntity[] Query<T>() where T : IEntityComponent
public IEntity[] Query<T>()
{
return _entities.Values.Where(x => x.TryGetComponent<T>(out _)).ToArray();
}
@@ -76,7 +76,7 @@ public partial class GodotEntitiesService : Node,IEntitiesService
.Select(x => new ValueTuple<T>(x))
.ToArray();
}
public (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
public (T, T1)[] QueryComponents<T, T1>()
{
var entities = _entities.Values.Where(x => x.TryGetComponent<T>(out _) && x.TryGetComponent<T1>(out _));
var result = new List<(T, T1)>();
@@ -89,7 +89,7 @@ public partial class GodotEntitiesService : Node,IEntitiesService
return result.ToArray();
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
return _entities.Values
.Where(x => x.TryGetComponent<T>(out _) && x.TryGetComponent<T1>(out _) && x.TryGetComponent<T2>(out _))

View File

@@ -1,52 +0,0 @@
using System;
using Cysharp.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace BITKit;
public interface IDatabaseContext<T> where T : class
{
void Add(T entity);
UniTask AddAsync(T entity);
void Remove(T entity);
T[] GetArray();
bool TrySearch(Func<T, bool> searchFactory, out T result);
bool TrySearchArray(Func<T, bool> searchFactory, out T[] result);
}
public abstract class EntityFrameworkContext<T>:DbContext ,IDatabaseContext<T> where T : class
{
protected DbSet<T> context { get; private set; }
public void Add(T entity)
{
context.Add(entity);
SaveChanges();
}
public async UniTask AddAsync(T entity)
{
await context.AddAsync(entity);
await SaveChangesAsync();
}
public void Remove(T entity)
{
throw new NotImplementedException();
}
public T[] GetArray()
{
throw new NotImplementedException();
}
public bool TrySearch(Func<T, bool> searchFactory, out T result)
{
throw new NotImplementedException();
}
public bool TrySearchArray(Func<T, bool> searchFactory, out T[] result)
{
throw new NotImplementedException();
}
}

View File

@@ -1,18 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Console;
namespace BITKit;
public class MySQLContext<T>:DbContext where T:class
{
protected readonly string _connectSql;
protected DbSet<T> context { get; private set; }
public MySQLContext(string connectSql) : base()
{
_connectSql = connectSql;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL("_connectSql");
}
}

View File

@@ -1,80 +0,0 @@
using System;
using System.Linq;
using Cysharp.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace BITKit;
public class SqlLiteContext<T> : DbContext,IDatabaseContext<T> where T : class
{
public DbSet<T> context { get; private set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var sql = SQLiteContextHelper.GetConnectionString<T>();
optionsBuilder.UseSqlite(sql);
}
public virtual void Add(T entity)
{
context.Add(entity);
SaveChanges();
}
public UniTask AddAsync(T entity)
{
throw new NotImplementedException();
}
public virtual void Remove(T entity)
{
context.Remove(entity);
SaveChanges();
}
public virtual T[] GetArray()
{
return context.ToArray();
}
public virtual bool TrySearch(Func<T,bool> searchFactory,out T result)
{
result = context.FirstOrDefault(searchFactory);
return result != null;
}
/// <summary>
/// 搜索数组
/// </summary>
/// <param name="searchFactory"></param>
/// <param name="result"></param>
/// <returns></returns>
public virtual bool TrySearchArray(Func<T, bool> searchFactory, out T[] result)
{
result = context.Where(searchFactory).ToArray();
return result.Length > 0;
}
}
public static class SQLiteContextHelper
{
private const string _database = "Database";
public static string GetConnectionString(string key)
{
GetConnectionSqlAndPath(key,out var connectionSql,out var path);
BIT4Log.Log($"已创建数据库链接:{path}");
return connectionSql;
}
public static string GetConnectionString<T>()
{
GetConnectionSqlAndPath(typeof(T).Name,out var connectionSql,out var path);
BIT4Log.Log<T>($"已创建数据库链接:{path}");
return connectionSql;
}
public static void GetConnectionSqlAndPath(string name,out string connectionSql,out string path)
{
PathHelper.GetFolderPath(_database);
path = PathHelper.GetPath(_database, $"{name}.db");
connectionSql = $"Data Source={path}";
}
}

View File

@@ -1,7 +1,7 @@
using Godot;
using System;
namespace BITKit;
namespace BITKit.UX;
public partial class UXPanel : Control, IUXPanel
{
@@ -10,29 +10,33 @@ public partial class UXPanel : Control, IUXPanel
[Export] private bool allowInput;
[Export] private bool isStartPanel;
public bool IsAnimate => isAnimate;
public bool IsValid { get; set; }
public string Index => _index;
public bool AllowCursor => allowCursor;
public bool AllowInput => allowInput;
private string _index;
public virtual void OnEntry(){}
public virtual void Entry()
{
Show();
OnEntry();
//OnEntry();
}
public virtual void Exit()
{
Hide();
OnExit();
//OnExit();
}
public virtual void OnExit(){}
public event Action OnEntry;
public event Action OnExit;
//public virtual void OnExit(){}
public override void _Ready()
{
IsValid = true;
_index = GetType().FullName == typeof(UXPanel).FullName ? Name : GetType().FullName;
UXService.Register(this);
@@ -49,9 +53,6 @@ public partial class UXPanel : Control, IUXPanel
public override void _ExitTree()
{
UXService.UnRegister(this);
IsValid = false;
}
// protected override void Dispose(bool disposing)
// {
// UXService.UnRegister(this);
// }
}

View File

@@ -4,43 +4,9 @@ using System.Linq;
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();
}
namespace BITKit.UX;
/// <summary>
/// 基本UX服务(GUI管理器),主要通过加载叠加面板实现
/// </summary>
/// <para>使用方式:</para>
///
///
public partial class UXService : Control
public partial class UXService : Control, IUXService
{
private static UXService Singleton;
@@ -53,19 +19,13 @@ public partial class UXService : Control
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)
{
UnRegistryQueue.Enqueue(panel);
@@ -131,11 +91,7 @@ public partial class UXService : Control
private static InitializationState InitializationState;
private void _Entry(IUXPanel panel)
{
}
public override void _Process(double delta)
{
if (TransitionPanles.Count is not 0) return;
@@ -169,4 +125,10 @@ public partial class UXService : Control
EnabledPanels.Push(next);
History.Push(next);
}
void IUXService.Register(IUXPanel panel)=>Register(panel);
void IUXService.UnRegister(IUXPanel panel)=>UnRegister(panel);
void IUXService.Entry<T>() => Open<T>();
void IUXService.Return() => Return();
void IUXService.Entry(IUXPanel panel) => Open(panel);
void IUXService.Entry(string panelName) => Open(panelName);
}

View File

@@ -1,5 +1,6 @@
using Godot;
using System;
using BITKit.UX;
namespace BITKit;

View File

@@ -0,0 +1,82 @@
using Godot;
using System;
using Godot.Collections;
namespace BITKit.UX
{
[Tool]
public partial class UXTabViewService : Control
{
[ExportCategory(Constant.Header.Settings)]
[Export(PropertyHint.Range, "0,100,1")]
private int currentIndex
{
get=>_currentIndex;
set => SetIndex(value);
}
[Export] private int initialIndex;
[ExportCategory(Constant.Header.Components)]
[Export] private Array<Button> tabs;
[Export] private TabContainer tabContainer;
private ButtonGroup _buttonGroup;
private int _currentIndex;
public override void _Ready()
{
if (_isReady is false) return;
_buttonGroup = new ButtonGroup();
for (var i = 0; i < tabs.Count; i++)
{
var tab = tabs[i];
var _i = i;
tab.Pressed += () => { SetIndex(_i); };
}
var index = (Engine.IsEditorHint(), currentIndex, initialIndex) switch
{
(true,_,_)=>currentIndex,
(false,_,>-1)=>initialIndex,
(_,_,-1)=>-1,
_ => -1
};
SetIndex(index);
}
private void SetIndex(int value)
{
if (_isReady is false) return;
if (value < 0) return;
EnsureConfiguration();
value = Mathf.Clamp(value, 0, tabContainer.GetChildCount() -1 );
_currentIndex = value;
tabContainer.CurrentTab = value;
foreach (var tab in tabs)
{
tab.ButtonPressed = false;
}
if (tabs.TryGetElementAt(value, out var button))
{
button.ButtonPressed = true;
}
}
private void EnsureConfiguration()
{
if (_isReady is false) return;
tabContainer.TabsVisible = false;
foreach (var tab in tabs)
{
tab.ButtonGroup = _buttonGroup;
}
}
private bool _isReady => IsNodeReady() && tabContainer is not null & tabs is not null;
}
}

View File

@@ -4,6 +4,7 @@ using Godot.Collections;
namespace BITKit;
[Tool]
[Obsolete("see UXTabContainerService")]
public partial class UXWindowService : Control
{
[Export] private Array<Button> tabs;
@@ -34,7 +35,6 @@ public partial class UXWindowService : Control
//if(window.Visible is true && window != x)
x.Hide();
}
var index = windows.IndexOf(window as Control);
if (index is not -1)
{