mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 20:34:29 +08:00
refactor(state): 将历史快照属性改为方法并优化批处理逻辑
- 将 HistoryEntries 属性替换为 GetHistoryEntriesSnapshot() 方法,明确表达会返回集合副本 - 在批处理清理逻辑中添加 else 条件避免无效操作 - 更新测试代码使用新的快照获取方法 - 添加 System.Diagnostics 命名空间引用 - 修复批处理深度为零时的异常处理逻辑
This commit is contained in:
parent
bd29475748
commit
e5da5aa801
@ -52,15 +52,16 @@ public interface IStoreDiagnostics<TState>
|
||||
/// </summary>
|
||||
int HistoryIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前历史快照列表。
|
||||
/// 调试工具可以基于该列表渲染时间旅行面板,而不需要访问 Store 内部结构。
|
||||
/// </summary>
|
||||
IReadOnlyList<StoreHistoryEntry<TState>> HistoryEntries { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前是否处于批处理阶段。
|
||||
/// 该值为 <see langword="true"/> 时,状态变更通知会延迟到最外层批处理结束后再统一发送。
|
||||
/// </summary>
|
||||
bool IsBatching { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前历史快照列表的只读快照。
|
||||
/// 该方法会返回一份独立快照,供调试工具渲染时间旅行面板,而不暴露 Store 的内部可变集合。
|
||||
/// </summary>
|
||||
/// <returns>当前历史快照列表;若未启用历史记录或当前没有历史,则返回空数组。</returns>
|
||||
IReadOnlyList<StoreHistoryEntry<TState>> GetHistoryEntriesSnapshot();
|
||||
}
|
||||
@ -536,7 +536,8 @@ public class StoreTests
|
||||
|
||||
Assert.That(store.State.Count, Is.EqualTo(12));
|
||||
Assert.That(store.CanRedo, Is.False, "新 dispatch 应清除 redo 分支");
|
||||
Assert.That(store.HistoryEntries.Select(entry => entry.State.Count), Is.EqualTo(new[] { 0, 1, 2, 12 }));
|
||||
Assert.That(store.GetHistoryEntriesSnapshot().Select(entry => entry.State.Count),
|
||||
Is.EqualTo(new[] { 0, 1, 2, 12 }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -556,7 +557,7 @@ public class StoreTests
|
||||
Assert.That(store.HistoryCount, Is.EqualTo(1));
|
||||
Assert.That(store.HistoryIndex, Is.EqualTo(0));
|
||||
Assert.That(store.CanUndo, Is.False);
|
||||
Assert.That(store.HistoryEntries[0].State.Count, Is.EqualTo(2));
|
||||
Assert.That(store.GetHistoryEntriesSnapshot()[0].State.Count, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.StateManagement;
|
||||
using GFramework.Core.Events;
|
||||
@ -157,48 +158,6 @@ public sealed class Store<TState> : IStore<TState>, IStoreDiagnostics<TState>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次分发的 action 类型。
|
||||
/// </summary>
|
||||
public Type? LastActionType
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastActionType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次真正改变状态的时间戳。
|
||||
/// </summary>
|
||||
public DateTimeOffset? LastStateChangedAt
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastStateChangedAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前历史快照列表。
|
||||
/// </summary>
|
||||
public IReadOnlyList<StoreHistoryEntry<TState>> HistoryEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _history.Count == 0 ? Array.Empty<StoreHistoryEntry<TState>>() : _history.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前状态快照。
|
||||
/// </summary>
|
||||
@ -369,86 +328,6 @@ public sealed class Store<TState> : IStore<TState>, IStoreDiagnostics<TState>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前订阅者数量。
|
||||
/// </summary>
|
||||
public int SubscriberCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _listeners.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次分发记录。
|
||||
/// </summary>
|
||||
public StoreDispatchRecord<TState>? LastDispatchRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastDispatchRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前 Store 使用的 action 匹配策略。
|
||||
/// </summary>
|
||||
public StoreActionMatchingMode ActionMatchingMode => _actionMatchingMode;
|
||||
|
||||
/// <summary>
|
||||
/// 获取历史缓冲区容量。
|
||||
/// </summary>
|
||||
public int HistoryCapacity => _historyCapacity;
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前可见历史记录数量。
|
||||
/// </summary>
|
||||
public int HistoryCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _history.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前状态在历史缓冲区中的索引。
|
||||
/// </summary>
|
||||
public int HistoryIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _historyIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前是否处于批处理阶段。
|
||||
/// </summary>
|
||||
public bool IsBatching
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _batchDepth > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将多个状态操作合并到一个批处理中执行。
|
||||
/// 批处理内的状态变化会立即提交,但通知会在最外层批处理结束后折叠为一次最终回放。
|
||||
@ -477,16 +356,18 @@ public sealed class Store<TState> : IStore<TState>, IStoreDiagnostics<TState>
|
||||
{
|
||||
if (_batchDepth == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Batch depth is already zero.");
|
||||
Debug.Fail("Batch depth is already zero during RunInBatch cleanup.");
|
||||
}
|
||||
|
||||
_batchDepth--;
|
||||
if (_batchDepth == 0 && _hasPendingBatchNotification)
|
||||
else
|
||||
{
|
||||
notificationState = _pendingBatchState;
|
||||
_pendingBatchState = default!;
|
||||
_hasPendingBatchNotification = false;
|
||||
listenersSnapshot = SnapshotListenersForNotification(notificationState);
|
||||
_batchDepth--;
|
||||
if (_batchDepth == 0 && _hasPendingBatchNotification)
|
||||
{
|
||||
notificationState = _pendingBatchState;
|
||||
_pendingBatchState = default!;
|
||||
_hasPendingBatchNotification = false;
|
||||
listenersSnapshot = SnapshotListenersForNotification(notificationState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -598,6 +479,127 @@ public sealed class Store<TState> : IStore<TState>, IStoreDiagnostics<TState>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次分发的 action 类型。
|
||||
/// </summary>
|
||||
public Type? LastActionType
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastActionType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次真正改变状态的时间戳。
|
||||
/// </summary>
|
||||
public DateTimeOffset? LastStateChangedAt
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastStateChangedAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前订阅者数量。
|
||||
/// </summary>
|
||||
public int SubscriberCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _listeners.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近一次分发记录。
|
||||
/// </summary>
|
||||
public StoreDispatchRecord<TState>? LastDispatchRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _lastDispatchRecord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前 Store 使用的 action 匹配策略。
|
||||
/// </summary>
|
||||
public StoreActionMatchingMode ActionMatchingMode => _actionMatchingMode;
|
||||
|
||||
/// <summary>
|
||||
/// 获取历史缓冲区容量。
|
||||
/// </summary>
|
||||
public int HistoryCapacity => _historyCapacity;
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前可见历史记录数量。
|
||||
/// </summary>
|
||||
public int HistoryCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _history.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前状态在历史缓冲区中的索引。
|
||||
/// </summary>
|
||||
public int HistoryIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _historyIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前是否处于批处理阶段。
|
||||
/// </summary>
|
||||
public bool IsBatching
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _batchDepth > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前历史快照列表的只读快照。
|
||||
/// 该方法以方法语义显式表达会分配并返回集合副本,避免把快照克隆隐藏在属性访问中。
|
||||
/// </summary>
|
||||
/// <returns>当前历史快照列表;若未启用历史记录或当前没有历史,则返回空数组。</returns>
|
||||
public IReadOnlyList<StoreHistoryEntry<TState>> GetHistoryEntriesSnapshot()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _history.Count == 0 ? Array.Empty<StoreHistoryEntry<TState>>() : _history.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个用于当前状态类型的 Store 构建器。
|
||||
/// </summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user