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