diff --git a/Src/Core/Applation/BITApp.cs b/Src/Core/Applation/BITApp.cs index 15f8898..7fcd6f0 100644 --- a/Src/Core/Applation/BITApp.cs +++ b/Src/Core/Applation/BITApp.cs @@ -172,22 +172,16 @@ namespace BITKit /// /// 依赖服务集合 /// - public static ServiceCollection ServiceCollection { get; internal set; } = new(); + public static ServiceCollection ServiceCollection { get; set; } = new(); /// /// 依赖服务提供接口 /// - public static ServiceProvider ServiceProvider { get; private set; } - public static ServiceProvider BuildServiceProvider() + public static ServiceProvider ServiceProvider { - var value = ServiceProvider = ServiceCollection.BuildServiceProvider(); - OnServiceProviderBuild?.Invoke(value); - return value; + get=>_serviceProvider??=ServiceCollection.BuildServiceProvider(); + set => _serviceProvider = value; } - - /// - /// 服务创建后的回调 - /// - public static Action OnServiceProviderBuild; + private static ServiceProvider _serviceProvider; /// /// 主线程 /// diff --git a/Src/Core/Item/Item.cs b/Src/Core/Item/Item.cs index cdf279f..97c2ba2 100644 --- a/Src/Core/Item/Item.cs +++ b/Src/Core/Item/Item.cs @@ -116,7 +116,7 @@ namespace BITKit /// /// 数量 /// - public int Amount { get; } + public int Amount { get; set; } /// /// 运行时属性 diff --git a/Src/Core/Item/ItemContainer.cs b/Src/Core/Item/ItemContainer.cs index d9c36e0..4fb7b03 100644 --- a/Src/Core/Item/ItemContainer.cs +++ b/Src/Core/Item/ItemContainer.cs @@ -15,6 +15,7 @@ namespace BITKit /// public interface IRuntimeItemContainer:IBinarySerialize { + public ValidHandle IsBusy { get; } /// /// 物品容器的唯一Id /// @@ -32,6 +33,11 @@ namespace BITKit /// bool Remove(int id); /// + /// 设置物品 + /// + /// + void Set(IRuntimeItem id); + /// /// 通过通过Id丢下物品 /// bool Drop(int id); @@ -75,6 +81,10 @@ namespace BITKit public class RuntimeItemContainer : IRuntimeItemContainer { + public RuntimeItemContainer() + { + IsBusy.AddListener(x=>OnRelease?.Invoke(!x)); + } public readonly ConcurrentDictionary Items = new(); public void Read(BinaryReader r) { @@ -86,11 +96,13 @@ namespace BITKit throw new NotImplementedException(); } + public ValidHandle IsBusy { get; } = new(); public int Id { get; set; } public IRuntimeItem[] GetItems()=>Items.Values.ToArray(); public bool Add(IRuntimeItem item) { + using var _ = IsBusy.GetHandle(); foreach (var func in AddFactory.CastAsFunc()) { if (func.Invoke(item) is false) @@ -109,6 +121,7 @@ namespace BITKit public bool Remove(int id) { + using var _ = IsBusy.GetHandle(); if (Items.TryGetValue(id, out var item) is false) return false; foreach (var func in RemoveFactory.CastAsFunc()) @@ -124,8 +137,17 @@ namespace BITKit return true; } + public void Set(IRuntimeItem id) + { + using var _ = IsBusy.GetHandle(); + if (!Items.TryGetValue(id.Id, out var item)) return; + item = id; + OnSet?.Invoke(item); + } + public bool Drop(int id) { + using var _ = IsBusy.GetHandle(); if (Items.TryGetValue(id, out var item) is false) return false; foreach (var func in DropFactory.CastAsFunc()) { diff --git a/Src/Core/StateMachine/AsyncStateMachine.cs b/Src/Core/StateMachine/AsyncStateMachine.cs index 5723b67..373ccc7 100644 --- a/Src/Core/StateMachine/AsyncStateMachine.cs +++ b/Src/Core/StateMachine/AsyncStateMachine.cs @@ -1,9 +1,9 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Random = UnityEngine.Random; namespace BITKit.StateMachine { @@ -11,15 +11,8 @@ namespace BITKit.StateMachine /// 动态异步状态机 /// /// 异步状态 - public class AsyncStateMachine:IStateMachine ,IDisposable where T : IStateAsync + public class AsyncStateMachine:IStateMachine ,IDisposable where T : class, IStateAsync { - private enum AsyncState - { - Initializing, - InEntering, - InExiting, - } - private readonly IServiceProvider _serviceProvider; public AsyncStateMachine(IServiceProvider serviceProvider) { @@ -31,113 +24,153 @@ namespace BITKit.StateMachine } public bool Enabled { get; set; } = true; - public T CurrentState { get; set; } + public T CurrentState { get;private set; } + public T NextOrCurrentState => _nextTargetState.IfNotAllow(CurrentState); private T _nextState; public event Action OnStateChanging; public event Action OnStateChanged; public event Action OnStateRegistered; + public IReadOnlyDictionary Dictionary => _dictionary; public event Action OnStateUnRegistered; public IDictionary StateDictionary { get; } = new Dictionary(); + public readonly ValidHandle IsBusy=new(); private readonly CancellationTokenSource _cancellationTokenSource=new(); - private readonly ValidHandle _isBusy=new(); - private readonly ConcurrentQueue<(UniTask task,AsyncState state,T value)> _taskQueue=new(); - public void Initialize() + private readonly Dictionary _dictionary = new(); + private readonly Optional _nextTargetState = new(); + public async void Initialize() { + await IsBusy; + if(_cancellationTokenSource.IsCancellationRequested)return; + using var _ = IsBusy.GetHandle(); foreach (var (_,value) in StateDictionary) { - _taskQueue.Enqueue(new (value.InitializeAsync(),AsyncState.Initializing,value)); + await value.InitializeAsync(); + value.Initialize(); } } + public async void UpdateState(float deltaTime) { - if(Enabled is false)return; - CurrentState?.OnStateUpdate(deltaTime); - if(_isBusy)return; - using var _ = _isBusy.GetHandle(); - if (!_taskQueue.TryDequeue(out var task)) - { - if(Enabled is false)return; - if (CurrentState is not null) - { - await CurrentState.OnStateUpdateAsync(deltaTime); - } - return; - } - await task.task; - if(_cancellationTokenSource.IsCancellationRequested|| Enabled is false)return; - switch (task.state) - { - case AsyncState.Initializing: - task.value.Initialize(); - OnStateRegistered?.Invoke(task.value); - break; - case AsyncState.InEntering: - if (_nextState is not null) - { - _nextState.OnStateEntry(_nextState); - OnStateChanged?.Invoke(CurrentState,_nextState); - } - else - { - OnStateChanged?.Invoke(CurrentState,default); - } - CurrentState = _nextState; - break; - case AsyncState.InExiting: - CurrentState?.OnStateExit(CurrentState,_nextState); - break; - } - - - + if (CurrentState is null) return; + using var _ = IsBusy.GetHandle(); + await CurrentState.OnStateUpdateAsync(deltaTime); + CurrentState.OnStateUpdate(deltaTime); } - public void DisposeState() + + public async void DisposeState() { - _taskQueue.Clear(); - if (CurrentState is not null) - { - _taskQueue.Enqueue(new(CurrentState.OnStateExitAsync(CurrentState,null),AsyncState.InExiting,CurrentState)); - } + await IsBusy; + if(_cancellationTokenSource.IsCancellationRequested)return; + if (CurrentState is null) return; + using var _ = IsBusy.GetHandle(); + await CurrentState.OnStateExitAsync(CurrentState, null); + if(_cancellationTokenSource.IsCancellationRequested)return; + CurrentState.OnStateExit(CurrentState, null); + CurrentState = null; } public T TransitionState() where TState : T { T nextState; - foreach (var (type, value) in StateDictionary) + foreach (var (type, value) in Dictionary) { - if (!type.IsAssignableFrom(typeof(TState))) continue; + if ((typeof(TState) == value.GetType()) is false) continue; + nextState = value; TransitionState(nextState); return nextState; } nextState = _serviceProvider.GetRequiredService(); - _taskQueue.Enqueue(new(nextState.InitializeAsync(),AsyncState.Initializing,nextState)); + return TransitionState(nextState);; } + + public async UniTask TransitionStateAsync(T nextState) + { + if (nextState is not null) + { + if (nextState.Identifier == 0) + { + nextState.Identifier = nextState.GetHashCode(); + } + } + if (Equals(nextState, CurrentState)) return; + if(_nextTargetState.Allow && Equals(_nextTargetState.Value,nextState))return; + if (_nextTargetState.Allow) + { + _nextTargetState.Value = nextState; + return; + } + _nextTargetState.SetValueThenAllow(nextState); + await IsBusy; + if(_cancellationTokenSource.IsCancellationRequested)return; + using var _ = IsBusy.GetHandle(); + OnStateChanging?.Invoke(CurrentState,nextState); + if (_dictionary.TryAdd(nextState.Identifier, nextState)) + { + await nextState.InitializeAsync(); + if(_cancellationTokenSource.IsCancellationRequested)return; + nextState.Initialize(); + } + if (CurrentState is not null) + { + CurrentState.Enabled = false; + await CurrentState.OnStateExitAsync(CurrentState, nextState); + if(_cancellationTokenSource.IsCancellationRequested)return; + CurrentState.OnStateExit(CurrentState,nextState); + } + + var tempState = CurrentState; + CurrentState = _nextTargetState.Value; + _nextTargetState.Clear(); + nextState.Enabled = true; + await nextState.OnStateEntryAsync(tempState); + if(_cancellationTokenSource.IsCancellationRequested)return; + nextState.OnStateEntry(tempState); + OnStateChanged?.Invoke(tempState,nextState); + + } public T TransitionState(T nextState) { - if(Equals(CurrentState,nextState))return nextState; - OnStateChanging?.Invoke(CurrentState,nextState); - if (CurrentState is not null) - { - _taskQueue.Enqueue(new(CurrentState.OnStateExitAsync(CurrentState,nextState),AsyncState.InExiting,CurrentState)); - } - - if (nextState is not null) - { - _taskQueue.Enqueue(new(nextState.OnStateEntryAsync(nextState),AsyncState.InEntering,nextState)); - } - return _nextState= nextState; + TransitionStateAsync(nextState).Forget(); + return nextState; } + public async void UnRegister(T newState) + { + if (newState is null) return; + if (Dictionary.ContainsKey(newState.Identifier) is false) return; + _dictionary.Remove(newState.Identifier); + + if (Equals(CurrentState, newState)) + { + await CurrentState.OnStateExitAsync(CurrentState, null); + CurrentState.OnStateExit(CurrentState, null); + if (CurrentState is IAsyncDisposable asyncDisposable) + { + await asyncDisposable.DisposeAsync(); + } + if (CurrentState is IDisposable disposable) + { + disposable.Dispose(); + } + CurrentState = null; + } + + OnStateUnRegistered?.Invoke(newState); + } public void Dispose() { + if(_isDisposed)return; _cancellationTokenSource.Cancel(); _cancellationTokenSource.Dispose(); + _isDisposed = true; } + + private bool _isDisposed; } } diff --git a/Src/Core/StateMachine/IStateMachine.cs b/Src/Core/StateMachine/IStateMachine.cs index aabe43e..d18a074 100644 --- a/Src/Core/StateMachine/IStateMachine.cs +++ b/Src/Core/StateMachine/IStateMachine.cs @@ -47,7 +47,7 @@ namespace BITKit.StateMachine public interface IStateMachine where T:IState { bool Enabled { get; set; } - T CurrentState { get; set; } + T CurrentState { get; } event Action OnStateChanged; event Action OnStateRegistered; event Action OnStateUnRegistered; diff --git a/Src/Core/Utility/ValidHandle.cs b/Src/Core/Utility/ValidHandle.cs index 3588dce..0369e8a 100644 --- a/Src/Core/Utility/ValidHandle.cs +++ b/Src/Core/Utility/ValidHandle.cs @@ -26,19 +26,37 @@ namespace BITKit public class MyHandle:IDisposable { private readonly ValidHandle _validHandle; - - public MyHandle(ValidHandle validHandle) + private bool _isDisable = false; + public MyHandle(ValidHandle validHandle,bool isDisable = false) { _validHandle = validHandle; - _validHandle.AddElement(this); + + _isDisable = isDisable; + if (isDisable) + { + _validHandle.AddDisableElements(this); + } + else + { + _validHandle.AddElement(this); + } + } public void Dispose() { - _validHandle.RemoveElement(this); + if (_isDisable) + { + _validHandle.RemoveDisableElements(this); + } + else + { + _validHandle.RemoveElement(this); + } } } public MyHandle GetHandle() => new MyHandle(this); + public MyHandle GetDisableHandle()=> new MyHandle(this,true); public override string ToString() { @@ -69,7 +87,7 @@ namespace BITKit public readonly List disableObjs = new List(); private bool tempEnable; private Action EventOnEnableChanged; - private readonly List _completionSources = new(); + private readonly Queue _completionSources = new(); public void AddElement(object obj) @@ -96,7 +114,7 @@ namespace BITKit EventOnEnableChanged.Invoke(enableHandle); } if (tempEnable) return; - foreach (var cs in _completionSources) + if (_completionSources.TryDequeue(out var cs)) { cs.TrySetResult(); } @@ -197,7 +215,7 @@ namespace BITKit return UniTask.CompletedTask.GetAwaiter(); } var cs = new UniTaskCompletionSource(); - _completionSources.Add(cs); + _completionSources.Enqueue(cs); return cs.Task.GetAwaiter(); } public void Clear() diff --git a/Src/Unity/Configs/Input/BITController.inputactions b/Src/Unity/Configs/Input/BITController.inputactions index 6669185..df780ad 100644 --- a/Src/Unity/Configs/Input/BITController.inputactions +++ b/Src/Unity/Configs/Input/BITController.inputactions @@ -72,9 +72,9 @@ "name": "Aim", "type": "Button", "id": "f521b9d3-bfbb-4ce2-85c8-15cb3fcc2534", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", - "interactions": "Tap,Hold,Press", + "interactions": "Press", "initialStateCheck": false }, { @@ -135,7 +135,7 @@ "name": "Primary", "type": "Button", "id": "113a3c02-0fbb-4081-9fac-c39878ddfd09", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "Press,Hold", "initialStateCheck": false @@ -144,7 +144,7 @@ "name": "Secondary", "type": "Button", "id": "57a12f28-2fde-45e5-957f-d8d61afe44de", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "Press,Hold", "initialStateCheck": false @@ -153,7 +153,7 @@ "name": "Tertiary", "type": "Button", "id": "c2535f43-fec8-42bd-b680-6d1cee5246e5", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "Press,Hold", "initialStateCheck": false @@ -162,7 +162,7 @@ "name": "Quaternary", "type": "Button", "id": "6740f3a7-7571-4277-96e9-15aa08af7302", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "Press,Hold", "initialStateCheck": false @@ -171,7 +171,7 @@ "name": "Quinary", "type": "Button", "id": "97511588-e441-4e27-953e-e60cbea80489", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "", "initialStateCheck": false @@ -180,7 +180,7 @@ "name": "Senary", "type": "Button", "id": "46173186-2ef3-4ab9-8ff4-b94cc113df67", - "expectedControlType": "Button", + "expectedControlType": "", "processors": "", "interactions": "", "initialStateCheck": false diff --git a/Src/Unity/Scripts/Reference/DictionaryReferenceScriptableObject.cs b/Src/Unity/Scripts/Reference/DictionaryReferenceScriptableObject.cs index 4047a02..61f76d3 100644 --- a/Src/Unity/Scripts/Reference/DictionaryReferenceScriptableObject.cs +++ b/Src/Unity/Scripts/Reference/DictionaryReferenceScriptableObject.cs @@ -2,10 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.IO; using AYellowpaper.SerializedCollections; - +using YooAsset; #if UNITY_EDITOR using UnityEditor; -using YooAsset; + #endif using UnityEngine; diff --git a/Src/Unity/Scripts/UX/ContextMenu/UXContextMenu.cs b/Src/Unity/Scripts/UX/ContextMenu/UXContextMenu.cs index 5334e8f..627f6fc 100644 --- a/Src/Unity/Scripts/UX/ContextMenu/UXContextMenu.cs +++ b/Src/Unity/Scripts/UX/ContextMenu/UXContextMenu.cs @@ -111,6 +111,7 @@ namespace BITKit.UX private readonly IUXService _uxService; private VisualElement _root; private VisualElement _container; + private bool _isInitialized = false; public UXContextMenu(IUXService uxService) { _uxService = uxService; @@ -121,7 +122,7 @@ namespace BITKit.UX private async void InitializeAsync() { - var go = new GameObject("UXConsole"); + var go = new GameObject(nameof(UXContextMenu)); Object.DontDestroyOnLoad(go); var document = go.AddComponent(); document.sortingOrder = 1; @@ -143,6 +144,7 @@ namespace BITKit.UX { Close(); }); + _isInitialized = true; Close(); } public void Create(ContextMenuBuilder builder) @@ -166,6 +168,7 @@ namespace BITKit.UX } private void Close() { + if(_isInitialized is false)return; _container.Clear(); _root.SetActive(false); } diff --git a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs index 6355950..fc0697e 100644 --- a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs +++ b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolKitPanel.cs @@ -29,6 +29,7 @@ namespace BITKit.UX public VisualElement RootVisualElement { get; set; } protected VisualTreeAsset VisualTreeAsset { get; private set; } private readonly ValidHandle _isBusy = new(); + public readonly UniTaskCompletionSource WaitUtilInitialized = new(); protected UIToolKitPanel(IUXService uxService) { UXService = uxService; @@ -76,6 +77,8 @@ namespace BITKit.UX UXUtils.Inject(this); RootVisualElement.SetActive(false); + + WaitUtilInitialized.TrySetResult(); } } diff --git a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs deleted file mode 100644 index ace89aa..0000000 --- a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using BITKit.UX; -using UnityEngine; - -public class UIToolkitSubPanel -{ - public UIToolkitSubPanel() - { - } -} diff --git a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs.meta b/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs.meta deleted file mode 100644 index 089228f..0000000 --- a/Src/Unity/Scripts/UX/Service/UI Toolkit/UIToolkitSubPanel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 398253ee7f746d143bbbcd9effab9da1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/Unity/UX/BITQuest.uss b/Src/Unity/UX/BITQuest.uss index 5de42c8..b129ac9 100644 --- a/Src/Unity/UX/BITQuest.uss +++ b/Src/Unity/UX/BITQuest.uss @@ -31,3 +31,4 @@ scale: 1.2 1.2; opacity: 0.5; } + diff --git a/Src/UnityPluginsSupport/AI.meta b/Src/UnityPluginsSupport/AI.meta deleted file mode 100644 index c78dfb6..0000000 --- a/Src/UnityPluginsSupport/AI.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6be2ea5bfce9e6c44b9227b2084f2e85 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/Dreamteck.meta b/Src/UnityPluginsSupport/Dreamteck.meta deleted file mode 100644 index 39c230b..0000000 --- a/Src/UnityPluginsSupport/Dreamteck.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8f39c17a963315c4ea9df830636a76cf -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/KumoKyaku.meta b/Src/UnityPluginsSupport/KumoKyaku.meta deleted file mode 100644 index 10fef94..0000000 --- a/Src/UnityPluginsSupport/KumoKyaku.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ea845eb2a3c47f54c9e70466915ce6f0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/Netcode.meta b/Src/UnityPluginsSupport/Netcode.meta deleted file mode 100644 index a9732bc..0000000 --- a/Src/UnityPluginsSupport/Netcode.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: bb2db3744d41b7e47a230183dc579273 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/NodeCanvas.meta b/Src/UnityPluginsSupport/NodeCanvas.meta deleted file mode 100644 index 3345e5a..0000000 --- a/Src/UnityPluginsSupport/NodeCanvas.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 650ee3d040a06c3409e069a838480a53 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/VisualScripting.meta b/Src/UnityPluginsSupport/VisualScripting.meta deleted file mode 100644 index 25cc98d..0000000 --- a/Src/UnityPluginsSupport/VisualScripting.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3b817d6ebbc547f4f8a3405d33e18c85 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Src/UnityPluginsSupport/WXPusher.meta b/Src/UnityPluginsSupport/WXPusher.meta deleted file mode 100644 index bebabee..0000000 --- a/Src/UnityPluginsSupport/WXPusher.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7e6a775310ef1f845ab84594ee93ed03 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: