diff --git a/AGENTS.md b/AGENTS.md index cff06ee..0998e84 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -158,19 +158,6 @@ dotnet run --project sandbox/Benchmark/Benchmark.csproj -c Release dotnet run --project sandbox/ConsoleApp/ConsoleApp.csproj ``` -## Compatibility APIs - -Legacy callback and alias APIs remain for compatibility, but new code and docs should not prefer them: - -```csharp -DataTableManagerExtension.Preload(() => Console.WriteLine("All loaded")); -var table = DataTableManager.GetDataTable(); -DataTableManager.CreateDataTable(() => Console.WriteLine("DTScene loaded")); -DataTableManager.EnableMemoryManagement(50); -``` - -When touching compatibility behavior, preserve existing tests or add migration-focused tests. - ## Hard constraints - Do not put try/catch blocks around imports. diff --git a/README.md b/README.md index 0c2f85e..94963c9 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ var cachedShard = DataTableManager.GetCached("x001"); var shardIsLoaded = DataTableManager.IsLoaded("x001"); ``` -旧的回调加载、`CreateDataTable*`、`GetDataTable*` 和 `HasDataTable*` 仅作为兼容 API 保留;新代码不要依赖这些别名。 +旧的回调加载、`CreateDataTable*`、`GetDataTable*`、`HasDataTable*`、`EnableMemoryManagement` 等兼容别名已在破坏性清理中移除;代码应直接使用 `LoadAsync` / `GetCached` / `IsLoaded` / `EnableEstimatedMemoryBudget`。 ### 独立上下文 diff --git a/docs/designs/kv-table-design.md b/docs/designs/kv-table-design.md index 7422b5e..bdf8c57 100644 --- a/docs/designs/kv-table-design.md +++ b/docs/designs/kv-table-design.md @@ -55,7 +55,7 @@ var rewards = DTGameConfig.DefaultRewards; 当前实现还会生成动态访问 API: ```csharp -var table = DataTableManager.GetDataTable(); +var table = DataTableManager.GetCached(); table?.TryGetValue("MaxLevel", out int? value); table?.GetValue("MaxLevel"); ``` @@ -114,7 +114,7 @@ table?.GetValue("MaxLevel"); 2. 每个条目写出 key、类型签名和 value payload。 3. 结构化 header 继续使用 v3 header、schema hash、generator version、table full name 和 flags。 -如果后续引入独立 kv payload,可保留 key 到 value 的元数据,方便调试工具和兼容 API 查询。 +如果后续引入独立 kv payload,可保留 key 到 value 的元数据,方便调试工具和调试查询。 ## 与索引和预热的关系 diff --git a/docs/guides/table-types.md b/docs/guides/table-types.md index 4b383e0..58a5ac8 100644 --- a/docs/guides/table-types.md +++ b/docs/guides/table-types.md @@ -52,8 +52,8 @@ ```csharp DTGameConfig.MaxLevel DTGameConfig.EnablePvp -DataTableManager.GetDataTable()?.GetValue("MaxLevel") -DataTableManager.GetDataTable()?.TryGetValue("EnablePvp", out bool? enablePvp) +DataTableManager.GetCached()?.GetValue("MaxLevel") +DataTableManager.GetCached()?.TryGetValue("EnablePvp", out bool? enablePvp) ``` 当前校验与生成规则: diff --git a/docs/planning/agent-engineering-review-2026-07.md b/docs/planning/agent-engineering-review-2026-07.md index 35491f7..46c01d7 100644 --- a/docs/planning/agent-engineering-review-2026-07.md +++ b/docs/planning/agent-engineering-review-2026-07.md @@ -29,17 +29,17 @@ ### 2.1 合理之处 -1. **覆盖面较完整**:当前 Agent 指令包含项目定位、核心组件、生成器结构、常用命令、Unity 说明、测试命令和兼容 API,对新 Agent 有较好的启动帮助。 +1. **覆盖面较完整**:当前 Agent 指令包含项目定位、核心组件、生成器结构、常用命令、Unity 说明、测试命令和历史兼容 API,对新 Agent 有较好的启动帮助。 2. **核心方向与代码基本一致**:异步加载、`GetCached`、LRU 估算缓存、`IDataSource`、`PreheatAsync`、Hook、并发安全等能力在测试与 README 中均能找到对应证据。 3. **面向生成器和运行时双域**:文档同时描述 Excel 生成链路与运行时加载链路,符合 DataTables 既是生成器又是运行时库的项目特点。 -4. **保留兼容信息**:旧回调 API、`GetDataTable*`、`CreateDataTable*` 等兼容入口被提示为旧路径,能减少 Agent 破坏性重构风险。 +4. **保留兼容信息**:旧回调 API、`GetDataTable*`、`CreateDataTable*` 等兼容入口已经进入破坏性清理范围,后续 Agent 应避免恢复这些冗余入口。 ### 2.2 不准确或容易误导的内容 | 问题 | 现状 | 风险 | 建议 | | --- | --- | --- | --- | | 性能收益口径过强 | `30-50%内存优化`、`90%性能提升潜力`、`零延迟` 等表述缺少基准链接 | Agent 可能把目标当成已验证事实,继续扩写宣传性代码或文档 | 改成“目标/预期/需 benchmark 证明”,并链接 `docs/performance` 或 benchmark 命令 | -| API 名称漂移 | Agent 文档示例使用 `EnableMemoryManagement(50)`,README 强调 `EnableEstimatedMemoryBudget(50)` | Agent 可能在新代码中偏向旧别名或不准确命名 | Agent 文档应以 README 当前推荐 API 为准,旧别名放兼容区 | +| API 名称漂移 | Agent 文档示例使用 `EnableMemoryManagement(50)`,README 强调 `EnableEstimatedMemoryBudget(50)` | Agent 可能在新代码中偏向旧别名或不准确命名 | Agent 文档应以 README 当前推荐 API 为准,不再提供旧别名示例 | | 数据源抽象描述过时 | `IDataSource` 被描述为“文件系统、网络、自定义数据源”,但当前 README 已强调可组合装饰器与 payload 缓存边界 | Agent 对数据源管线的缓存/压缩/版本边界理解不足 | 增加“数据源管线任务必须先看 docs/guides/data-source-pipeline.md” | | 生成器架构描述偏粗 | 只描述 T4、并行 Excel、二进制序列化,缺少 v3 schema hash、结构化 header、注册式 parser 等当前重点 | Agent 修改生成器时容易绕开新分层 | 增加 Schema/Validation/Serialization/Diagnostics 任务路由 | | Unity 镜像风险不足 | README 明确 `src/DataTables` 是源,Unity 镜像由构建同步;Agent 文档只说 Unity 路径 | Agent 可能直接编辑 Unity 镜像 | 明确禁止直接编辑 Unity runtime 镜像,除非同步机制本身变更 | @@ -106,7 +106,7 @@ Unity 与服务端双运行时的核心差异在于线程、I/O、平台文件 3. **同步当前推荐 API** - 主示例使用 `EnableEstimatedMemoryBudget`。 - - `EnableMemoryManagement`、旧回调 API、`GetDataTable*` 放在兼容章节。 + - 删除 `EnableMemoryManagement`、旧回调 API、`GetDataTable*` 等兼容章节。 - 验收:新代码示例不再优先展示旧别名。 4. **补充 Unity 镜像与 T4 约束** diff --git a/sandbox/ConsoleApp/Generated/DRDataTableSample.cs b/sandbox/ConsoleApp/Generated/DRDataTableSample.cs index 9c64f5b..9e7b6fb 100644 --- a/sandbox/ConsoleApp/Generated/DRDataTableSample.cs +++ b/sandbox/ConsoleApp/Generated/DRDataTableSample.cs @@ -154,7 +154,7 @@ protected override void OnDataRowsRemoved() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSample? GetById(string dataTableName, int id) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index1.TryGetValue(id, out var result) == true ? result : null; } @@ -164,7 +164,7 @@ protected override void OnDataRowsRemoved() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetById(string dataTableName, int id, out DRDataTableSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index1.TryGetValue(id, out result); } @@ -175,15 +175,10 @@ public static bool TryGetById(string dataTableName, int id, out DRDataTableSampl [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsId(string dataTableName, int id) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index1.ContainsKey(id) == true; } - [Obsolete("Use GetById instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSample? GetRowById(int id) => GetById(id); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSample? GetByColor(ConsoleApp.ColorT color) => GetByColor(string.Empty, color); @@ -191,7 +186,7 @@ public static bool ContainsId(string dataTableName, int id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSample? GetByColor(string dataTableName, ConsoleApp.ColorT color) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index2.TryGetValue(color, out var result) == true ? result : null; } @@ -201,7 +196,7 @@ public static bool ContainsId(string dataTableName, int id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetByColor(string dataTableName, ConsoleApp.ColorT color, out DRDataTableSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index2.TryGetValue(color, out result); } @@ -212,15 +207,10 @@ public static bool TryGetByColor(string dataTableName, ConsoleApp.ColorT color, [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index2.ContainsKey(color) == true; } - [Obsolete("Use GetByColor instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSample? GetRowByColor(ConsoleApp.ColorT color) => GetByColor(color); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSample? GetByIdAndInt16Value(int id, short int16Value) => GetByIdAndInt16Value(string.Empty, id, int16Value); @@ -228,7 +218,7 @@ public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSample? GetByIdAndInt16Value(string dataTableName, int id, short int16Value) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index3.TryGetValue((id, int16Value), out var result) == true ? result : null; } @@ -238,7 +228,7 @@ public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetByIdAndInt16Value(string dataTableName, int id, short int16Value, out DRDataTableSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index3.TryGetValue((id, int16Value), out result); } @@ -249,15 +239,10 @@ public static bool TryGetByIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsIdAndInt16Value(string dataTableName, int id, short int16Value) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index3.ContainsKey((id, int16Value)) == true; } - [Obsolete("Use GetByIdAndInt16Value instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSample? GetRowByIdAndInt16Value(int id, short int16Value) => GetByIdAndInt16Value(id, int16Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByNameAndBoolValue(string name, bool boolValue) => GetManyByNameAndBoolValue(string.Empty, name, boolValue); @@ -265,7 +250,7 @@ public static bool ContainsIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByNameAndBoolValue(string dataTableName, string name, bool boolValue) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index4.TryGetValue((name, boolValue), out var result) == true ? result : null; } @@ -275,15 +260,10 @@ public static bool ContainsIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsNameAndBoolValue(string dataTableName, string name, bool boolValue) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index4.ContainsKey((name, boolValue)) == true; } - [Obsolete("Use GetManyByNameAndBoolValue instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List? GetRowsGroupByNameAndBoolValue(string name, bool boolValue) => GetManyByNameAndBoolValue(name, boolValue) as List; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByName(string name) => GetManyByName(string.Empty, name); @@ -291,7 +271,7 @@ public static bool ContainsNameAndBoolValue(string dataTableName, string name, b [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByName(string dataTableName, string name) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index5.TryGetValue(name, out var result) == true ? result : null; } @@ -301,15 +281,10 @@ public static bool ContainsNameAndBoolValue(string dataTableName, string name, b [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsName(string dataTableName, string name) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index5.ContainsKey(name) == true; } - [Obsolete("Use GetManyByName instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List? GetRowsGroupByName(string name) => GetManyByName(name) as List; - #endregion } diff --git a/sandbox/ConsoleApp/Generated/DRDataTableSplitSample.cs b/sandbox/ConsoleApp/Generated/DRDataTableSplitSample.cs index 5d924f8..33659ed 100644 --- a/sandbox/ConsoleApp/Generated/DRDataTableSplitSample.cs +++ b/sandbox/ConsoleApp/Generated/DRDataTableSplitSample.cs @@ -154,7 +154,7 @@ protected override void OnDataRowsRemoved() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSplitSample? GetById(string dataTableName, int id) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index1.TryGetValue(id, out var result) == true ? result : null; } @@ -164,7 +164,7 @@ protected override void OnDataRowsRemoved() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetById(string dataTableName, int id, out DRDataTableSplitSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index1.TryGetValue(id, out result); } @@ -175,15 +175,10 @@ public static bool TryGetById(string dataTableName, int id, out DRDataTableSplit [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsId(string dataTableName, int id) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index1.ContainsKey(id) == true; } - [Obsolete("Use GetById instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSplitSample? GetRowById(int id) => GetById(id); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSplitSample? GetByColor(ConsoleApp.ColorT color) => GetByColor(string.Empty, color); @@ -191,7 +186,7 @@ public static bool ContainsId(string dataTableName, int id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSplitSample? GetByColor(string dataTableName, ConsoleApp.ColorT color) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index2.TryGetValue(color, out var result) == true ? result : null; } @@ -201,7 +196,7 @@ public static bool ContainsId(string dataTableName, int id) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetByColor(string dataTableName, ConsoleApp.ColorT color, out DRDataTableSplitSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index2.TryGetValue(color, out result); } @@ -212,15 +207,10 @@ public static bool TryGetByColor(string dataTableName, ConsoleApp.ColorT color, [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index2.ContainsKey(color) == true; } - [Obsolete("Use GetByColor instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSplitSample? GetRowByColor(ConsoleApp.ColorT color) => GetByColor(color); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSplitSample? GetByIdAndInt16Value(int id, short int16Value) => GetByIdAndInt16Value(string.Empty, id, int16Value); @@ -228,7 +218,7 @@ public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DRDataTableSplitSample? GetByIdAndInt16Value(string dataTableName, int id, short int16Value) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index3.TryGetValue((id, int16Value), out var result) == true ? result : null; } @@ -238,7 +228,7 @@ public static bool ContainsColor(string dataTableName, ConsoleApp.ColorT color) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetByIdAndInt16Value(string dataTableName, int id, short int16Value, out DRDataTableSplitSample? result) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); result = null; return table != null && table.m_Index3.TryGetValue((id, int16Value), out result); } @@ -249,15 +239,10 @@ public static bool TryGetByIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsIdAndInt16Value(string dataTableName, int id, short int16Value) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index3.ContainsKey((id, int16Value)) == true; } - [Obsolete("Use GetByIdAndInt16Value instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DRDataTableSplitSample? GetRowByIdAndInt16Value(int id, short int16Value) => GetByIdAndInt16Value(id, int16Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByNameAndBoolValue(string name, bool boolValue) => GetManyByNameAndBoolValue(string.Empty, name, boolValue); @@ -265,7 +250,7 @@ public static bool ContainsIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByNameAndBoolValue(string dataTableName, string name, bool boolValue) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index4.TryGetValue((name, boolValue), out var result) == true ? result : null; } @@ -275,15 +260,10 @@ public static bool ContainsIdAndInt16Value(string dataTableName, int id, short i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsNameAndBoolValue(string dataTableName, string name, bool boolValue) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index4.ContainsKey((name, boolValue)) == true; } - [Obsolete("Use GetManyByNameAndBoolValue instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List? GetRowsGroupByNameAndBoolValue(string name, bool boolValue) => GetManyByNameAndBoolValue(name, boolValue) as List; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByName(string name) => GetManyByName(string.Empty, name); @@ -291,7 +271,7 @@ public static bool ContainsNameAndBoolValue(string dataTableName, string name, b [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList? GetManyByName(string dataTableName, string name) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index5.TryGetValue(name, out var result) == true ? result : null; } @@ -301,15 +281,10 @@ public static bool ContainsNameAndBoolValue(string dataTableName, string name, b [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool ContainsName(string dataTableName, string name) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_Index5.ContainsKey(name) == true; } - [Obsolete("Use GetManyByName instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List? GetRowsGroupByName(string name) => GetManyByName(name) as List; - #endregion } diff --git a/sandbox/ConsoleApp/Generated/DRMatrixSample.cs b/sandbox/ConsoleApp/Generated/DRMatrixSample.cs index 8671a31..5500fe1 100644 --- a/sandbox/ConsoleApp/Generated/DRMatrixSample.cs +++ b/sandbox/ConsoleApp/Generated/DRMatrixSample.cs @@ -71,7 +71,7 @@ public static DTMatrixSample Table public static DTMatrixSample GetTable(string dataTableName) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); if (table == null) { throw new InvalidOperationException($"DTMatrixSample '{dataTableName}' is not loaded. Call DataTableManager.LoadAsync(dataTableName) first."); @@ -84,7 +84,7 @@ public static DTMatrixSample GetTable(string dataTableName) /// public static DTMatrixSample? TableOrNull => GetTableOrNull(string.Empty); - public static DTMatrixSample? GetTableOrNull(string dataTableName) => DataTableManager.GetDataTableInternal(dataTableName); + public static DTMatrixSample? GetTableOrNull(string dataTableName) => DataTableManager.GetCached(dataTableName); /// /// 检查数据矩阵是否已加载 (静态方法) @@ -102,7 +102,7 @@ public static DTMatrixSample GetTable(string dataTableName) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool? GetRow(string dataTableName, short key1, long key2) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.Get(key1, key2); } @@ -115,7 +115,7 @@ public static DTMatrixSample GetTable(string dataTableName) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GetRowOrDefault(string dataTableName, short key1, long key2) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table != null ? table.Get(key1, key2)! : default!; } diff --git a/sandbox/ConsoleApp/Generated/DataTableManagerExtension.cs b/sandbox/ConsoleApp/Generated/DataTableManagerExtension.cs index ff54581..e0a2840 100644 --- a/sandbox/ConsoleApp/Generated/DataTableManagerExtension.cs +++ b/sandbox/ConsoleApp/Generated/DataTableManagerExtension.cs @@ -65,84 +65,5 @@ public static ValueTask PreloadAsync(DataTableContext context, Priori Register(context); return context.PreheatAsync(priorities, cancellationToken); } - - /// - /// 预加载所有数据表。 - /// - /// 全部数据表预加载完成时回调。 - /// 单步加载完成时回调。 - [Obsolete("Use DataTableManager.PreloadAllAsync or PreloadAsync(context) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void Preload(Action? onCompleted = default, Action? onProgress = default) - { - const int total = 5; - int done = 0; - - void next() - { - done++; - onProgress?.Invoke((float)done / total); - if (done == total) - { - onCompleted?.Invoke(); - } - }; - - DataTableManager.CreateDataTable(next); - DataTableManager.CreateDataTable(next); - DataTableManager.CreateDataTable("x001", next); - DataTableManager.CreateDataTable("x002", next); - DataTableManager.CreateDataTable(next); - } - - /// - /// 按优先级预加载数据表 - /// - [Obsolete("Use DataTableManager.PreheatAsync or PreloadAsync(context) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void PreloadByPriority(Priority priorities, Action? onCompleted = default, Action? onProgress = default) - { - var selected = new List>(); - if (Priorities.ContainsKey("ConsoleApp.DTColumnTableSample") && (priorities & Priorities["ConsoleApp.DTColumnTableSample"]) != 0) - { - selected.Add(next => DataTableManager.CreateDataTable(next)); - } - if (Priorities.ContainsKey("ConsoleApp.DTDataTableSample") && (priorities & Priorities["ConsoleApp.DTDataTableSample"]) != 0) - { - selected.Add(next => DataTableManager.CreateDataTable(next)); - } - if (Priorities.ContainsKey("ConsoleApp.DTDataTableSplitSample") && (priorities & Priorities["ConsoleApp.DTDataTableSplitSample"]) != 0) - { - selected.Add(next => DataTableManager.CreateDataTable("x001", next)); - selected.Add(next => DataTableManager.CreateDataTable("x002", next)); - } - if (Priorities.ContainsKey("ConsoleApp.DTMatrixSample") && (priorities & Priorities["ConsoleApp.DTMatrixSample"]) != 0) - { - selected.Add(next => DataTableManager.CreateDataTable(next)); - } - - int total = selected.Count; - if (total == 0) - { - onCompleted?.Invoke(); - return; - } - - int done = 0; - void next() - { - done++; - onProgress?.Invoke((float)done / total); - if (done == total) - { - onCompleted?.Invoke(); - } - } - - foreach (var action in selected) - { - action(next); - } - } } } diff --git a/src/DataTables.GeneratorCore/DataMatrixTemplate.cs b/src/DataTables.GeneratorCore/DataMatrixTemplate.cs index 3d46cca..71589cd 100644 --- a/src/DataTables.GeneratorCore/DataMatrixTemplate.cs +++ b/src/DataTables.GeneratorCore/DataMatrixTemplate.cs @@ -1,490 +1,490 @@ -// ------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本: 17.0.0.0 -// -// 对此文件的更改可能导致不正确的行为,如果 -// 重新生成代码,这些更改将会丢失。 -// -// ------------------------------------------------------------------------------ -namespace DataTables.GeneratorCore -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System; - - /// - /// Class to produce the template output - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public partial class DataMatrixTemplate : DataMatrixTemplateBase - { - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write(@"// -#pragma warning disable CS0105 -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. -#pragma warning disable CS8602 // Dereference of a possibly null reference. -using System; -using System.IO; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using DataTables; - -#nullable enable - -"); - if (!string.IsNullOrEmpty(GenerationContext.Namespace)) { - this.Write("namespace "); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.Namespace)); - this.Write("\r\n{\r\n"); - } - this.Write("\r\npublic sealed partial class DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" : DataMatrixBase<"); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(">\n{\n public override ulong SchemaHash => "); - this.Write(this.ToStringHelper.ToStringWithCulture(DataTableSchemaHash.Compute(GenerationContext))); - this.Write("UL;\n\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(string.IsNullOrEmpty(GenerationContext.MatrixDefaultValue) ? string.Empty : "protected override " + BuildTypeString(kValue) + " DefaultValue => " + BuildTypeValueString(kValue, GenerationContext.MatrixDefaultValue) + ";" + Environment.NewLine)); - this.Write("\n public DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("(string name, int capacity) : base(name, capacity)\r\n { }\r\n\r\n public overrid" + - "e bool ParseDataRow(int index, BinaryReader reader)\r\n {\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" "); - this.Write(this.ToStringHelper.ToStringWithCulture(kKey1)); - this.Write(";\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey1))); - this.Write("\r\n\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" "); - this.Write(this.ToStringHelper.ToStringWithCulture(kKey2)); - this.Write(";\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey2))); - this.Write("\r\n\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" "); - this.Write(this.ToStringHelper.ToStringWithCulture(kValue)); - this.Write(";\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kValue))); - this.Write("\r\n\r\n SetDataRow(index, "); - this.Write(this.ToStringHelper.ToStringWithCulture(kKey1)); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(kKey2)); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(kValue)); - this.Write(");\r\n return true;\r\n }\r\n\r\n #region Instance API\r\n\r\n /// \r" + - "\n /// 根据Key1和Key2获取数据值 (实例方法)\r\n /// \r\n [MethodImpl(MethodImpl" + - "Options.AggressiveInlining)]\r\n public "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write("? GetDataRow("); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2)\r\n {\r\n return Get(key1, key2);\r\n }\r\n\r\n /// \r\n /" + - "// 根据Key1和Key2获取数据值,如果不存在则返回默认值 (实例方法)\r\n /// \r\n [MethodImpl(Meth" + - "odImplOptions.AggressiveInlining)]\r\n public "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" GetDataRowOrDefault("); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2)\n {\n return Get(key1, key2)!;\n }\r\n\r\n #endregion\r\n\r\n #reg" + - "ion Static API\r\n\r\n /// \r\n /// 获取数据矩阵实例 - 便于访问基类方法 (静态方法)\r\n ///" + - " \r\n public static DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" Table\n {\n get => GetTable(string.Empty);\n }\n\n public static DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" GetTable(string dataTableName)\n {\n var table = DataTableManager.GetDat" + - "aTableInternal(dataTableName);\n if (table == null)\n {\n throw new Inva" + - "lidOperationException($\"DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" \'{dataTableName}\' is not loaded. Call DataTableManager.LoadAsync(dataTableName) first.\");\n }\n return table;\n }\n\r\n /// \r\n /// 安全获取数据矩阵实例 - 返回null如果未加载 (静态方法)\r\n /// \r\n public sta" + - "tic DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("? TableOrNull => GetTableOrNull(string.Empty);\n\n public static DT"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("? GetTableOrNull(string dataTableName) => DataTableManager.GetDataTableInternal(dataTableName);\n\r\n /// \r\n /// 检查数据矩阵是否已加载 (静态方法)\r\n /// \r\n public static bool IsLoaded => IsTableLoaded(string.Empty);\n\n publi" + - "c static bool IsTableLoaded(string dataTableName) => DataTableManager.IsLoaded(dataTableName);\n\r\n /// \r\n /// 根据Key1和Key2获取数据值 (静态方法)\r\n /// <" + - "/summary>\r\n [MethodImpl(MethodImplOptions.AggressiveInlining)]\n public sta" + - "tic "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write("? GetRow("); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2) => GetRow(string.Empty, key1, key2);\n\n [MethodImpl(MethodImplOptions.Ag" + - "gressiveInlining)]\n public static "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write("? GetRow(string dataTableName, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2)\n {\n var table = DataTableManager.GetDataTableInternal(dataTableName);\n return table?.Get(key1, key2);\n }\n\r\n /// \r\n /// 根据Key1和Key2获取数据值,如果不存在则返回默认值 (静态方法)\r\n /// \r\n [MethodI" + - "mpl(MethodImplOptions.AggressiveInlining)]\n public static "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" GetRowOrDefault("); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2) => GetRowOrDefault(string.Empty, key1, key2);\n\n [MethodImpl(MethodImplO" + - "ptions.AggressiveInlining)]\n public static "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" GetRowOrDefault(string dataTableName, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" key1, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" key2)\n {\n var table = DataTableManager.GetDataTableInternal(dataTableName);\n return table != null ? table.Get(key1, key2)! : default" + - "!;\n }\n\r\n #endregion\r\n\r\n #region MatrixDataRow Support\r\n\r\n /// \r\n /// 创建数据行实例\r\n /// \r\n protected override MatrixDataRowBa" + - "se<"); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write("> CreateDataRowInstance()\r\n {\r\n return new DR"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("();\r\n }\r\n\r\n #endregion\r\n}\r\n\r\n/// \r\n/// "); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" 的数据行类 - 包含RowKey、ColumnKey和Value\r\n/// \r\npublic sealed class DR"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write(" : MatrixDataRowBase<"); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(", "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(">\r\n{\r\n /// \r\n /// 构造函数\r\n /// \r\n public DR"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("() : base()\r\n {\r\n }\r\n\r\n /// \r\n /// 构造函数\r\n /// \r" + - "\n /// 行键\r\n /// 列键\r\n /// 值\r\n public DR"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); - this.Write("("); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" rowKey, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" columnKey, "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" value) \r\n : base(rowKey, columnKey, value)\r\n {\r\n }\r\n\r\n /// \r\n /// 从二进制读取器反序列化\r\n /// \r\n public override bool Deserial" + - "ize(BinaryReader reader)\r\n {\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); - this.Write(" rowKey;\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey1).Replace(kKey1, "rowKey"))); - this.Write("\r\n\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); - this.Write(" columnKey;\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey2).Replace(kKey2, "columnKey"))); - this.Write("\r\n\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); - this.Write(" value;\r\n "); - this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kValue).Replace(kValue, "value"))); - this.Write("\r\n\r\n SetData(rowKey, columnKey, value);\r\n return true;\r\n }\r\n}\r\n\r" + - "\n"); - if (!string.IsNullOrEmpty(GenerationContext.Namespace)) { - this.Write("}\r\n"); - } - return this.GenerationEnvironment.ToString(); - } - } - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public class DataMatrixTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - public System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} +// ------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 17.0.0.0 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,这些更改将会丢失。 +// +// ------------------------------------------------------------------------------ +namespace DataTables.GeneratorCore +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System; + + /// + /// Class to produce the template output + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class DataMatrixTemplate : DataMatrixTemplateBase + { + /// + /// Create the template output + /// + public virtual string TransformText() + { + this.Write(@"// +#pragma warning disable CS0105 +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. +#pragma warning disable CS8602 // Dereference of a possibly null reference. +using System; +using System.IO; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using DataTables; + +#nullable enable + +"); + if (!string.IsNullOrEmpty(GenerationContext.Namespace)) { + this.Write("namespace "); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.Namespace)); + this.Write("\r\n{\r\n"); + } + this.Write("\r\npublic sealed partial class DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" : DataMatrixBase<"); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(">\n{\n public override ulong SchemaHash => "); + this.Write(this.ToStringHelper.ToStringWithCulture(DataTableSchemaHash.Compute(GenerationContext))); + this.Write("UL;\n\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(string.IsNullOrEmpty(GenerationContext.MatrixDefaultValue) ? string.Empty : "protected override " + BuildTypeString(kValue) + " DefaultValue => " + BuildTypeValueString(kValue, GenerationContext.MatrixDefaultValue) + ";" + Environment.NewLine)); + this.Write("\n public DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("(string name, int capacity) : base(name, capacity)\r\n { }\r\n\r\n public overrid" + + "e bool ParseDataRow(int index, BinaryReader reader)\r\n {\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" "); + this.Write(this.ToStringHelper.ToStringWithCulture(kKey1)); + this.Write(";\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey1))); + this.Write("\r\n\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" "); + this.Write(this.ToStringHelper.ToStringWithCulture(kKey2)); + this.Write(";\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey2))); + this.Write("\r\n\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" "); + this.Write(this.ToStringHelper.ToStringWithCulture(kValue)); + this.Write(";\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kValue))); + this.Write("\r\n\r\n SetDataRow(index, "); + this.Write(this.ToStringHelper.ToStringWithCulture(kKey1)); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(kKey2)); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(kValue)); + this.Write(");\r\n return true;\r\n }\r\n\r\n #region Instance API\r\n\r\n /// \r" + + "\n /// 根据Key1和Key2获取数据值 (实例方法)\r\n /// \r\n [MethodImpl(MethodImpl" + + "Options.AggressiveInlining)]\r\n public "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write("? GetDataRow("); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2)\r\n {\r\n return Get(key1, key2);\r\n }\r\n\r\n /// \r\n /" + + "// 根据Key1和Key2获取数据值,如果不存在则返回默认值 (实例方法)\r\n /// \r\n [MethodImpl(Meth" + + "odImplOptions.AggressiveInlining)]\r\n public "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" GetDataRowOrDefault("); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2)\n {\n return Get(key1, key2)!;\n }\r\n\r\n #endregion\r\n\r\n #reg" + + "ion Static API\r\n\r\n /// \r\n /// 获取数据矩阵实例 - 便于访问基类方法 (静态方法)\r\n ///" + + " \r\n public static DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" Table\n {\n get => GetTable(string.Empty);\n }\n\n public static DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" GetTable(string dataTableName)\n {\n var table = DataTableManager.GetCac" + + "hed(dataTableName);\n if (table == null)\n {\n throw new Inva" + + "lidOperationException($\"DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" \'{dataTableName}\' is not loaded. Call DataTableManager.LoadAsync(dataTableName) first.\");\n }\n return table;\n }\n\r\n /// \r\n /// 安全获取数据矩阵实例 - 返回null如果未加载 (静态方法)\r\n /// \r\n public sta" + + "tic DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("? TableOrNull => GetTableOrNull(string.Empty);\n\n public static DT"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("? GetTableOrNull(string dataTableName) => DataTableManager.GetCached(dataTableName);\n\r\n /// \r\n /// 检查数据矩阵是否已加载 (静态方法)\r\n /// \r\n public static bool IsLoaded => IsTableLoaded(string.Empty);\n\n publi" + + "c static bool IsTableLoaded(string dataTableName) => DataTableManager.IsLoaded(dataTableName);\n\r\n /// \r\n /// 根据Key1和Key2获取数据值 (静态方法)\r\n /// <" + + "/summary>\r\n [MethodImpl(MethodImplOptions.AggressiveInlining)]\n public sta" + + "tic "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write("? GetRow("); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2) => GetRow(string.Empty, key1, key2);\n\n [MethodImpl(MethodImplOptions.Ag" + + "gressiveInlining)]\n public static "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write("? GetRow(string dataTableName, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2)\n {\n var table = DataTableManager.GetCached(dataTableName);\n return table?.Get(key1, key2);\n }\n\r\n /// \r\n /// 根据Key1和Key2获取数据值,如果不存在则返回默认值 (静态方法)\r\n /// \r\n [MethodI" + + "mpl(MethodImplOptions.AggressiveInlining)]\n public static "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" GetRowOrDefault("); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2) => GetRowOrDefault(string.Empty, key1, key2);\n\n [MethodImpl(MethodImplO" + + "ptions.AggressiveInlining)]\n public static "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" GetRowOrDefault(string dataTableName, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" key1, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" key2)\n {\n var table = DataTableManager.GetCached(dataTableName);\n return table != null ? table.Get(key1, key2)! : default" + + "!;\n }\n\r\n #endregion\r\n\r\n #region MatrixDataRow Support\r\n\r\n /// \r\n /// 创建数据行实例\r\n /// \r\n protected override MatrixDataRowBa" + + "se<"); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write("> CreateDataRowInstance()\r\n {\r\n return new DR"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("();\r\n }\r\n\r\n #endregion\r\n}\r\n\r\n/// \r\n/// "); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" 的数据行类 - 包含RowKey、ColumnKey和Value\r\n/// \r\npublic sealed class DR"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write(" : MatrixDataRowBase<"); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(", "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(">\r\n{\r\n /// \r\n /// 构造函数\r\n /// \r\n public DR"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("() : base()\r\n {\r\n }\r\n\r\n /// \r\n /// 构造函数\r\n /// \r" + + "\n /// 行键\r\n /// 列键\r\n /// 值\r\n public DR"); + this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.ClassName)); + this.Write("("); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" rowKey, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" columnKey, "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" value) \r\n : base(rowKey, columnKey, value)\r\n {\r\n }\r\n\r\n /// \r\n /// 从二进制读取器反序列化\r\n /// \r\n public override bool Deserial" + + "ize(BinaryReader reader)\r\n {\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey1))); + this.Write(" rowKey;\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey1).Replace(kKey1, "rowKey"))); + this.Write("\r\n\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kKey2))); + this.Write(" columnKey;\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kKey2).Replace(kKey2, "columnKey"))); + this.Write("\r\n\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildTypeString(kValue))); + this.Write(" value;\r\n "); + this.Write(this.ToStringHelper.ToStringWithCulture(BuildDeserializeMethodString(kValue).Replace(kValue, "value"))); + this.Write("\r\n\r\n SetData(rowKey, columnKey, value);\r\n return true;\r\n }\r\n}\r\n\r" + + "\n"); + if (!string.IsNullOrEmpty(GenerationContext.Namespace)) { + this.Write("}\r\n"); + } + return this.GenerationEnvironment.ToString(); + } + } + #region Base class + /// + /// Base class for this transformation + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public class DataMatrixTemplateBase + { + #region Fields + private global::System.Text.StringBuilder generationEnvironmentField; + private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; + private global::System.Collections.Generic.List indentLengthsField; + private string currentIndentField = ""; + private bool endsWithNewline; + private global::System.Collections.Generic.IDictionary sessionField; + #endregion + #region Properties + /// + /// The string builder that generation-time code is using to assemble generated output + /// + public System.Text.StringBuilder GenerationEnvironment + { + get + { + if ((this.generationEnvironmentField == null)) + { + this.generationEnvironmentField = new global::System.Text.StringBuilder(); + } + return this.generationEnvironmentField; + } + set + { + this.generationEnvironmentField = value; + } + } + /// + /// The error collection for the generation process + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors + { + get + { + if ((this.errorsField == null)) + { + this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); + } + return this.errorsField; + } + } + /// + /// A list of the lengths of each indent that was added with PushIndent + /// + private System.Collections.Generic.List indentLengths + { + get + { + if ((this.indentLengthsField == null)) + { + this.indentLengthsField = new global::System.Collections.Generic.List(); + } + return this.indentLengthsField; + } + } + /// + /// Gets the current indent we use when adding lines to the output + /// + public string CurrentIndent + { + get + { + return this.currentIndentField; + } + } + /// + /// Current transformation session + /// + public virtual global::System.Collections.Generic.IDictionary Session + { + get + { + return this.sessionField; + } + set + { + this.sessionField = value; + } + } + #endregion + #region Transform-time helpers + /// + /// Write text directly into the generated output + /// + public void Write(string textToAppend) + { + if (string.IsNullOrEmpty(textToAppend)) + { + return; + } + // If we're starting off, or if the previous text ended with a newline, + // we have to append the current indent first. + if (((this.GenerationEnvironment.Length == 0) + || this.endsWithNewline)) + { + this.GenerationEnvironment.Append(this.currentIndentField); + this.endsWithNewline = false; + } + // Check if the current text ends with a newline + if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) + { + this.endsWithNewline = true; + } + // This is an optimization. If the current indent is "", then we don't have to do any + // of the more complex stuff further down. + if ((this.currentIndentField.Length == 0)) + { + this.GenerationEnvironment.Append(textToAppend); + return; + } + // Everywhere there is a newline in the text, add an indent after it + textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); + // If the text ends with a newline, then we should strip off the indent added at the very end + // because the appropriate indent will be added when the next time Write() is called + if (this.endsWithNewline) + { + this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); + } + else + { + this.GenerationEnvironment.Append(textToAppend); + } + } + /// + /// Write text directly into the generated output + /// + public void WriteLine(string textToAppend) + { + this.Write(textToAppend); + this.GenerationEnvironment.AppendLine(); + this.endsWithNewline = true; + } + /// + /// Write formatted text directly into the generated output + /// + public void Write(string format, params object[] args) + { + this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Write formatted text directly into the generated output + /// + public void WriteLine(string format, params object[] args) + { + this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Raise an error + /// + public void Error(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + this.Errors.Add(error); + } + /// + /// Raise a warning + /// + public void Warning(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + error.IsWarning = true; + this.Errors.Add(error); + } + /// + /// Increase the indent + /// + public void PushIndent(string indent) + { + if ((indent == null)) + { + throw new global::System.ArgumentNullException("indent"); + } + this.currentIndentField = (this.currentIndentField + indent); + this.indentLengths.Add(indent.Length); + } + /// + /// Remove the last indent that was added with PushIndent + /// + public string PopIndent() + { + string returnValue = ""; + if ((this.indentLengths.Count > 0)) + { + int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; + this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); + if ((indentLength > 0)) + { + returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); + this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); + } + } + return returnValue; + } + /// + /// Remove any indentation + /// + public void ClearIndent() + { + this.indentLengths.Clear(); + this.currentIndentField = ""; + } + #endregion + #region ToString Helpers + /// + /// Utility class to produce culture-oriented representation of an object as a string. + /// + public class ToStringInstanceHelper + { + private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; + /// + /// Gets or sets format provider to be used by ToStringWithCulture method. + /// + public System.IFormatProvider FormatProvider + { + get + { + return this.formatProviderField ; + } + set + { + if ((value != null)) + { + this.formatProviderField = value; + } + } + } + /// + /// This is called from the compile/run appdomain to convert objects within an expression block to a string + /// + public string ToStringWithCulture(object objectToConvert) + { + if ((objectToConvert == null)) + { + throw new global::System.ArgumentNullException("objectToConvert"); + } + System.Type t = objectToConvert.GetType(); + System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { + typeof(System.IFormatProvider)}); + if ((method == null)) + { + return objectToConvert.ToString(); + } + else + { + return ((string)(method.Invoke(objectToConvert, new object[] { + this.formatProviderField }))); + } + } + } + private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); + /// + /// Helper to produce culture-oriented representation of an object as a string + /// + public ToStringInstanceHelper ToStringHelper + { + get + { + return this.toStringHelperField; + } + } + #endregion + } + #endregion +} diff --git a/src/DataTables.GeneratorCore/DataMatrixTemplate.tt b/src/DataTables.GeneratorCore/DataMatrixTemplate.tt index d693008..9c46eb7 100644 --- a/src/DataTables.GeneratorCore/DataMatrixTemplate.tt +++ b/src/DataTables.GeneratorCore/DataMatrixTemplate.tt @@ -77,7 +77,7 @@ public sealed partial class DT<#= GenerationContext.ClassName #> : DataMatrixBas public static DT<#= GenerationContext.ClassName #> GetTable(string dataTableName) { - var table = DataTableManager.GetDataTableInternal>(dataTableName); + var table = DataTableManager.GetCached>(dataTableName); if (table == null) { throw new InvalidOperationException($"DT<#= GenerationContext.ClassName #> '{dataTableName}' is not loaded. Call DataTableManager.LoadAsync>(dataTableName) first."); @@ -90,7 +90,7 @@ public sealed partial class DT<#= GenerationContext.ClassName #> : DataMatrixBas /// public static DT<#= GenerationContext.ClassName #>? TableOrNull => GetTableOrNull(string.Empty); - public static DT<#= GenerationContext.ClassName #>? GetTableOrNull(string dataTableName) => DataTableManager.GetDataTableInternal>(dataTableName); + public static DT<#= GenerationContext.ClassName #>? GetTableOrNull(string dataTableName) => DataTableManager.GetCached>(dataTableName); /// /// 检查数据矩阵是否已加载 (静态方法) @@ -108,7 +108,7 @@ public sealed partial class DT<#= GenerationContext.ClassName #> : DataMatrixBas [MethodImpl(MethodImplOptions.AggressiveInlining)] public static <#= BuildTypeString(kValue) #>? GetRow(string dataTableName, <#= BuildTypeString(kKey1) #> key1, <#= BuildTypeString(kKey2) #> key2) { - var table = DataTableManager.GetDataTableInternal>(dataTableName); + var table = DataTableManager.GetCached>(dataTableName); return table?.Get(key1, key2); } @@ -121,7 +121,7 @@ public sealed partial class DT<#= GenerationContext.ClassName #> : DataMatrixBas [MethodImpl(MethodImplOptions.AggressiveInlining)] public static <#= BuildTypeString(kValue) #> GetRowOrDefault(string dataTableName, <#= BuildTypeString(kKey1) #> key1, <#= BuildTypeString(kKey2) #> key2) { - var table = DataTableManager.GetDataTableInternal>(dataTableName); + var table = DataTableManager.GetCached>(dataTableName); return table != null ? table.Get(key1, key2)! : default!; } diff --git a/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.cs b/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.cs index 159f5a2..7ab2319 100644 --- a/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.cs +++ b/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.cs @@ -137,104 +137,6 @@ public static ValueTask PreloadAsync(DataTableContext context, Priori Register(context); return context.PreheatAsync(priorities, cancellationToken); } - - /// - /// 预加载所有数据表。 - /// - /// 全部数据表预加载完成时回调。 - /// 单步加载完成时回调。 - [Obsolete(""Use DataTableManager.PreloadAllAsync or PreloadAsync(context) instead."")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void Preload(Action? onCompleted = default, Action? onProgress = default) - { - const int total = "); - this.Write(this.ToStringHelper.ToStringWithCulture(DataTables.Sum(pair => pair.Value.Any() ? pair.Value.Count() : 1))); - this.Write(";\r\n int done = 0;\r\n\r\n void next()\r\n {\r\n done++;\r\n" + - " onProgress?.Invoke((float)done / total);\r\n if (done == to" + - "tal)\r\n {\r\n onCompleted?.Invoke();\r\n }\r\n " + - " };\r\n\r\n"); - -foreach (var pair in DataTables) -{ - if (!pair.Value.Any()) - { - - this.Write(" DataTableManager.CreateDataTable<"); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write(">(next);"); - this.Write(this.ToStringHelper.ToStringWithCulture(Environment.NewLine)); - - } - else - { - foreach (var name in pair.Value) - { - - this.Write(" DataTableManager.CreateDataTable<"); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write(">(\""); - this.Write(this.ToStringHelper.ToStringWithCulture(name)); - this.Write("\", next);"); - this.Write(this.ToStringHelper.ToStringWithCulture(Environment.NewLine)); - - } - } -} - - this.Write(@" } - - /// - /// 按优先级预加载数据表 - /// - [Obsolete(""Use DataTableManager.PreheatAsync or PreloadAsync(context) instead."")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void PreloadByPriority(Priority priorities, Action? onCompleted = default, Action? onProgress = default) - { - var selected = new List>(); -"); - foreach (var pair in DataTables) { - this.Write(" if (Priorities.ContainsKey(\""); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write("\") && (priorities & Priorities[\""); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write("\"]) != 0)\r\n {\r\n"); - if (!pair.Value.Any()) { - this.Write(" selected.Add(next => DataTableManager.CreateDataTable<"); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write(">(next));\r\n"); - } else { foreach (var name in pair.Value) { - this.Write(" selected.Add(next => DataTableManager.CreateDataTable<"); - this.Write(this.ToStringHelper.ToStringWithCulture(pair.Key)); - this.Write(">(\""); - this.Write(this.ToStringHelper.ToStringWithCulture(name)); - this.Write("\", next));\r\n"); - } } - this.Write(" }\r\n"); - } - this.Write(@" - int total = selected.Count; - if (total == 0) - { - onCompleted?.Invoke(); - return; - } - - int done = 0; - void next() - { - done++; - onProgress?.Invoke((float)done / total); - if (done == total) - { - onCompleted?.Invoke(); - } - } - - foreach (var action in selected) - { - action(next); - } - } } "); if (!string.IsNullOrEmpty(Namespace)) { diff --git a/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.tt b/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.tt index 157f148..f0f6737 100644 --- a/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.tt +++ b/src/DataTables.GeneratorCore/DataTableManagerExtensionTemplate.tt @@ -83,89 +83,6 @@ public static class DataTableManagerExtension Register(context); return context.PreheatAsync(priorities, cancellationToken); } - - /// - /// 预加载所有数据表。 - /// - /// 全部数据表预加载完成时回调。 - /// 单步加载完成时回调。 - [Obsolete("Use DataTableManager.PreloadAllAsync or PreloadAsync(context) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void Preload(Action? onCompleted = default, Action? onProgress = default) - { - const int total = <#=DataTables.Sum(pair => pair.Value.Any() ? pair.Value.Count() : 1)#>; - int done = 0; - - void next() - { - done++; - onProgress?.Invoke((float)done / total); - if (done == total) - { - onCompleted?.Invoke(); - } - }; - -<# -foreach (var pair in DataTables) -{ - if (!pair.Value.Any()) - { - #> DataTableManager.CreateDataTable<<#=pair.Key#>>(next);<#=Environment.NewLine#><# - } - else - { - foreach (var name in pair.Value) - { - #> DataTableManager.CreateDataTable<<#=pair.Key#>>("<#=name#>", next);<#=Environment.NewLine#><# - } - } -} -#> - } - - /// - /// 按优先级预加载数据表 - /// - [Obsolete("Use DataTableManager.PreheatAsync or PreloadAsync(context) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void PreloadByPriority(Priority priorities, Action? onCompleted = default, Action? onProgress = default) - { - var selected = new List>(); -<# foreach (var pair in DataTables) { #> - if (Priorities.ContainsKey("<#= pair.Key #>") && (priorities & Priorities["<#= pair.Key #>"]) != 0) - { -<# if (!pair.Value.Any()) { #> - selected.Add(next => DataTableManager.CreateDataTable<<#=pair.Key#>>(next)); -<# } else { foreach (var name in pair.Value) { #> - selected.Add(next => DataTableManager.CreateDataTable<<#=pair.Key#>>("<#=name#>", next)); -<# } } #> - } -<# } #> - - int total = selected.Count; - if (total == 0) - { - onCompleted?.Invoke(); - return; - } - - int done = 0; - void next() - { - done++; - onProgress?.Invoke((float)done / total); - if (done == total) - { - onCompleted?.Invoke(); - } - } - - foreach (var action in selected) - { - action(next); - } - } } <# if (!string.IsNullOrEmpty(Namespace)) { #> } diff --git a/src/DataTables.GeneratorCore/DataTableTemplate.cs b/src/DataTables.GeneratorCore/DataTableTemplate.cs index 7021ec5..2e96c29 100644 --- a/src/DataTables.GeneratorCore/DataTableTemplate.cs +++ b/src/DataTables.GeneratorCore/DataTableTemplate.cs @@ -253,7 +253,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(")\n {\n var table = DataTableManager.GetDataTableInternal<"); + this.Write(")\n {\n var table = DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); @@ -281,7 +281,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); this.Write(", out "); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataRowClassName)); - this.Write("? result)\n {\n var table = DataTableManager.GetDataTableInternal<"); + this.Write("? result)\n {\n var table = DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); @@ -305,7 +305,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(")\n {\n var table = DataTableManager.GetDataTableInternal<"); + this.Write(")\n {\n var table = DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); @@ -313,20 +313,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(i + 1)); this.Write(".ContainsKey("); this.Write(this.ToStringHelper.ToStringWithCulture(key)); - this.Write(") == true;\n }\n\n [Obsolete(\"Use GetBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write(" instead.\")]\n [EditorBrowsable(EditorBrowsableState.Never)]\n [MethodImpl(Me" + - "thodImplOptions.AggressiveInlining)]\n public static "); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataRowClassName)); - this.Write("? GetRowBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write("("); - this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(") => GetBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write("("); - this.Write(this.ToStringHelper.ToStringWithCulture(arguments)); - this.Write(");\n"); + this.Write(") == true;\n }\n"); } for (var i = 0; i < GenerationContext.GroupIndexDefinitions.Count; i++) @@ -359,7 +346,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(")\n {\n var table = DataTableManager.GetDataTableInternal<"); + this.Write(")\n {\n var table = DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); @@ -383,7 +370,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(")\n {\n var table = DataTableManager.GetDataTableInternal<"); + this.Write(")\n {\n var table = DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(tableNameParameter)); @@ -391,22 +378,7 @@ public virtual string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(dictNo)); this.Write(".ContainsKey("); this.Write(this.ToStringHelper.ToStringWithCulture(key)); - this.Write(") == true;\n }\n\n [Obsolete(\"Use GetManyBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write(" instead.\")]\n [EditorBrowsable(EditorBrowsableState.Never)]\n [MethodImpl(Me" + - "thodImplOptions.AggressiveInlining)]\n public static List<"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataRowClassName)); - this.Write(">? GetRowsGroupBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write("("); - this.Write(this.ToStringHelper.ToStringWithCulture(parameters)); - this.Write(") => GetManyBy"); - this.Write(this.ToStringHelper.ToStringWithCulture(suffix)); - this.Write("("); - this.Write(this.ToStringHelper.ToStringWithCulture(arguments)); - this.Write(") as List<"); - this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataRowClassName)); - this.Write(">;\n"); + this.Write(") == true;\n }\n"); } diff --git a/src/DataTables.GeneratorCore/DataTableTemplate.tt b/src/DataTables.GeneratorCore/DataTableTemplate.tt index 1879420..1d3a202 100644 --- a/src/DataTables.GeneratorCore/DataTableTemplate.tt +++ b/src/DataTables.GeneratorCore/DataTableTemplate.tt @@ -172,7 +172,7 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static <#= GenerationContext.DataRowClassName #>? GetBy<#= suffix #>(string <#= tableNameParameter #>, <#= parameters #>) { - var table = DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); + var table = DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); return table?.m_Index<#= i + 1 #>.TryGetValue(<#= key #>, out var result) == true ? result : null; } @@ -182,7 +182,7 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetBy<#= suffix #>(string <#= tableNameParameter #>, <#= parameters #>, out <#= GenerationContext.DataRowClassName #>? result) { - var table = DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); + var table = DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); result = null; return table != null && table.m_Index<#= i + 1 #>.TryGetValue(<#= key #>, out result); } @@ -193,14 +193,9 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Contains<#= suffix #>(string <#= tableNameParameter #>, <#= parameters #>) { - var table = DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); + var table = DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); return table?.m_Index<#= i + 1 #>.ContainsKey(<#= key #>) == true; } - - [Obsolete("Use GetBy<#= suffix #> instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static <#= GenerationContext.DataRowClassName #>? GetRowBy<#= suffix #>(<#= parameters #>) => GetBy<#= suffix #>(<#= arguments #>); <# } for (var i = 0; i < GenerationContext.GroupIndexDefinitions.Count; i++) @@ -220,7 +215,7 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IReadOnlyList<<#= GenerationContext.DataRowClassName #>>? GetManyBy<#= suffix #>(string <#= tableNameParameter #>, <#= parameters #>) { - var table = DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); + var table = DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); return table?.m_Index<#= dictNo #>.TryGetValue(<#= key #>, out var result) == true ? result : null; } @@ -230,14 +225,9 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Contains<#= suffix #>(string <#= tableNameParameter #>, <#= parameters #>) { - var table = DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); + var table = DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(<#= tableNameParameter #>); return table?.m_Index<#= dictNo #>.ContainsKey(<#= key #>) == true; } - - [Obsolete("Use GetManyBy<#= suffix #> instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List<<#= GenerationContext.DataRowClassName #>>? GetRowsGroupBy<#= suffix #>(<#= parameters #>) => GetManyBy<#= suffix #>(<#= arguments #>) as List<<#= GenerationContext.DataRowClassName #>>; <# } #> diff --git a/src/DataTables.GeneratorCore/GraphTableTemplate.cs b/src/DataTables.GeneratorCore/GraphTableTemplate.cs index 32da486..f4dd505 100644 --- a/src/DataTables.GeneratorCore/GraphTableTemplate.cs +++ b/src/DataTables.GeneratorCore/GraphTableTemplate.cs @@ -210,7 +210,7 @@ private string BuildGraphApi() WL(" public bool ContainsNode(string nodeId) => GetDataRowsGroupByFrom(nodeId) != null || GetDataRowsGroupByTo(nodeId) != null;"); WL(" public string? GetNode(string nodeId) => ContainsNode(nodeId) ? nodeId : null;"); WL(); - WL($" private static {table}? GetGraphTableStatic(string dataTableName) => DataTableManager.GetDataTableInternal<{table}>(dataTableName);"); + WL($" private static {table}? GetGraphTableStatic(string dataTableName) => DataTableManager.GetCached<{table}>(dataTableName);"); WL($" public static int EdgeCountStatic => GetEdgeCountStatic(string.Empty);"); WL($" public static int GetEdgeCountStatic(string dataTableName) => GetGraphTableStatic(dataTableName)?.EdgeCount ?? 0;"); WL($" public static int NodeCountStatic => GetNodeCountStatic(string.Empty);"); diff --git a/src/DataTables.GeneratorCore/GraphTableTemplate.tt b/src/DataTables.GeneratorCore/GraphTableTemplate.tt index 936072c..c39f4fc 100644 --- a/src/DataTables.GeneratorCore/GraphTableTemplate.tt +++ b/src/DataTables.GeneratorCore/GraphTableTemplate.tt @@ -181,7 +181,7 @@ WL(" public bool ContainsNode(string nodeId) => GetDataRowsGroupByFrom(nodeId) != null || GetDataRowsGroupByTo(nodeId) != null;"); WL(" public string? GetNode(string nodeId) => ContainsNode(nodeId) ? nodeId : null;"); WL(); - WL($" private static {table}? GetGraphTableStatic(string dataTableName) => DataTableManager.GetDataTableInternal<{table}>(dataTableName);"); + WL($" private static {table}? GetGraphTableStatic(string dataTableName) => DataTableManager.GetCached<{table}>(dataTableName);"); WL($" public static int EdgeCountStatic => GetEdgeCountStatic(string.Empty);"); WL($" public static int GetEdgeCountStatic(string dataTableName) => GetGraphTableStatic(dataTableName)?.EdgeCount ?? 0;"); WL($" public static int NodeCountStatic => GetNodeCountStatic(string.Empty);"); diff --git a/src/DataTables.GeneratorCore/KvTableTemplate.cs b/src/DataTables.GeneratorCore/KvTableTemplate.cs index c20b7b7..dc52960 100644 --- a/src/DataTables.GeneratorCore/KvTableTemplate.cs +++ b/src/DataTables.GeneratorCore/KvTableTemplate.cs @@ -62,7 +62,7 @@ public override string TransformText() this.Write(this.ToStringHelper.ToStringWithCulture(GetPropertyTypeString(item))); this.Write(" Get"); this.Write(this.ToStringHelper.ToStringWithCulture(item.Name)); - this.Write("(string dataTableName) => DataTableManager.GetDataTableInternal<"); + this.Write("(string dataTableName) => DataTableManager.GetCached<"); this.Write(this.ToStringHelper.ToStringWithCulture(GenerationContext.DataTableClassName)); this.Write(">(dataTableName)![0]."); this.Write(this.ToStringHelper.ToStringWithCulture(item.Name)); diff --git a/src/DataTables.GeneratorCore/KvTableTemplate.tt b/src/DataTables.GeneratorCore/KvTableTemplate.tt index 6907763..382b34a 100644 --- a/src/DataTables.GeneratorCore/KvTableTemplate.tt +++ b/src/DataTables.GeneratorCore/KvTableTemplate.tt @@ -30,7 +30,7 @@ using DataTables;<# if (!string.IsNullOrEmpty(Using)) { #><#= Environment.NewLin /// <#= BuildSummary(item.Title) #> public static <#= GetPropertyTypeString(item) #> <#= item.Name #> => Get<#= item.Name #>(string.Empty); - public static <#= GetPropertyTypeString(item) #> Get<#= item.Name #>(string dataTableName) => DataTableManager.GetDataTableInternal<<#= GenerationContext.DataTableClassName #>>(dataTableName)![0].<#= item.Name #>; + public static <#= GetPropertyTypeString(item) #> Get<#= item.Name #>(string dataTableName) => DataTableManager.GetCached<<#= GenerationContext.DataTableClassName #>>(dataTableName)![0].<#= item.Name #>; <# } diff --git a/src/DataTables.GeneratorCore/TreeTableTemplate.cs b/src/DataTables.GeneratorCore/TreeTableTemplate.cs index f237c33..c2e0102 100644 --- a/src/DataTables.GeneratorCore/TreeTableTemplate.cs +++ b/src/DataTables.GeneratorCore/TreeTableTemplate.cs @@ -98,13 +98,13 @@ private string BuildTreeApi() WL($" public static IReadOnlyList<{row}> Roots => GetRootsStatic(string.Empty);"); WL($" public static IReadOnlyList<{row}> StaticRoots => Roots;"); WL($" public static IReadOnlyList<{row}> RootsStatic => Roots;"); - WL($" public static IReadOnlyList<{row}> GetRootsStatic(string dataTableName) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetRoots() ?? Array.Empty<{row}>();"); + WL($" public static IReadOnlyList<{row}> GetRootsStatic(string dataTableName) => DataTableManager.GetCached<{table}>(dataTableName)?.GetRoots() ?? Array.Empty<{row}>();"); WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string id) => GetChildrenStatic(string.Empty, id);"); - WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetChildren(id);"); + WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.GetChildren(id);"); WL($" public static {row}? GetParentStatic(string id) => GetParentStatic(string.Empty, id);"); - WL($" public static {row}? GetParentStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetParent(id);"); + WL($" public static {row}? GetParentStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.GetParent(id);"); WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string id) => TraverseDepthFirstStatic(string.Empty, id);"); - WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.TraverseDepthFirst(id) ?? Array.Empty<{row}>();"); + WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.TraverseDepthFirst(id) ?? Array.Empty<{row}>();"); WL(" #endregion"); return sb.ToString(); } diff --git a/src/DataTables.GeneratorCore/TreeTableTemplate.tt b/src/DataTables.GeneratorCore/TreeTableTemplate.tt index cb72139..d3c1e34 100644 --- a/src/DataTables.GeneratorCore/TreeTableTemplate.tt +++ b/src/DataTables.GeneratorCore/TreeTableTemplate.tt @@ -68,13 +68,13 @@ WL($" public static IReadOnlyList<{row}> Roots => GetRootsStatic(string.Empty);"); WL($" public static IReadOnlyList<{row}> StaticRoots => Roots;"); WL($" public static IReadOnlyList<{row}> RootsStatic => Roots;"); - WL($" public static IReadOnlyList<{row}> GetRootsStatic(string dataTableName) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetRoots() ?? Array.Empty<{row}>();"); + WL($" public static IReadOnlyList<{row}> GetRootsStatic(string dataTableName) => DataTableManager.GetCached<{table}>(dataTableName)?.GetRoots() ?? Array.Empty<{row}>();"); WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string id) => GetChildrenStatic(string.Empty, id);"); - WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetChildren(id);"); + WL($" public static IReadOnlyList<{row}>? GetChildrenStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.GetChildren(id);"); WL($" public static {row}? GetParentStatic(string id) => GetParentStatic(string.Empty, id);"); - WL($" public static {row}? GetParentStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.GetParent(id);"); + WL($" public static {row}? GetParentStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.GetParent(id);"); WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string id) => TraverseDepthFirstStatic(string.Empty, id);"); - WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string dataTableName, string id) => DataTableManager.GetDataTableInternal<{table}>(dataTableName)?.TraverseDepthFirst(id) ?? Array.Empty<{row}>();"); + WL($" public static IEnumerable<{row}> TraverseDepthFirstStatic(string dataTableName, string id) => DataTableManager.GetCached<{table}>(dataTableName)?.TraverseDepthFirst(id) ?? Array.Empty<{row}>();"); WL(" #endregion"); return sb.ToString(); } diff --git a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableContext.cs b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableContext.cs index 10d93e6..4a01fce 100644 --- a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableContext.cs +++ b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableContext.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; using System.Threading; @@ -30,9 +29,7 @@ public enum DataTableParseExecution /// /// 独立的数据表运行时上下文。每个实例拥有自己的数据源、加载任务、缓存、生命周期和 Hook。 /// -#pragma warning disable CS0618 - public sealed class DataTableContext : IDataTableContext, IDataTableManager, IDisposable -#pragma warning restore CS0618 + public sealed class DataTableContext : IDataTableContext, IDisposable { private readonly ConcurrentDictionary m_DataTables = new(); private readonly ConcurrentDictionary> m_LoadingTables = new(); @@ -86,10 +83,6 @@ public bool IsEstimatedMemoryBudgetEnabled } } - [Obsolete("Use IsEstimatedMemoryBudgetEnabled instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool IsMemoryManagementEnabled => IsEstimatedMemoryBudgetEnabled; - /// /// Gets or sets where synchronous payload deserialization executes. Payload I/O is always asynchronous. /// @@ -174,10 +167,6 @@ public void EnableEstimatedMemoryBudget(int maxEstimatedMemoryMB, Func EnableEstimatedMemoryBudget(maxMemoryMB); - public void DisableEstimatedMemoryBudget() { ThrowIfDisposed(); @@ -196,10 +185,6 @@ public void DisableEstimatedMemoryBudget() cache.Dispose(); } - [Obsolete("Use DisableEstimatedMemoryBudget() instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void DisableMemoryManagement() => DisableEstimatedMemoryBudget(); - public void EnableProfiling(Action onPerformanceReport) { if (onPerformanceReport == null) throw new ArgumentNullException(nameof(onPerformanceReport)); @@ -276,21 +261,6 @@ public async ValueTask PreheatAsync(Priority priorities = Priority.Cr return result as T; } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask LoadAsync(CancellationToken cancellationToken) where T : DataTableBase - => LoadAsync(string.Empty, cancellationToken); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask GetOrCreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask CreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - public T? GetCached(string name = "") where T : DataTableBase { ThrowIfDisposed(); @@ -302,38 +272,6 @@ public async ValueTask PreheatAsync(Priority priorities = Priority.Cr public bool IsLoaded(string name = "") where T : DataTableBase => GetCached(name) != null; - [Obsolete("Compatibility API. Prefer IsLoaded(name).")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool HasDataTable(Type dataTableType, string name = "") - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - ThrowIfDisposed(); - lock (m_Gate) - { - return TryGetDataTableUnsafe(new TypeNamePair(dataTableType, name ?? string.Empty), out _); - } - } - - [Obsolete("Use IsLoaded(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool HasDataTable(string name = "") where T : DataTableBase => IsLoaded(name); - - [Obsolete("Use GetCached(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public T? GetDataTable(string name = "") where T : DataTableBase => GetCached(name); - - [Obsolete("Compatibility API. Prefer GetCached(name).")] - [EditorBrowsable(EditorBrowsableState.Never)] - public DataTableBase? GetDataTable(Type dataTableType, string name = "") - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - ThrowIfDisposed(); - lock (m_Gate) - { - return TryGetDataTableUnsafe(new TypeNamePair(dataTableType, name ?? string.Empty), out var table) ? table : null; - } - } - public DataTableBase[] GetAllDataTables() { ThrowIfDisposed(); @@ -350,36 +288,6 @@ public void GetAllDataTables(List results) results.AddRange(GetAllDataTables()); } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Action onCompleted) where T : DataTableBase - { - _ = CompleteLegacyCreateAsync(new TypeNamePair(typeof(T), string.Empty), onCompleted); - } - - [Obsolete("Use the generic LoadAsync(name, cancellationToken) API instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Type dataTableType, Action onCompleted) - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - _ = CompleteLegacyCreateAsync(new TypeNamePair(dataTableType, string.Empty), onCompleted); - } - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(string name, Action onCompleted) where T : DataTableBase - { - _ = CompleteLegacyCreateAsync(new TypeNamePair(typeof(T), name ?? string.Empty), onCompleted); - } - - [Obsolete("Use the generic LoadAsync(name, cancellationToken) API instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Type dataTableType, string name, Action onCompleted) - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - _ = CompleteLegacyCreateAsync(new TypeNamePair(dataTableType, name ?? string.Empty), onCompleted); - } - public bool DestroyDataTable(DataTableBase dataTable) { if (dataTable == null) throw new ArgumentNullException(nameof(dataTable)); @@ -550,23 +458,6 @@ private async Task CompleteLoadAsync(TypeNamePair pair, TaskCompletionSource LoadDataTableInternalAsync(TypeNamePair pair, long lifecycleGeneration, long tableGeneration, CancellationToken lifecycleToken, DataTableParseExecution parseExecution) { DataTableBase? loadedTable = null; diff --git a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableManager.cs b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableManager.cs index 40753a4..e3a4f2d 100644 --- a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableManager.cs +++ b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/DataTableManager.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -18,53 +16,28 @@ public enum Priority All = Critical | Normal | Lazy } - [Obsolete("Unused compatibility type.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public enum DataTableStatus - { - NotLoaded, - LoadedEmpty, - LoadedWithData - } - public readonly struct CacheStats { - public readonly int TotalItems; - - [Obsolete("Use EstimatedMemoryUsageBytes instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public readonly long MemoryUsage; - public readonly long AccessCount; - public readonly long HitCount; - public readonly float HitRate; - - [Obsolete("Use EstimatedBudgetUsageRate instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public readonly float MemoryUsageRate; - public readonly DateTime LastAccessed; + public int TotalItems { get; } -#pragma warning disable CS0618 // Compatibility fields back the clearer estimated-budget aliases. - /// - /// Estimated cache-entry bytes calculated by the configured estimator. - /// - public long EstimatedMemoryUsageBytes => MemoryUsage; + public long EstimatedMemoryUsageBytes { get; } + public long AccessCount { get; } + public long HitCount { get; } + public float HitRate { get; } - /// - /// Ratio of estimated cache-entry bytes to the configured estimated budget. - /// - public float EstimatedBudgetUsageRate => MemoryUsageRate; + public float EstimatedBudgetUsageRate { get; } + public DateTime LastAccessed { get; } - public CacheStats(int totalItems, long memoryUsage, long accessCount, long hitCount, float memoryUsageRate, DateTime lastAccessed) + public CacheStats(int totalItems, long estimatedMemoryUsageBytes, long accessCount, long hitCount, float estimatedBudgetUsageRate, DateTime lastAccessed) { TotalItems = totalItems; - MemoryUsage = memoryUsage; + EstimatedMemoryUsageBytes = estimatedMemoryUsageBytes; AccessCount = accessCount; HitCount = hitCount; HitRate = accessCount > 0 ? (float)hitCount / accessCount : 0f; - MemoryUsageRate = memoryUsageRate; + EstimatedBudgetUsageRate = estimatedBudgetUsageRate; LastAccessed = lastAccessed; } -#pragma warning restore CS0618 } public readonly struct LoadStats @@ -105,26 +78,13 @@ public LoadStats(long loadTime, int tableCount, long memoryUsed, int successCoun public readonly struct TableRegistration { - private readonly Func>? m_LoadAsync; private readonly Func>? m_ContextLoadAsync; - [Obsolete("Use the context-aware TableRegistration constructor instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public TableRegistration(Type tableType, string name, Priority priority, Func> loadAsync) - { - TableType = tableType ?? throw new ArgumentNullException(nameof(tableType)); - Name = name ?? string.Empty; - Priority = priority; - m_LoadAsync = loadAsync ?? throw new ArgumentNullException(nameof(loadAsync)); - m_ContextLoadAsync = null; - } - public TableRegistration(Type tableType, string name, Priority priority, Func> loadAsync) { TableType = tableType ?? throw new ArgumentNullException(nameof(tableType)); Name = name ?? string.Empty; Priority = priority; - m_LoadAsync = null; m_ContextLoadAsync = loadAsync ?? throw new ArgumentNullException(nameof(loadAsync)); } @@ -132,15 +92,11 @@ public TableRegistration(Type tableType, string name, Priority priority, Func LoadAsync(CancellationToken cancellationToken = default) - => LoadAsync(DataTableManager.DefaultContextInternal, cancellationToken); - public ValueTask LoadAsync(DataTableContext context, CancellationToken cancellationToken = default) { if (context == null) throw new ArgumentNullException(nameof(context)); - return m_ContextLoadAsync != null ? m_ContextLoadAsync(context, cancellationToken) : m_LoadAsync!(cancellationToken); + if (m_ContextLoadAsync == null) throw new InvalidOperationException("Table registration is not initialized."); + return m_ContextLoadAsync(context, cancellationToken); } } @@ -157,13 +113,9 @@ public static class DataTableManager private static readonly DataTableContext s_DefaultContext = new(); private static readonly object s_DefaultInitializationGate = new(); - internal static DataTableContext DefaultContextInternal => s_DefaultContext; public static int Count => s_DefaultContext.Count; public static bool IsEstimatedMemoryBudgetEnabled => s_DefaultContext.IsEstimatedMemoryBudgetEnabled; - [Obsolete("Use IsEstimatedMemoryBudgetEnabled instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool IsMemoryManagementEnabled => IsEstimatedMemoryBudgetEnabled; public static DataTableParseExecution ParseExecution { get => s_DefaultContext.ParseExecution; @@ -172,23 +124,13 @@ public static DataTableParseExecution ParseExecution public static void UseFileSystem(string dataDirectory) => s_DefaultContext.UseFileSystem(dataDirectory); public static void UseNetwork(string baseUrl) => s_DefaultContext.UseNetwork(baseUrl); - [Obsolete("Use UseDataSource(source) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void UseCustomSource(IDataSource dataSource) => UseDataSource(dataSource); public static void UseDataSource(IDataSource source) => s_DefaultContext.UseDataSource(source); public static void UseCompositeSource(params IDataSource[] sources) => s_DefaultContext.UseCompositeSource(sources); public static void EnableEstimatedMemoryBudget(int maxEstimatedMemoryMB, Func? estimatedSizeProvider = null) => s_DefaultContext.EnableEstimatedMemoryBudget(maxEstimatedMemoryMB, estimatedSizeProvider); - [Obsolete("Use EnableEstimatedMemoryBudget(maxEstimatedMemoryMB, estimatedSizeProvider) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void EnableMemoryManagement(int maxMemoryMB) => EnableEstimatedMemoryBudget(maxMemoryMB); - public static void DisableEstimatedMemoryBudget() => s_DefaultContext.DisableEstimatedMemoryBudget(); - [Obsolete("Use DisableEstimatedMemoryBudget() instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void DisableMemoryManagement() => DisableEstimatedMemoryBudget(); public static void EnableProfiling(Action onPerformanceReport) => s_DefaultContext.EnableProfiling(onPerformanceReport); public static void RegisterTables(IReadOnlyList registrations) => s_DefaultContext.RegisterTables(registrations); public static void ClearTableRegistrations() => s_DefaultContext.ClearTableRegistrations(); @@ -218,17 +160,9 @@ public static ValueTask PreloadAllAsync(CancellationToken cancellatio return s_DefaultContext.LoadAsync(name, cancellationToken); } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask LoadAsync(CancellationToken cancellationToken) where T : DataTableBase - => LoadAsync(string.Empty, cancellationToken); - public static T? GetCached(string name = "") where T : DataTableBase => s_DefaultContext.GetCached(name); public static bool IsLoaded(string name = "") where T : DataTableBase => s_DefaultContext.IsLoaded(name); - [Obsolete("Use IsLoaded(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool HasDataTable() where T : DataTableBase => IsLoaded(); public static void OnLoaded(Action onLoaded) where T : DataTableBase => s_DefaultContext.OnLoaded(onLoaded); public static void OnAnyLoaded(Action onLoaded) => s_DefaultContext.OnAnyLoaded(onLoaded); public static void ClearHooks() => s_DefaultContext.ClearHooks(); @@ -236,65 +170,7 @@ public static ValueTask PreloadAllAsync(CancellationToken cancellatio public static CacheStats? GetCacheStats() => s_DefaultContext.GetCacheStats(); public static void ClearCache() => s_DefaultContext.ClearCache(); - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask GetOrCreateDataTableAsync() where T : DataTableBase - => LoadAsync(); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask GetOrCreateDataTableAsync(string name, CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [EditorBrowsable(EditorBrowsableState.Never)] - public static T? GetDataTableInternal(string name = "") where T : DataTableBase => s_DefaultContext.GetCached(name); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask CreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void CreateDataTable(Action onCompleted) where T : DataTableBase - { - EnsureDefaultContextInitialized(); - _ = CompleteLegacyCreateAsync(string.Empty, onCompleted); - } - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void CreateDataTable(string name, Action onCompleted) where T : DataTableBase - { - EnsureDefaultContextInitialized(); - _ = CompleteLegacyCreateAsync(name, onCompleted); - } - public static bool DestroyDataTable(string name = "") where T : DataTableBase => s_DefaultContext.DestroyDataTable(name); - - [Obsolete("请使用 GetCached() 或 LoadAsync() 替代")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static T? GetDataTable() where T : DataTableBase => GetCached(); - - private static async Task CompleteLegacyCreateAsync(string name, Action? onCompleted) where T : DataTableBase - { - try - { - await LoadAsync(name, CancellationToken.None); - } - catch (Exception exception) - { - Log.Error($"Failed to load table {typeof(T).FullName}.{name}: {exception.Message}", exception); - } - finally - { - try { onCompleted?.Invoke(); } - catch (Exception exception) { Log.Error($"Data table completion callback failed: {exception.Message}", exception); } - } - } - private static void EnsureDefaultContextInitialized() { if (s_DefaultContext.HasDataSource) return; diff --git a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs deleted file mode 100644 index a1731e3..0000000 --- a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -namespace DataTables -{ - /// - /// 数据表管理器接口。 - /// - [Obsolete("Compatibility callback API. Use IDataTableContext instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public interface IDataTableManager - { - /// - /// 获取数据表数量。 - /// - int Count - { - get; - } - - /// - /// 是否存在数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否存在数据表。 - bool HasDataTable(Type dataTableType, string name = ""); - - /// - /// 是否存在数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否存在数据表。 - bool HasDataTable(string name = "") where T : DataTableBase; - - /// - /// 获取数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 要获取的数据表。 - T? GetDataTable(string name = "") where T : DataTableBase; - - /// - /// 获取数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 要获取的数据表。 - DataTableBase? GetDataTable(Type dataTableType, string name = ""); - - /// - /// 获取所有数据表。 - /// - /// 所有数据表。 - DataTableBase[] GetAllDataTables(); - - /// - /// 获取所有数据表。 - /// - /// 所有数据表。 - void GetAllDataTables(List results); - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表加载完成时回调。 - void CreateDataTable(Action onCompleted) where T : DataTableBase; - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表加载完成时回调。 - void CreateDataTable(Type dataTableType, Action onCompleted); - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 数据表加载完成时回调。 - void CreateDataTable(string name, Action onCompleted) where T : DataTableBase; - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 数据表加载完成时回调。 - void CreateDataTable(Type dataTableType, string name, Action onCompleted); - - /// - /// 销毁数据表。 - /// - /// 要销毁的数据表。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(DataTableBase dataTable); - - /// - /// 销毁数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(string name = "") where T : DataTableBase; - - /// - /// 销毁数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(Type dataTableType, string name = ""); - } -} diff --git a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs.meta b/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs.meta deleted file mode 100644 index 475e378..0000000 --- a/src/DataTables.Unity/Assets/Scripts/DataTables/Runtime/Core/IDataTableManager.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fc399e86ff36b4c43ae32ed2fa0a7b52 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/DataTables/DataTableContext.cs b/src/DataTables/DataTableContext.cs index 10d93e6..4a01fce 100644 --- a/src/DataTables/DataTableContext.cs +++ b/src/DataTables/DataTableContext.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; using System.Threading; @@ -30,9 +29,7 @@ public enum DataTableParseExecution /// /// 独立的数据表运行时上下文。每个实例拥有自己的数据源、加载任务、缓存、生命周期和 Hook。 /// -#pragma warning disable CS0618 - public sealed class DataTableContext : IDataTableContext, IDataTableManager, IDisposable -#pragma warning restore CS0618 + public sealed class DataTableContext : IDataTableContext, IDisposable { private readonly ConcurrentDictionary m_DataTables = new(); private readonly ConcurrentDictionary> m_LoadingTables = new(); @@ -86,10 +83,6 @@ public bool IsEstimatedMemoryBudgetEnabled } } - [Obsolete("Use IsEstimatedMemoryBudgetEnabled instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool IsMemoryManagementEnabled => IsEstimatedMemoryBudgetEnabled; - /// /// Gets or sets where synchronous payload deserialization executes. Payload I/O is always asynchronous. /// @@ -174,10 +167,6 @@ public void EnableEstimatedMemoryBudget(int maxEstimatedMemoryMB, Func EnableEstimatedMemoryBudget(maxMemoryMB); - public void DisableEstimatedMemoryBudget() { ThrowIfDisposed(); @@ -196,10 +185,6 @@ public void DisableEstimatedMemoryBudget() cache.Dispose(); } - [Obsolete("Use DisableEstimatedMemoryBudget() instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void DisableMemoryManagement() => DisableEstimatedMemoryBudget(); - public void EnableProfiling(Action onPerformanceReport) { if (onPerformanceReport == null) throw new ArgumentNullException(nameof(onPerformanceReport)); @@ -276,21 +261,6 @@ public async ValueTask PreheatAsync(Priority priorities = Priority.Cr return result as T; } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask LoadAsync(CancellationToken cancellationToken) where T : DataTableBase - => LoadAsync(string.Empty, cancellationToken); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask GetOrCreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public ValueTask CreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - public T? GetCached(string name = "") where T : DataTableBase { ThrowIfDisposed(); @@ -302,38 +272,6 @@ public async ValueTask PreheatAsync(Priority priorities = Priority.Cr public bool IsLoaded(string name = "") where T : DataTableBase => GetCached(name) != null; - [Obsolete("Compatibility API. Prefer IsLoaded(name).")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool HasDataTable(Type dataTableType, string name = "") - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - ThrowIfDisposed(); - lock (m_Gate) - { - return TryGetDataTableUnsafe(new TypeNamePair(dataTableType, name ?? string.Empty), out _); - } - } - - [Obsolete("Use IsLoaded(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public bool HasDataTable(string name = "") where T : DataTableBase => IsLoaded(name); - - [Obsolete("Use GetCached(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public T? GetDataTable(string name = "") where T : DataTableBase => GetCached(name); - - [Obsolete("Compatibility API. Prefer GetCached(name).")] - [EditorBrowsable(EditorBrowsableState.Never)] - public DataTableBase? GetDataTable(Type dataTableType, string name = "") - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - ThrowIfDisposed(); - lock (m_Gate) - { - return TryGetDataTableUnsafe(new TypeNamePair(dataTableType, name ?? string.Empty), out var table) ? table : null; - } - } - public DataTableBase[] GetAllDataTables() { ThrowIfDisposed(); @@ -350,36 +288,6 @@ public void GetAllDataTables(List results) results.AddRange(GetAllDataTables()); } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Action onCompleted) where T : DataTableBase - { - _ = CompleteLegacyCreateAsync(new TypeNamePair(typeof(T), string.Empty), onCompleted); - } - - [Obsolete("Use the generic LoadAsync(name, cancellationToken) API instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Type dataTableType, Action onCompleted) - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - _ = CompleteLegacyCreateAsync(new TypeNamePair(dataTableType, string.Empty), onCompleted); - } - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(string name, Action onCompleted) where T : DataTableBase - { - _ = CompleteLegacyCreateAsync(new TypeNamePair(typeof(T), name ?? string.Empty), onCompleted); - } - - [Obsolete("Use the generic LoadAsync(name, cancellationToken) API instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public void CreateDataTable(Type dataTableType, string name, Action onCompleted) - { - if (dataTableType == null) throw new ArgumentNullException(nameof(dataTableType)); - _ = CompleteLegacyCreateAsync(new TypeNamePair(dataTableType, name ?? string.Empty), onCompleted); - } - public bool DestroyDataTable(DataTableBase dataTable) { if (dataTable == null) throw new ArgumentNullException(nameof(dataTable)); @@ -550,23 +458,6 @@ private async Task CompleteLoadAsync(TypeNamePair pair, TaskCompletionSource LoadDataTableInternalAsync(TypeNamePair pair, long lifecycleGeneration, long tableGeneration, CancellationToken lifecycleToken, DataTableParseExecution parseExecution) { DataTableBase? loadedTable = null; diff --git a/src/DataTables/DataTableManager.cs b/src/DataTables/DataTableManager.cs index 40753a4..e3a4f2d 100644 --- a/src/DataTables/DataTableManager.cs +++ b/src/DataTables/DataTableManager.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -18,53 +16,28 @@ public enum Priority All = Critical | Normal | Lazy } - [Obsolete("Unused compatibility type.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public enum DataTableStatus - { - NotLoaded, - LoadedEmpty, - LoadedWithData - } - public readonly struct CacheStats { - public readonly int TotalItems; - - [Obsolete("Use EstimatedMemoryUsageBytes instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public readonly long MemoryUsage; - public readonly long AccessCount; - public readonly long HitCount; - public readonly float HitRate; - - [Obsolete("Use EstimatedBudgetUsageRate instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public readonly float MemoryUsageRate; - public readonly DateTime LastAccessed; + public int TotalItems { get; } -#pragma warning disable CS0618 // Compatibility fields back the clearer estimated-budget aliases. - /// - /// Estimated cache-entry bytes calculated by the configured estimator. - /// - public long EstimatedMemoryUsageBytes => MemoryUsage; + public long EstimatedMemoryUsageBytes { get; } + public long AccessCount { get; } + public long HitCount { get; } + public float HitRate { get; } - /// - /// Ratio of estimated cache-entry bytes to the configured estimated budget. - /// - public float EstimatedBudgetUsageRate => MemoryUsageRate; + public float EstimatedBudgetUsageRate { get; } + public DateTime LastAccessed { get; } - public CacheStats(int totalItems, long memoryUsage, long accessCount, long hitCount, float memoryUsageRate, DateTime lastAccessed) + public CacheStats(int totalItems, long estimatedMemoryUsageBytes, long accessCount, long hitCount, float estimatedBudgetUsageRate, DateTime lastAccessed) { TotalItems = totalItems; - MemoryUsage = memoryUsage; + EstimatedMemoryUsageBytes = estimatedMemoryUsageBytes; AccessCount = accessCount; HitCount = hitCount; HitRate = accessCount > 0 ? (float)hitCount / accessCount : 0f; - MemoryUsageRate = memoryUsageRate; + EstimatedBudgetUsageRate = estimatedBudgetUsageRate; LastAccessed = lastAccessed; } -#pragma warning restore CS0618 } public readonly struct LoadStats @@ -105,26 +78,13 @@ public LoadStats(long loadTime, int tableCount, long memoryUsed, int successCoun public readonly struct TableRegistration { - private readonly Func>? m_LoadAsync; private readonly Func>? m_ContextLoadAsync; - [Obsolete("Use the context-aware TableRegistration constructor instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public TableRegistration(Type tableType, string name, Priority priority, Func> loadAsync) - { - TableType = tableType ?? throw new ArgumentNullException(nameof(tableType)); - Name = name ?? string.Empty; - Priority = priority; - m_LoadAsync = loadAsync ?? throw new ArgumentNullException(nameof(loadAsync)); - m_ContextLoadAsync = null; - } - public TableRegistration(Type tableType, string name, Priority priority, Func> loadAsync) { TableType = tableType ?? throw new ArgumentNullException(nameof(tableType)); Name = name ?? string.Empty; Priority = priority; - m_LoadAsync = null; m_ContextLoadAsync = loadAsync ?? throw new ArgumentNullException(nameof(loadAsync)); } @@ -132,15 +92,11 @@ public TableRegistration(Type tableType, string name, Priority priority, Func LoadAsync(CancellationToken cancellationToken = default) - => LoadAsync(DataTableManager.DefaultContextInternal, cancellationToken); - public ValueTask LoadAsync(DataTableContext context, CancellationToken cancellationToken = default) { if (context == null) throw new ArgumentNullException(nameof(context)); - return m_ContextLoadAsync != null ? m_ContextLoadAsync(context, cancellationToken) : m_LoadAsync!(cancellationToken); + if (m_ContextLoadAsync == null) throw new InvalidOperationException("Table registration is not initialized."); + return m_ContextLoadAsync(context, cancellationToken); } } @@ -157,13 +113,9 @@ public static class DataTableManager private static readonly DataTableContext s_DefaultContext = new(); private static readonly object s_DefaultInitializationGate = new(); - internal static DataTableContext DefaultContextInternal => s_DefaultContext; public static int Count => s_DefaultContext.Count; public static bool IsEstimatedMemoryBudgetEnabled => s_DefaultContext.IsEstimatedMemoryBudgetEnabled; - [Obsolete("Use IsEstimatedMemoryBudgetEnabled instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool IsMemoryManagementEnabled => IsEstimatedMemoryBudgetEnabled; public static DataTableParseExecution ParseExecution { get => s_DefaultContext.ParseExecution; @@ -172,23 +124,13 @@ public static DataTableParseExecution ParseExecution public static void UseFileSystem(string dataDirectory) => s_DefaultContext.UseFileSystem(dataDirectory); public static void UseNetwork(string baseUrl) => s_DefaultContext.UseNetwork(baseUrl); - [Obsolete("Use UseDataSource(source) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void UseCustomSource(IDataSource dataSource) => UseDataSource(dataSource); public static void UseDataSource(IDataSource source) => s_DefaultContext.UseDataSource(source); public static void UseCompositeSource(params IDataSource[] sources) => s_DefaultContext.UseCompositeSource(sources); public static void EnableEstimatedMemoryBudget(int maxEstimatedMemoryMB, Func? estimatedSizeProvider = null) => s_DefaultContext.EnableEstimatedMemoryBudget(maxEstimatedMemoryMB, estimatedSizeProvider); - [Obsolete("Use EnableEstimatedMemoryBudget(maxEstimatedMemoryMB, estimatedSizeProvider) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void EnableMemoryManagement(int maxMemoryMB) => EnableEstimatedMemoryBudget(maxMemoryMB); - public static void DisableEstimatedMemoryBudget() => s_DefaultContext.DisableEstimatedMemoryBudget(); - [Obsolete("Use DisableEstimatedMemoryBudget() instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void DisableMemoryManagement() => DisableEstimatedMemoryBudget(); public static void EnableProfiling(Action onPerformanceReport) => s_DefaultContext.EnableProfiling(onPerformanceReport); public static void RegisterTables(IReadOnlyList registrations) => s_DefaultContext.RegisterTables(registrations); public static void ClearTableRegistrations() => s_DefaultContext.ClearTableRegistrations(); @@ -218,17 +160,9 @@ public static ValueTask PreloadAllAsync(CancellationToken cancellatio return s_DefaultContext.LoadAsync(name, cancellationToken); } - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask LoadAsync(CancellationToken cancellationToken) where T : DataTableBase - => LoadAsync(string.Empty, cancellationToken); - public static T? GetCached(string name = "") where T : DataTableBase => s_DefaultContext.GetCached(name); public static bool IsLoaded(string name = "") where T : DataTableBase => s_DefaultContext.IsLoaded(name); - [Obsolete("Use IsLoaded(name) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static bool HasDataTable() where T : DataTableBase => IsLoaded(); public static void OnLoaded(Action onLoaded) where T : DataTableBase => s_DefaultContext.OnLoaded(onLoaded); public static void OnAnyLoaded(Action onLoaded) => s_DefaultContext.OnAnyLoaded(onLoaded); public static void ClearHooks() => s_DefaultContext.ClearHooks(); @@ -236,65 +170,7 @@ public static ValueTask PreloadAllAsync(CancellationToken cancellatio public static CacheStats? GetCacheStats() => s_DefaultContext.GetCacheStats(); public static void ClearCache() => s_DefaultContext.ClearCache(); - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask GetOrCreateDataTableAsync() where T : DataTableBase - => LoadAsync(); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask GetOrCreateDataTableAsync(string name, CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [EditorBrowsable(EditorBrowsableState.Never)] - public static T? GetDataTableInternal(string name = "") where T : DataTableBase => s_DefaultContext.GetCached(name); - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static ValueTask CreateDataTableAsync(string name = "", CancellationToken cancellationToken = default) where T : DataTableBase - => LoadAsync(name, cancellationToken); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void CreateDataTable(Action onCompleted) where T : DataTableBase - { - EnsureDefaultContextInitialized(); - _ = CompleteLegacyCreateAsync(string.Empty, onCompleted); - } - - [Obsolete("Use LoadAsync(name, cancellationToken) instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static void CreateDataTable(string name, Action onCompleted) where T : DataTableBase - { - EnsureDefaultContextInitialized(); - _ = CompleteLegacyCreateAsync(name, onCompleted); - } - public static bool DestroyDataTable(string name = "") where T : DataTableBase => s_DefaultContext.DestroyDataTable(name); - - [Obsolete("请使用 GetCached() 或 LoadAsync() 替代")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static T? GetDataTable() where T : DataTableBase => GetCached(); - - private static async Task CompleteLegacyCreateAsync(string name, Action? onCompleted) where T : DataTableBase - { - try - { - await LoadAsync(name, CancellationToken.None); - } - catch (Exception exception) - { - Log.Error($"Failed to load table {typeof(T).FullName}.{name}: {exception.Message}", exception); - } - finally - { - try { onCompleted?.Invoke(); } - catch (Exception exception) { Log.Error($"Data table completion callback failed: {exception.Message}", exception); } - } - } - private static void EnsureDefaultContextInitialized() { if (s_DefaultContext.HasDataSource) return; diff --git a/src/DataTables/IDataTableManager.cs b/src/DataTables/IDataTableManager.cs deleted file mode 100644 index a1731e3..0000000 --- a/src/DataTables/IDataTableManager.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -namespace DataTables -{ - /// - /// 数据表管理器接口。 - /// - [Obsolete("Compatibility callback API. Use IDataTableContext instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public interface IDataTableManager - { - /// - /// 获取数据表数量。 - /// - int Count - { - get; - } - - /// - /// 是否存在数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否存在数据表。 - bool HasDataTable(Type dataTableType, string name = ""); - - /// - /// 是否存在数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否存在数据表。 - bool HasDataTable(string name = "") where T : DataTableBase; - - /// - /// 获取数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 要获取的数据表。 - T? GetDataTable(string name = "") where T : DataTableBase; - - /// - /// 获取数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 要获取的数据表。 - DataTableBase? GetDataTable(Type dataTableType, string name = ""); - - /// - /// 获取所有数据表。 - /// - /// 所有数据表。 - DataTableBase[] GetAllDataTables(); - - /// - /// 获取所有数据表。 - /// - /// 所有数据表。 - void GetAllDataTables(List results); - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表加载完成时回调。 - void CreateDataTable(Action onCompleted) where T : DataTableBase; - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表加载完成时回调。 - void CreateDataTable(Type dataTableType, Action onCompleted); - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 数据表加载完成时回调。 - void CreateDataTable(string name, Action onCompleted) where T : DataTableBase; - - /// - /// 创建数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 数据表加载完成时回调。 - void CreateDataTable(Type dataTableType, string name, Action onCompleted); - - /// - /// 销毁数据表。 - /// - /// 要销毁的数据表。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(DataTableBase dataTable); - - /// - /// 销毁数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(string name = "") where T : DataTableBase; - - /// - /// 销毁数据表。 - /// - /// 数据表的类型。 - /// 数据表名称。 - /// 是否销毁数据表成功。 - bool DestroyDataTable(Type dataTableType, string name = ""); - } -} diff --git a/tests/DataTables.Tests/ConcurrencyTest.cs b/tests/DataTables.Tests/ConcurrencyTest.cs index 81663b3..81059e0 100644 --- a/tests/DataTables.Tests/ConcurrencyTest.cs +++ b/tests/DataTables.Tests/ConcurrencyTest.cs @@ -119,62 +119,6 @@ public async Task DestroyDuringLoad_ShouldNotRepublishTheTable() (await DataTableManager.LoadAsync()).Should().NotBeNull("销毁后的新请求应能重新加载"); } - [Fact] - public async Task LegacyCreateDuringClear_ShouldNotRepublishTheTable() - { - ResetDataTableManager(); - var source = new BlockingCountingDataSource(); - DataTableManager.UseDataSource(source); - var completed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - -#pragma warning disable CS0618 // This test intentionally exercises the callback compatibility layer. - DataTableManager.CreateDataTable(() => completed.TrySetResult(true)); -#pragma warning restore CS0618 - await source.FirstLoadStarted.Task; - - DataTableManager.ClearCache(); - source.Release(); - await completed.Task; - - DataTableManager.GetCached().Should().BeNull(); - } - - [Fact] - public async Task LegacyCreateAndLoadAsync_ShouldShareOneSourceLoad() - { - ResetDataTableManager(); - var source = new BlockingCountingDataSource(); - DataTableManager.UseDataSource(source); - var callbackCompleted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var callbackCount = 0; - - try - { -#pragma warning disable CS0618 // This test intentionally exercises the callback compatibility layer. - DataTableManager.CreateDataTable(() => - { - Interlocked.Increment(ref callbackCount); - callbackCompleted.TrySetResult(true); - }); -#pragma warning restore CS0618 - await source.FirstLoadStarted.Task; - - var loading = DataTableManager.LoadAsync().AsTask(); - source.LoadCount.Should().Be(1); - - source.Release(); - (await loading).Should().NotBeNull(); - await callbackCompleted.Task; - - Volatile.Read(ref callbackCount).Should().Be(1); - source.LoadCount.Should().Be(1); - } - finally - { - source.Release(); - } - } - /// /// 测试并发加载不同数据表的性能 /// diff --git a/tests/DataTables.Tests/DataTableManagerOptimizedTest.cs b/tests/DataTables.Tests/DataTableManagerOptimizedTest.cs index 9ce8707..ed04162 100644 --- a/tests/DataTables.Tests/DataTableManagerOptimizedTest.cs +++ b/tests/DataTables.Tests/DataTableManagerOptimizedTest.cs @@ -351,8 +351,8 @@ public void HighPerformanceInlines_ShouldWork() DataTableManager.UseDataSource(new FastMockDataSource()); // Act - 测试内联优化的内部方法 - var table1 = DataTableManager.GetDataTableInternal(); - var table2 = DataTableManager.GetDataTableInternal(); + var table1 = DataTableManager.GetCached(); + var table2 = DataTableManager.GetCached(); // Assert if (table1 != null && table2 != null) diff --git a/tests/DataTables.Tests/DataTableTemplateTests.cs b/tests/DataTables.Tests/DataTableTemplateTests.cs index 9440fb7..330dd09 100644 --- a/tests/DataTables.Tests/DataTableTemplateTests.cs +++ b/tests/DataTables.Tests/DataTableTemplateTests.cs @@ -28,8 +28,6 @@ public void GroupedIndex_Output_Should_Compile() code.Should().Contain("public static IReadOnlyList? GetManyBySkillPos(int skillPos)"); code.Should().Contain("public static IReadOnlyList? GetManyBySkillPos(string dataTableName, int skillPos)"); - code.Should().Contain("[Obsolete(\"Use GetManyBySkillPos instead.\")]"); - code.Should().Contain("[EditorBrowsable(EditorBrowsableState.Never)]"); code.Should().Contain("m_Dict1.Clear();"); code.Should().Contain("m_Dict2.Clear();"); Regex.IsMatch(code, @"}\r?\n\z").Should().BeTrue("generated files should end with one line break, not a blank line"); @@ -50,7 +48,7 @@ public void CompoundIndex_WithTableNameField_Should_GenerateUnambiguousNamedTabl var code = new DataTableTemplate(context).TransformText(); code.Should().Contain("GetByIdAndDataTableName(string _dataTableName, int id, string dataTableName)"); - code.Should().Contain("GetDataTableInternal(_dataTableName)"); + code.Should().Contain("GetCached(_dataTableName)"); AssertCompiles("GeneratedCompoundNamedIndex", code); } @@ -70,7 +68,7 @@ public void CustomUsing_Output_Should_Start_On_A_New_Line() var kvCode = new KvTableTemplate(context).TransformText(); kvCode.Should().Contain(expected); kvCode.Should().Contain("GetVersion(string dataTableName)"); - kvCode.Should().Contain("GetDataTableInternal(dataTableName)"); + kvCode.Should().Contain("GetCached(dataTableName)"); AssertCompiles("GeneratedKvCustomUsing", kvCode); } @@ -110,7 +108,7 @@ public void TreeIndex_Output_Should_Compile() var code = new TreeTableTemplate(context).TransformText(); code.Should().Contain("GetChildrenStatic(string dataTableName, string id)"); - code.Should().Contain("GetDataTableInternal(dataTableName)"); + code.Should().Contain("GetCached(dataTableName)"); AssertCompiles("GeneratedTreeIndex", code); } @@ -133,7 +131,7 @@ public void MatrixValueType_Output_Should_Compile_Without_Warnings() var code = new DataMatrixTemplate(context).TransformText(); code.Should().Contain("GetRow(string dataTableName, short key1, long key2)"); - code.Should().Contain("GetDataTableInternal(dataTableName)"); + code.Should().Contain("GetCached(dataTableName)"); AssertCompiles("GeneratedFlagMatrix", code, allowWarnings: false); } diff --git a/tests/DataTables.Tests/DocumentationSmokeTests.cs b/tests/DataTables.Tests/DocumentationSmokeTests.cs index a1133f9..f3d7f40 100644 --- a/tests/DataTables.Tests/DocumentationSmokeTests.cs +++ b/tests/DataTables.Tests/DocumentationSmokeTests.cs @@ -58,9 +58,15 @@ public void Readme_CSharpBlocks_Should_Compile() } [Fact] - public void AgentGuide_CSharpBlocks_Should_Compile() + public void AgentGuide_ShouldNotDocumentRemovedCompatibilityApis() { - AssertMarkdownCSharpBlocksCompile(AgentsPath, "AgentGuide"); + var markdown = File.ReadAllText(AgentsPath); + + markdown.Should().NotContain("Compatibility APIs"); + markdown.Should().NotContain("EnableMemoryManagement"); + markdown.Should().NotContain("CreateDataTable<"); + markdown.Should().NotContain("GetDataTable<"); + markdown.Should().NotContain("HasDataTable"); } [Fact] diff --git a/tests/DataTables.Tests/PublicApiMetadataTests.cs b/tests/DataTables.Tests/PublicApiMetadataTests.cs index 2cc005c..1bae77b 100644 --- a/tests/DataTables.Tests/PublicApiMetadataTests.cs +++ b/tests/DataTables.Tests/PublicApiMetadataTests.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Linq; using System.Reflection; using System.Threading; @@ -12,47 +11,43 @@ namespace DataTables.Tests; public sealed class PublicApiMetadataTests { [Fact] - public void CompatibilityMembers_ShouldBeObsoleteAndHiddenFromIntelliSense() + public void RemovedCompatibilityMembers_ShouldNotExist() { - var members = new MemberInfo[] + var removedMembers = new (Type Type, string Name)[] { - FindProperty(typeof(DataTableManager), "IsMemoryManagementEnabled"), - FindMethod(typeof(DataTableManager), "UseCustomSource", 1), - FindMethod(typeof(DataTableManager), "EnableMemoryManagement", 1), - FindMethod(typeof(DataTableManager), "DisableMemoryManagement", 0), - FindMethod(typeof(DataTableManager), "LoadAsync", 1, isGeneric: true), - FindMethod(typeof(DataTableManager), "HasDataTable", 0, isGeneric: true), - FindMethod(typeof(DataTableManager), "GetOrCreateDataTableAsync", 0, isGeneric: true), - FindMethod(typeof(DataTableManager), "GetOrCreateDataTableAsync", 2, isGeneric: true), - FindMethod(typeof(DataTableManager), "CreateDataTableAsync", 2, isGeneric: true), - FindMethod(typeof(DataTableManager), "CreateDataTable", 1, isGeneric: true), - FindMethod(typeof(DataTableManager), "CreateDataTable", 2, isGeneric: true), - FindMethod(typeof(DataTableManager), "GetDataTable", 0, isGeneric: true), - FindProperty(typeof(DataTableContext), "IsMemoryManagementEnabled"), - FindMethod(typeof(DataTableContext), "EnableMemoryManagement", 1), - FindMethod(typeof(DataTableContext), "DisableMemoryManagement", 0), - FindMethod(typeof(DataTableContext), "LoadAsync", 1, isGeneric: true), - FindMethod(typeof(DataTableContext), "GetOrCreateDataTableAsync", 2, isGeneric: true), - FindMethod(typeof(DataTableContext), "CreateDataTableAsync", 2, isGeneric: true), - FindMethod(typeof(DataTableContext), "HasDataTable", 1, isGeneric: true), - FindMethod(typeof(DataTableContext), "GetDataTable", 1, isGeneric: true), - FindMethod(typeof(DataTableContext), "CreateDataTable", 1, isGeneric: true), - FindMethod(typeof(DataTableContext), "CreateDataTable", 2, isGeneric: true), - FindMethod(typeof(TableRegistration), "LoadAsync", 1), - FindLegacyRegistrationConstructor(), - FindField(typeof(CacheStats), "MemoryUsage"), - FindField(typeof(CacheStats), "MemoryUsageRate") + (typeof(DataTableManager), "IsMemoryManagementEnabled"), + (typeof(DataTableManager), "UseCustomSource"), + (typeof(DataTableManager), "EnableMemoryManagement"), + (typeof(DataTableManager), "DisableMemoryManagement"), + (typeof(DataTableManager), "HasDataTable"), + (typeof(DataTableManager), "GetOrCreateDataTableAsync"), + (typeof(DataTableManager), "CreateDataTableAsync"), + (typeof(DataTableManager), "CreateDataTable"), + (typeof(DataTableManager), "GetDataTable"), + (typeof(DataTableManager), "GetDataTableInternal"), + (typeof(DataTableContext), "IsMemoryManagementEnabled"), + (typeof(DataTableContext), "EnableMemoryManagement"), + (typeof(DataTableContext), "DisableMemoryManagement"), + (typeof(DataTableContext), "HasDataTable"), + (typeof(DataTableContext), "GetDataTable"), + (typeof(DataTableContext), "CreateDataTable"), + (typeof(CacheStats), "MemoryUsage"), + (typeof(CacheStats), "MemoryUsageRate"), }; - foreach (var member in members) AssertCompatibilityMember(member); + foreach (var (type, name) in removedMembers) + { + type.GetMember(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) + .Should().BeEmpty($"{type.FullName}.{name} should be removed in the breaking API cleanup"); + } var assembly = typeof(DataTableManager).Assembly; - AssertCompatibilityMember(assembly.GetType("DataTables.IDataTableManager", throwOnError: true)!); - AssertCompatibilityMember(assembly.GetType("DataTables.DataTableStatus", throwOnError: true)!); + assembly.GetType("DataTables.IDataTableManager").Should().BeNull(); + assembly.GetType("DataTables.DataTableStatus").Should().BeNull(); } [Fact] - public void RecommendedMembers_ShouldNotBeObsolete() + public void RecommendedMembers_ShouldRemainPublicAndNotObsolete() { var members = new MemberInfo[] { @@ -99,19 +94,6 @@ private static PropertyInfo FindProperty(Type type, string name) => type.GetProperty(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) ?? throw new InvalidOperationException($"Property {type.FullName}.{name} was not found."); - private static FieldInfo FindField(Type type, string name) - => type.GetField(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance) - ?? throw new InvalidOperationException($"Field {type.FullName}.{name} was not found."); - - private static ConstructorInfo FindLegacyRegistrationConstructor() - => typeof(TableRegistration).GetConstructor(new[] - { - typeof(Type), - typeof(string), - typeof(Priority), - typeof(Func>) - }) ?? throw new InvalidOperationException("Legacy TableRegistration constructor was not found."); - private static ConstructorInfo FindContextAwareRegistrationConstructor() => typeof(TableRegistration).GetConstructor(new[] { @@ -120,15 +102,4 @@ private static ConstructorInfo FindContextAwareRegistrationConstructor() typeof(Priority), typeof(Func>) }) ?? throw new InvalidOperationException("Context-aware TableRegistration constructor was not found."); - - private static void AssertCompatibilityMember(MemberInfo member) - { - member.GetCustomAttribute().Should().NotBeNull( - $"{member.DeclaringType?.FullName ?? member.Name}.{member.Name} is a compatibility API"); - var editorBrowsable = member.GetCustomAttribute(); - editorBrowsable.Should().NotBeNull( - $"{member.DeclaringType?.FullName ?? member.Name}.{member.Name} is a compatibility API"); - editorBrowsable!.State.Should().Be(EditorBrowsableState.Never, - $"{member.DeclaringType?.FullName ?? member.Name}.{member.Name} should be hidden from IntelliSense"); - } } diff --git a/tests/DataTables.Tests/SplitTableQueryTests.cs b/tests/DataTables.Tests/SplitTableQueryTests.cs index 55198e7..228ae05 100644 --- a/tests/DataTables.Tests/SplitTableQueryTests.cs +++ b/tests/DataTables.Tests/SplitTableQueryTests.cs @@ -59,7 +59,7 @@ protected override void OnDataRowsRemoved() public static SplitQueryRow? GetById(string dataTableName, int id) { - var table = DataTableManager.GetDataTableInternal(dataTableName); + var table = DataTableManager.GetCached(dataTableName); return table?.m_ById.TryGetValue(id, out var row) == true ? row : null; } }