补齐 package Tests 第一刀

This commit is contained in:
JSD\13999
2026-06-06 16:14:17 +08:00
parent 0930e7c173
commit 7b2243a40b
13 changed files with 334 additions and 169 deletions

View File

@@ -1,14 +1,43 @@
# FlowScope 安装与最小接入
日期2026-05-26
日期2026-06-06
本文说明 FlowScope 在 P2 第一阶段面向使用者的安装路径、项目内开发模式,以及基于当前真实 API 的最小 Bootstrap 写法。当前仓库尚未完成标准 Unity Package 物理搬迁package path 与 Git URL 方式是目标接入形态;项目内 `Assets/FlowScope` 开发模式是当前可用形态
本文说明 FlowScope 在 P2 package/editor 阶段的当前安装方式、最小接入写法和已知限制。当前仓库已经存在真实 Unity Package 目录 `Packages/com.flowscope.gamecore`,同时仍保留 `My project/Assets/FlowScope` 作为开发工程内的测试与样例源
## 安装方式
## 当前可用安装方式
### Git URL
消费方项目推荐通过 SSH Git URL 安装,并固定到 preview tag 或明确 commit
```json
{
"scopedRegistries": [
{
"name": "Unity NuGet",
"url": "https://unitynuget-registry.openupm.com",
"scopes": [
"org.nuget"
]
}
],
"dependencies": {
"com.cysharp.r3": "https://github.com/Cysharp/R3.git?path=src/R3.Unity/Assets/R3.Unity#1.3.0",
"com.flowscope.gamecore": "ssh://git@git.zz.com:2222/Developer/FlowScope.git?path=/Packages/com.flowscope.gamecore#v0.2.0-preview.1",
"org.nuget.r3": "1.3.0"
}
}
```
注意:
- `com.cysharp.r3` 提供 Unity 适配层。
- `org.nuget.r3` 提供 `R3.dll` 和相关 BCL DLL。
- Unity Package Manager 不可靠支持在 package 的 `package.json` 中声明 Git dependency因此 R3 必须由消费方 manifest 显式声明。
- 当前 `v0.2.0-preview.1` 已在 FishingFrenzy 消费方工程完成最小编译验证后续文档、Samples、Tests 收口后应打新的 preview tag。
### 本地 package path
当后续完成标准包目录后,可在使用方 Unity 项目的 `Packages/manifest.json` 中使用本地路径:
本机调试时可在消费方 Unity 项目的 `Packages/manifest.json` 中使用本地路径:
```json
{
@@ -19,66 +48,60 @@
```
适用场景:
- 本机同时开发 FlowScope 与游戏项目
- 需要在包仓库中调试 Runtime、Addressables、Editor 或 Samples
- 希望由 Unity Package Manager 识别包结构与 `Samples~`
注意P2 第一阶段当前仓库还没有 `Packages/com.flowscope.gamecore` 物理目录,因此此方式需要等第二阶段本地 package 试迁移完成后再用于实装验证。
### Git URL
当包目录与发布分支稳定后,可在 `Packages/manifest.json` 中使用 Git URL
```json
{
"dependencies": {
"com.flowscope.gamecore": "<最终发布仓库 Git URL>?path=/Packages/com.flowscope.gamecore#v0.2.0"
}
}
```
适用场景:
- 使用方只消费稳定版本,不直接修改 FlowScope 源码。
- 团队希望通过 tag 或固定 commit 控制接入版本。
当前仓库 `origin` 仍带有旧项目名,不应直接写入对外安装文档。发布前需要由团队确认最终 FlowScope 包仓库地址;使用 Git URL 时应固定 tag 或 commit避免使用浮动分支导致使用方项目在不同时间解析到不同代码。
- 同时开发 FlowScope 和消费方项目。
- 需要快速验证 Runtime、Addressables、Editor、Samples 或 Tests package 布局
- 不希望每次小改都重新打 Git tag
### 项目内 Assets 开发模式
当前可用模式是将 FlowScope 放在 Unity 项目内
```text
Assets/
FlowScope/
Runtime/
Addressables/
Samples/
Tests/
```
本仓库当前路径为:
FlowScope 自身开发工程仍保留
```text
My project/Assets/FlowScope
```
适用场景
该路径继续承担
- P0/P1 Runtime 回归测试。
- 主项目内 Addressables 真实 fixture 验收。
- MainMenuP0 Assets 样例源。
- 迁移到 package `Samples~` / `Tests~` 前的稳定参照。
- P2 第一阶段继续验证 P0/P1 Runtime 行为
- 并行开发 Addressables 验收、Editor 诊断与 package 文档。
- 在包迁移前保持 `MainMenuP0` 示例与测试路径稳定。
不要在消费方项目同时复制 `Assets/FlowScope` 并安装 Git package否则会混淆“项目内源码导入”和“package 消费”两条验证路径
使用此模式时,不需要在 `manifest.json` 中声明 `com.flowscope.gamecore`。仍需要确保项目已有当前代码依赖的包,例如 `com.cysharp.r3``com.unity.addressables``com.unity.ugui`
## 当前 package 内容
```text
Packages/com.flowscope.gamecore/
package.json
Runtime/
Addressables/
Editor/
Samples~/
Tests~/
Documentation~/
README.md
CHANGELOG.md
```
已完成:
- Runtime / Addressables / Editor 镜像到 package。
- `Samples~/MainMenuP0` 作为 package sample 候选。
- `Tests~/EditMode` 第一刀最小 smoke 测试。
- Git package 在 FishingFrenzy 中完成最小消费方验证。
仍未完成:
- package sample 导入后的人工验收。
- package `Tests~` 全量策略与 PlayMode 测试迁移。
- 真正空白 Unity 项目的 Git URL 安装复验。
- 下一个 preview tag。
## 最小 Bootstrap 示例
下面示例只使用当前代码中已经存在的 API 名称。示例使用 Addressables 作为资源后端,适合未来包接入;如果项目暂时没有 Addressables 资源,也可以参考 `MainMenuP0` 示例中的自定义 `IResourceBackend` 做本地验证。
下面示例只使用当前真实 API 名称。示例使用 Addressables 作为资源后端;如果项目暂时没有 Addressables 资源,也可以参考 `MainMenuP0` 中的 `SampleResourceBackend` 做本地验证。
```csharp
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using FlowScope.Addressables;
@@ -213,67 +236,38 @@ public sealed class FlowScopeBootstrap : MonoBehaviour
_screenNavigator = screenNavigator;
}
public Task LoadAsync(FeatureContext context)
{
return Task.CompletedTask;
}
public Task EnterAsync(FeatureContext context)
{
return Task.CompletedTask;
}
public Task ExitAsync(FeatureContext context)
{
return Task.CompletedTask;
}
public void Dispose()
{
}
public Task LoadAsync(FeatureContext context) => Task.CompletedTask;
public Task EnterAsync(FeatureContext context) => Task.CompletedTask;
public Task ExitAsync(FeatureContext context) => Task.CompletedTask;
public void Dispose() { }
}
}
```
接入要点
## 接入要点
- `GameFlow.StartupAsync<TInitialFeature>(Container root, CancellationToken cancellationToken)` 会先解析并加载 `IConfigProvider`
- 初始 Feature 必须实现 `IFeature`,并能从 Feature scope 中解析;示例使用 `_root.RegisterTransient(_ => new ExampleFeature(screenNavigator))`
- 业务资源统一通过 `IResourceService``IResourceGroup` 加载,不直接在业务层调用 Addressables。
- `GameFlow.StartupAsync<TInitialFeature>` 会先解析并加载 `IConfigProvider`
- 初始 Feature 必须实现 `IFeature`,并能从 root 或 Feature scope 中解析。
- 业务资源统一通过 `IResourceService``IResourceGroup` 加载,不直接调用 Addressables。
- UI 层使用 `UIManager.RegisterLayer(...)` 建立层级,再由 `UIScreenNavigator` 或业务 Feature 打开面板。
- Shutdown 时应调用 `GameFlow.ShutdownAsync(...)`,并释放 UI 预加载资源,例如 `_preloadService.ReleaseAll()`
## Addressables 接入说明
使用 Addressables 时,推荐注册:
```csharp
IResourceService resources = new AddressablesResourceService(
new AddressablesResourceBackend());
```
这会把业务层依赖收敛到 `IResourceService``AddressablesResourceBackend` 只位于 Addressables 适配程序集Runtime 不需要知道 Addressables 的存在。
如果某个系统需要独立资源生命周期,应通过 `resources.CreateGroup()` 创建 `IResourceGroup`,让 Feature 的资源释放跟随 `FeatureContext.Resources.Dispose()`
## 常见误用
- 不要让业务 Feature 直接调用 `UnityEngine.AddressableAssets.Addressables`;应通过 `IResourceService``IResourceGroup` 访问资源
- 不要把短生命周期对象注册 `RegisterInstance``RegisterSingletonFactory`;临时对象优先使用 `RegisterTransient`,需要随 Feature 生命周期释放的对象放在 Feature scope
- 不要跳过 `GameFlow.ShutdownAsync(...)`;它负责退出当前 Feature、释放 Feature scope并处置 root container
- 不要把 `UIScreenNavigator`完整页面路由系统;它是当前 UI 导航辅助,不负责 URL、跨 Feature 页面恢复或全局路由
- 不要让业务 Feature 直接调用 `UnityEngine.AddressableAssets.Addressables`
- 不要把短生命周期对象注册 `RegisterInstance``RegisterSingletonFactory`
- 不要跳过 `GameFlow.ShutdownAsync(...)`
- 不要把 `UIScreenNavigator`完整页面路由系统。
- 不要让 `FlowScope.Runtime` 反向依赖 Addressables、Editor、Samples 或 Tests。
- 不要在没有注册 UI layer 的情况下打开面板`UIManager.OpenAsync` 会要求面板声明的 layer 已经通过 `RegisterLayer` 注册
- 不要在未初始化 `AudioService.Initialize(IResourceService, AudioServiceConfig)` 前调用播放接口。
- 不要假设 package path 与 Git URL 在 P2 第一阶段已经可安装;当前真实可用形态仍是项目内 `Assets/FlowScope` 开发模式。
- 不要在没有注册 UI layer 的情况下打开面板。
- 不要在未初始化 `AudioService.Initialize(...)` 前调用播放接口。
## 当前限制
P2 第一阶段文档完成后FlowScope 仍需要后续 worker 或阶段完成以下验证后,才能把 package 安装方式视为可交付
P2 收口前仍需要完成
1. 建立真实 package 根目录与 `package.json`
2. 通过本地 package path 在干净 Unity 项目中验证安装
3. 验证 Git URL 安装与依赖解析
4. `MainMenuP0``Assets/FlowScope/Samples` 整理为可导入 package sample
5. 在干净 Unity 项目中复验 Addressables 测试资源、settings 与 PlayMode 用例;主项目内的真实 load/release 验收记录已完成。
6. 保持 generated csproj build 与 Unity Test Runner 记录为 0 error。
1. package sample 导入验收
2. package `Tests~` 全量策略和 PlayMode 迁移策略
3. 真正空白 Unity 项目 Git URL 安装复验
4. 下一个 preview tag
5. Unity Test Runner 或明确记录无法执行原因。