This commit is contained in:
CortexCore
2023-10-20 19:31:12 +08:00
parent 5cd094ed9a
commit a160813262
1878 changed files with 630581 additions and 4485 deletions

View File

@@ -299,7 +299,7 @@ namespace BITKit
BITCommands.Dispose();
BIT4Log.Log<BITApp>($"已停止{nameof(BITApp)}");
BIT4Log.Log<BITApp>($"运行时间:{runTime}");
BIT4Log.Log<BITApp>($"运行时间:{runTime.ToString("hh\\:mm\\:ss")}");
BIT4Log.Log<BITApp>("Exit Code:0");
}

View File

@@ -4,11 +4,22 @@ namespace BITKit
{
[AttributeUsage(AttributeTargets.Method)]
public class BITCommandAttribute : Attribute { }
/// <summary>
/// 自动注入依赖
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class InjectAttribute : System.Attribute
{
public readonly bool CanBeNull;
public InjectAttribute()
{
}
public InjectAttribute(bool canBeNull)
{
CanBeNull = canBeNull;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
public class CustomTypeAttribute : System.Attribute
{
@@ -19,4 +30,11 @@ namespace BITKit
Type = type;
}
}
#if UNITY_64
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
public class ExportAttribute : System.Attribute
{
}
#endif
}

View File

@@ -1,11 +1,15 @@
using System;
using System.Diagnostics;
#if UNITY_64
using UnityEngine;
#endif
namespace BITKit
{
public static class BIT4Log
{
#if UNITY_EDITOR
[UnityEngine.RuntimeInitializeOnLoadMethod]
[RuntimeInitializeOnLoadMethod]
private static void Reload()
{
OnLog = null;
@@ -21,12 +25,17 @@ namespace BITKit
public static event Action<ConsoleColor> OnSetConsoleColor;
public static event Action OnNextLine;
private static Type currentType;
#if UNITY_64
[HideInCallstack]
#endif
public static void Log(object x, int debugLevel = 0, ConsoleColor color = ConsoleColor.White)
{
OnSetConsoleColor?.Invoke(color);
OnLog?.Invoke(x?.ToString());
}
#if UNITY_64
[HideInCallstack]
#endif
public static void Log<T>(object x, int debugLevel = 0, ConsoleColor color = ConsoleColor.White)
{
if (currentType != typeof(T))
@@ -41,15 +50,23 @@ namespace BITKit
currentType = typeof(T);
}
#if UNITY_64
[HideInCallstack]
#endif
public static void LogException(Exception e)
{
OnException?.Invoke(e);
}
#if UNITY_64
[HideInCallstack]
#endif
public static void Warning(object x, int debugLevel = 0)
{
OnWarning?.Invoke(x.ToString());
}
#if UNITY_64
[HideInCallstack]
#endif
public static void Warning<T>(object x, int debugLevel = 0)
{
Warning($"{typeof(T).Name}:{x}", debugLevel);

View File

@@ -75,18 +75,20 @@ namespace BITKit
if (netReaders.TryGetValue(typeName, out var netReader))
return netReader.ReadBinaryAsObject(reader);
var json = reader.ReadString();
if (string.IsNullOrEmpty(json))
{
throw new Exception($"从二进制中读取的json值为空");
}
try
{
if (BITSharp.TryGetTypeFromFullName(typeName, out var type))
return JsonConvert.DeserializeObject(json, type);
}
catch (Exception)
catch (Exception e)
{
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
throw;
BIT4Log.LogException(e);
}
throw new Exception("未找到读取该二进制的BinaryReader");
}
@@ -126,16 +128,8 @@ namespace BITKit
{
netReader.WriteBinaryAsObject(writer,value);
}
#if NET5_0_OR_GREATER
else if( value is IBinarySerialize serialize)
{
serialize.Write(writer);
}
#endif
else
{
//throw new Exception($"没有找到{value.GetType().Name}的Binary写入方法");
writer.Write(value!.GetType().FullName!);
writer.Write(JsonConvert.SerializeObject(value));
}
}

View File

@@ -2,8 +2,5 @@ using System;
namespace BITKit
{
public interface IServiceRegister
{
Type BaseType { get; }
}
}

View File

@@ -9,6 +9,7 @@ namespace BITKit
/// <typeparam name="T"></typeparam>
public interface IDoubleBuffer<T>
{
bool CanRelease { get; }
T Current { get; }
void Release(T newValue);
event Action<T> OnRelease;
@@ -20,6 +21,8 @@ namespace BITKit
/// <typeparam name="T"></typeparam>
public class DoubleBuffer<T> : IDoubleBuffer<T>
{
public bool CanRelease => _release.Allow;
public T Current
{
get;
@@ -31,14 +34,23 @@ namespace BITKit
{
Current = newValue;
OnRelease?.Invoke(newValue);
_release.SetValueThenAllow(newValue);
}
public void Clear()
{
_release.Clear();
}
public event Action<T> OnRelease;
private readonly Queue<T> _releases = new();
private readonly Optional<T> _release=new();
public bool TryGetRelease(out T result)
{
return _releases.TryDequeue(out result);
result = _release.Value;
if (!_release.Allow) return _release.Allow;
_release.Clear();
return true;
}
}
}

View File

@@ -17,6 +17,7 @@ namespace BITKit.Core.Entites
IEntityComponent[] Components { get; }
bool RegisterComponent<T>(T component);
IServiceProvider ServiceProvider { get; }
void Inject(object obj);
}
/// <summary>
/// 基本实体组件

View File

@@ -1,16 +1,38 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace BITKit
{
public static class FuncExtensions
{
public static IEnumerable<Func<T0,T1>> CastAsFunc<T0,T1>(this Func<T0,T1> self)
{
return self.GetInvocationList().Cast<Func<T0, T1>>();
}
}
public static class FuncExtensions
{
public static IEnumerable<Func<T0, T1>> CastAsFunc<T0, T1>(this Func<T0, T1> self)
{
return self?.GetInvocationList().Cast<Func<T0, T1>>();
}
public static IEnumerable<Func<T0, T1, T2>> CastAsFunc<T0, T1, T2>(this Func<T0, T1, T2> self)
{
if (self is null)
{
yield break;
}
Delegate[] invocationList = self.GetInvocationList();
// 遍历委托数组,将每个委托转换为 Func<T0, T1, T2> 并返回
foreach (var delegateItem in invocationList)
{
if (delegateItem is not null && delegateItem is Func<T0, T1, T2> func)
{
yield return func;
}
}
}
public static IEnumerable<Func<T0, T1, T2, T3>> CastAsFunc<T0, T1, T2, T3>(this Func<T0, T1, T2, T3> self)
{
return self?.GetInvocationList().Cast<Func<T0, T1, T2, T3>>();
}
}
}

View File

@@ -1,13 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Cysharp.Threading.Tasks;
// ReSharper disable MethodHasAsyncOverload
namespace BITKit
{
public interface IEntryGroup { }
public interface IEntryGroup
{
}
public interface IEntryElement
{
bool IsEntered { get; set; }
void Entry();
UniTask EntryAsync();
void Exit();
UniTask ExitAsync();
}
[System.Serializable]
@@ -15,7 +24,11 @@ namespace BITKit
{
public int index = -1;
public List<T> list = new();
int m_index;
private int m_index = -1;
private bool completed=true;
public event Action<T> OnEntry;
public event Action<T> OnExit;
public void Entry(T t)
{
if (t is not null)
@@ -60,24 +73,53 @@ namespace BITKit
value = default;
return false;
}
private void EnsureConfiguration()
private async void EnsureConfiguration()
{
if (MathE.Equals(this.index, m_index))
try
{
if(completed is false) return;
completed = false;
if (index == m_index)
{
}
else
{
var currentIndex = m_index;
m_index = index;
if (currentIndex is not -1 && list.TryGetElementAt(currentIndex, out var element))
{
element.Exit();
try
{
await element.ExitAsync();
}
catch (OperationCanceledException)
{
}
element.IsEntered = false;
OnExit?.Invoke(element);
}
if (index is not -1 && list.TryGetElementAt(index, out element))
{
element.IsEntered = true;
element.Entry();
try
{
await element.EntryAsync();
}
catch (OperationCanceledException){}
OnEntry?.Invoke(element);
}
}
completed = true;
}
else
catch (Exception e)
{
if (m_index is not -1)
{
list[m_index].Exit();
}
if (index is not -1)
{
list[index].Entry();
}
BIT4Log.LogException(e);
}
m_index = index;
}
}
}

View File

@@ -73,10 +73,10 @@ namespace BITKit
#endregion
#region
/// <summary>
/// 可序列化的物品
/// 被托管的物品
/// </summary>
[Serializable]
public record SerializableItem : IBasicItem
public record ManagedItem : IBasicItem
{
#region
public int Id;

View File

@@ -41,6 +41,7 @@ namespace BITKit
/// 通过通过Id丢下物品
/// </summary>
bool Drop(int Id);
bool DropOrSpawn(IBasicItem item);
/// <summary>
/// 注册添加物品的工厂方法,
/// </summary>
@@ -58,6 +59,10 @@ namespace BITKit
/// </summary>
event Action<IBasicItem> OnAdd;
/// <summary>
/// 已使用Item的回调
/// </summary>
event Action<IBasicItem> OnUsed;
/// <summary>
/// 已移除Item的回调
/// </summary>
event Action<IBasicItem> OnRemove;

View File

@@ -7,7 +7,7 @@ namespace BITKit.Net
public static readonly KcpConfig Config = new KcpConfig(
NoDelay: true,
DualMode: false,
Interval: 1, // 1ms so at interval code at least runs.
Interval: 200, // 1ms so at interval code at least runs.
Timeout: 2000,
CongestionWindow: false

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Timers;
using Cysharp.Threading.Tasks;
using kcp2k;
@@ -21,6 +22,9 @@ namespace BITKit.Net
public int Ping => -1;
public int Id { get; private set; } = -1;
private readonly KcpClient client;
private readonly Queue<byte[]> commandQueue = new();
private readonly Timer _timer = new(100)
{
AutoReset = true
@@ -46,7 +50,15 @@ namespace BITKit.Net
private void Tick(object sender, ElapsedEventArgs e)
{
client.Tick();
//await UniTask.SwitchToThreadPool();
while (commandQueue.TryDequeue(out var bytes))
{
client.Send(bytes, KcpChannel.Reliable);
}
//for (var i = 0; i < 32; i++)
{
client.Tick();
}
}
public async void Disconnect()
@@ -79,6 +91,10 @@ namespace BITKit.Net
if (BITApp.SynchronizationContext is not null)
await UniTask.SwitchToSynchronizationContext(BITApp.SynchronizationContext);
OnConnected?.Invoke();
if (client.connected)
{
SendServerMessage(Environment.MachineName);
}
return client.connected;
}
catch (Exception e)
@@ -108,8 +124,7 @@ namespace BITKit.Net
case NetCommandType.Command:
var command = BITBinary.Read(reader);
if (command is object[] { Length: 1 } objs) command = objs[0];
// BIT4Log.Log<KcpClient>(
// $"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
//BIT4Log.Log<KcpClient>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
try
{
if (BITApp.SynchronizationContext is not null)
@@ -249,7 +264,8 @@ namespace BITKit.Net
.Write((byte)commandType)
.WriteObject(values)
.Build();
client.Send(bytes, KcpChannel.Reliable);
commandQueue.Enqueue(bytes);
//client.Send(bytes, KcpChannel.Reliable);
}
}

View File

@@ -14,7 +14,7 @@ namespace BITKit.Net
{
public class KCPNetServer:INetServer,INetProvider
{
public event Action<int> OnClientConnect;
public event Action<int> OnClientConnected;
public event Action<int> OnClientDisconnected;
public event Action OnStartServer;
public event Action OnStopServer;
@@ -41,7 +41,7 @@ namespace BITKit.Net
private void Tick(object sender, ElapsedEventArgs e)
{
if (server.IsActive() is false) return;
server.Tick();
server.Tick();
}
public void StartServer(ushort port = 27014)
@@ -66,7 +66,7 @@ namespace BITKit.Net
{
foreach (var Id in server.connections.Keys)
{
SendMessageToClient(Id,message);
}
}
@@ -74,6 +74,9 @@ namespace BITKit.Net
new Dictionary<int, EndPoint>(
server.connections.Select(x => new KeyValuePair<int, EndPoint>(x.Key, x.Value.remoteEndPoint)
));
public void Tick() => server.Tick();
public void HandShake()
{
@@ -85,7 +88,7 @@ namespace BITKit.Net
private void OnConnected(int Id)
{
OnClientConnect?.Invoke(Id);
OnClientConnected?.Invoke(Id);
ClientCommand(Id,new NetClientAllocateIdCommand
{
Id = Id,
@@ -105,8 +108,11 @@ namespace BITKit.Net
using var ms = new MemoryStream(bytes.ToArray());
using var reader = new BinaryReader(ms);
//BIT4Log.Log<INetServer>(Id);
var type = (NetCommandType)ms.ReadByte();
//BIT4Log.Log<INetServer>(type);
switch (type)
{
case NetCommandType.Message:
@@ -114,9 +120,12 @@ namespace BITKit.Net
break;
case NetCommandType.Command:
var command = BITBinary.Read(reader);
if (command is object[] objs && objs.Length is 1) command = objs[0];
if (command is object[] { Length: 1 } objs) command = objs[0];
//BIT4Log.Log<KCPNetServer>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
_events.Invoke(command.GetType().FullName, command);
(int Id,object Command) tuple = (Id,command);
_events.InvokeDirect(command.GetType().FullName,tuple);
break;
case NetCommandType.Heartbeat:
server.Send(Id,new byte[]{(byte)NetCommandType.Heartbeat}, KcpChannel.Reliable);
@@ -179,6 +188,24 @@ namespace BITKit.Net
{
_events.AddListener<T>(handle);
}
public void AddCommandListenerWithId<T>(Action<int, T> handle)
{
_events.AddListenerDirect(typeof(T).FullName, Callback);
return;
void Callback(object value)
{
if (value is ValueTuple<int, object> tuple && tuple.Item2 is T)
{
handle.Invoke(tuple.Item1, (T)tuple.Item2);
}
else
{
Console.WriteLine(value);
}
}
}
public void RemoveCommandListener<T>(Action<T> handle)
{

View File

@@ -141,7 +141,7 @@ namespace BITKit
/// <summary>
/// 回调:当客户端连接时
/// </summary>
public event Action<int> OnClientConnect;
public event Action<int> OnClientConnected;
/// <summary>
/// 回调:当客户端断开连接时
@@ -188,6 +188,13 @@ namespace BITKit
/// 所有已连接的客户端
/// </summary>
public IDictionary<int,EndPoint> Connections { get; }
/// <summary>
/// 添加远程命令监听,包括客户端Id
/// </summary>
/// <param name="handle"></param>
/// <typeparam name="T"></typeparam>
void AddCommandListenerWithId<T>(Action<int,T> handle);
}
/// <summary>
/// 基本网络客户端的接口定义,包括了基本客户端的功能

View File

@@ -45,8 +45,8 @@ namespace BITKit.UX
}
public abstract class UXPanelImplement:IUXPanel
{
protected virtual IUXPanel _iuxPanelImplementation1 { get; }
protected abstract IUXPanel _iuxPanelImplementation { get; }
protected abstract IUXPanel service { get; }
private IUXPanel _iuxPanelImplementation => service;
public bool IsAnimate => _iuxPanelImplementation.IsAnimate;
public bool IsValid => _iuxPanelImplementation.IsValid;
@@ -69,14 +69,14 @@ namespace BITKit.UX
public event Action OnEntry
{
add => _iuxPanelImplementation1.OnEntry += value;
remove => _iuxPanelImplementation1.OnEntry -= value;
add => _iuxPanelImplementation.OnEntry += value;
remove => _iuxPanelImplementation.OnEntry -= value;
}
public event Action OnExit
{
add => _iuxPanelImplementation1.OnExit += value;
remove => _iuxPanelImplementation1.OnExit -= value;
add => _iuxPanelImplementation.OnExit += value;
remove => _iuxPanelImplementation.OnExit -= value;
}
}
}

View File

@@ -30,6 +30,7 @@ namespace BITKit
public const string Input = "Input";
public const string Output = "Output";
public const string Graphic = "Graphic";
public const string HotFix = "HotFix";
}
public partial struct Animation
{

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BITKit
{
/// <summary>泛型事件,简单的事件接口</summary>
@@ -39,6 +40,12 @@ namespace BITKit
var list = events.Get(key);
list.Add(action);
}
public void AddListenerDirect(string key, Action<object> action)
{
events.Get(key).Add(action);
}
public void Invoke<T>(string key, T value)
{
key = key.GetType<T>();
@@ -52,6 +59,32 @@ namespace BITKit
}
});
}
public void InvokeDirect(string key,object value)
{
foreach (var x in events.Get(key))
{
if (x is Action<object> action)
{
//Console.WriteLine(action.Method);
action.Invoke(value);
}
else
{
throw new ArgumentException($"事件{key}的监听器{x}不是Action<object>类型");
}
}
// list.ToArray().ForEach(x =>
// {
// if (x is Action<object> action)
// {
// action.Invoke(value);
// }
// else
// {
// Console.WriteLine(x);
// }
// });
}
public void Invoke(string typeName, object value)
{
var key = $"{typeName}.{defaultEventName}";
@@ -80,6 +113,7 @@ namespace BITKit
public void Set<T>(T value) => dictionary.Set(Constant.System.Internal.GetType<T>(), value);
public void Set<T>(string key, T value) => dictionary.Set(key.GetType<T>(), value);
public void Set(Type type, object value) => dictionary.Set($"{type.FullName}.{Constant.System.Internal}", value);
public void SetDirect(string key, object value) => dictionary.Set(key, value);
public void RemoveListener<T>(string key, Action<T> action)
{
key = key.GetType<T>();
@@ -115,5 +149,10 @@ namespace BITKit
}
public void Invoke<T>() where T : new() => Invoke(new T());
public bool TryGetObjectDirect(string key, out object value)
{
return dictionary.TryGetValue(key, out value);
}
}
}