@kkarum/framework 2.3.18 → 2.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -93
- package/docs/CODEX_GUIDE.md +219 -0
- package/docs/CODEX_GUIDE.md.meta +6 -0
- package/docs/ERROR_HANDLING.md +233 -0
- package/docs/ERROR_HANDLING.md.meta +6 -0
- package/docs/FRAMEWORK_API.md +414 -0
- package/docs/FRAMEWORK_API.md.meta +6 -0
- package/docs/FRAMEWORK_EXAMPLES.md +309 -0
- package/docs/FRAMEWORK_EXAMPLES.md.meta +6 -0
- package/docs/FRAMEWORK_OVERVIEW.md +127 -0
- package/docs/FRAMEWORK_OVERVIEW.md.meta +6 -0
- package/docs/FRAMEWORK_PATTERNS.md +261 -0
- package/docs/FRAMEWORK_PATTERNS.md.meta +6 -0
- package/docs/FRAMEWORK_USAGE.md +344 -0
- package/docs/FRAMEWORK_USAGE.md.meta +6 -0
- package/docs/MCP_INTEGRATION.md +241 -0
- package/docs/MCP_INTEGRATION.md.meta +6 -0
- package/docs/UI_DEVELOPMENT_GUIDE.md +295 -0
- package/docs/UI_DEVELOPMENT_GUIDE.md.meta +6 -0
- package/docs.meta +13 -0
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Error Handling
|
|
2
|
+
|
|
3
|
+
本文档定义框架内业务错误处理、异步失败、资源失败和生命周期清理规范。
|
|
4
|
+
|
|
5
|
+
## 日志
|
|
6
|
+
|
|
7
|
+
统一使用 `FW.Log`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
FW.Log.debug("message");
|
|
11
|
+
FW.Log.warn("warning", data);
|
|
12
|
+
FW.Log.error("error", error);
|
|
13
|
+
FW.Log.request("request", msg);
|
|
14
|
+
FW.Log.response("response", msg);
|
|
15
|
+
FW.Log.send("socket send", msg);
|
|
16
|
+
FW.Log.receive("socket receive", msg);
|
|
17
|
+
FW.Log.system("system", msg);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
发布构建中框架会关闭 console 输出。业务代码不要自行覆盖 console。
|
|
21
|
+
|
|
22
|
+
## FrameworkBase.invoke
|
|
23
|
+
|
|
24
|
+
异步业务方法优先用 `invoke()`:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
const result = await this.invoke(
|
|
28
|
+
FW.Entry.resMgr.loadAssetData(asset),
|
|
29
|
+
"loadAssetData",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (!result) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`invoke()` 会:
|
|
38
|
+
|
|
39
|
+
- 记录开始和结束时间。
|
|
40
|
+
- 上报到 `performanceMgr`。
|
|
41
|
+
- 慢操作输出 warn。
|
|
42
|
+
- 捕获异常并输出结构化错误。
|
|
43
|
+
- 返回 `undefined`。
|
|
44
|
+
|
|
45
|
+
调用方必须处理 `undefined`。
|
|
46
|
+
|
|
47
|
+
## Promise 错误
|
|
48
|
+
|
|
49
|
+
使用 `FW.Entry.promiseMgr.execute()` 时设置合理超时:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const proxy = FW.Entry.promiseMgr.execute(resolveWork, {
|
|
53
|
+
timeout: 10000,
|
|
54
|
+
retryCount: 3,
|
|
55
|
+
retryInterval: 2,
|
|
56
|
+
retryCondition: (error, count) => true,
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
取消:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
proxy.abort("layer closed");
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
批量结果不会直接抛出所有错误,而是返回:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
{
|
|
70
|
+
success: [{ id, value }],
|
|
71
|
+
failed: [{ id, reason }],
|
|
72
|
+
cancelled: [id]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 资源加载失败
|
|
77
|
+
|
|
78
|
+
资源加载统一走 `FW.Entry.resMgr`。可注册拒绝处理器:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
FW.Entry.resMgr.registerRejectHandler({
|
|
82
|
+
loadBundleHandler(error, bundleName) {
|
|
83
|
+
FW.Log.error("load bundle failed", bundleName, error);
|
|
84
|
+
},
|
|
85
|
+
loadResHandler(error, path) {
|
|
86
|
+
FW.Log.error("load resource failed", path, error);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
加载失败时:
|
|
92
|
+
|
|
93
|
+
- 不继续操作节点。
|
|
94
|
+
- 不调用 `getAsset()` 兜底。
|
|
95
|
+
- UI 应显示空态、重试按钮或关闭弹窗。
|
|
96
|
+
- Codex 不应通过修改框架资源管理器绕过错误。
|
|
97
|
+
|
|
98
|
+
## Layer 错误
|
|
99
|
+
|
|
100
|
+
`FWLayerManager.openAsync()` 失败时会:
|
|
101
|
+
|
|
102
|
+
- 设置状态为 loading/opening。
|
|
103
|
+
- 失败后移除状态。
|
|
104
|
+
- 清理失败的 Layer 注册。
|
|
105
|
+
- 抛出错误。
|
|
106
|
+
|
|
107
|
+
业务调用:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
try {
|
|
111
|
+
await FW.Entry.layerMgr.openAsync({ type: RewardLayerController });
|
|
112
|
+
} catch (error) {
|
|
113
|
+
FW.Log.error("open reward layer failed", error);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`openSync()` 失败通常返回 `undefined`,调用方必须判断。
|
|
118
|
+
|
|
119
|
+
## Socket 错误
|
|
120
|
+
|
|
121
|
+
Socket 错误处理在 `Handle` 中实现:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
onError(msg: any) {
|
|
125
|
+
FW.Log.error("socket error", msg);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
onTimeout() {
|
|
129
|
+
FW.Entry.evtMgr.dispatch("SOCKET_TIMEOUT");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
onWeakNetWork() {
|
|
133
|
+
FW.Entry.evtMgr.dispatch("SOCKET_WEAK_NETWORK");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
onClose() {
|
|
137
|
+
FW.Entry.evtMgr.dispatch("SOCKET_CLOSED");
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
框架会处理:
|
|
142
|
+
|
|
143
|
+
- 心跳发送。
|
|
144
|
+
- 弱网检测。
|
|
145
|
+
- 心跳超时重连。
|
|
146
|
+
- 最大重连次数。
|
|
147
|
+
- 协议轮询清理。
|
|
148
|
+
|
|
149
|
+
业务不要重复实现底层重连循环。
|
|
150
|
+
|
|
151
|
+
## 事件清理
|
|
152
|
+
|
|
153
|
+
LayerController 销毁时,框架会调用:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
FW.Entry.timeMgr.unSchedule(this);
|
|
157
|
+
FW.Entry.evtMgr.targetOff(this);
|
|
158
|
+
this.layer?.unscheduleAllCallbacks();
|
|
159
|
+
this.layer?.node?.stopAllActions();
|
|
160
|
+
this.layer?.node?.destroy();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
普通对象或非 Layer 组件必须自行清理:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
onDestroy() {
|
|
167
|
+
FW.Entry.evtMgr.targetOff(this);
|
|
168
|
+
FW.Entry.timeMgr.unSchedule(this);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
UI 事件使用 `uiMgr.register()` 后,可用:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
FW.Entry.uiMgr.unRegisterTarget(target);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 定时器清理
|
|
179
|
+
|
|
180
|
+
创建定时器时传 target:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
FW.Entry.timeMgr.schedule(this.tick, 1, cc.macro.REPEAT_FOREVER, this);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
销毁时:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
FW.Entry.timeMgr.unSchedule(this);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
禁止使用无 target 的长期定时器,除非它属于全局系统并有明确 tag。
|
|
193
|
+
|
|
194
|
+
## 空值和节点有效性
|
|
195
|
+
|
|
196
|
+
操作 Cocos 节点前检查:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
if (!cc.isValid(node)) {
|
|
200
|
+
FW.Log.warn("node invalid");
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`FW.Entry.uiMgr.find()` 找不到节点会返回 `null` 并打印 warn。业务代码要处理:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const button = this.find("ConfirmButton", this.layer.node);
|
|
209
|
+
if (!button) return;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## 错误边界
|
|
213
|
+
|
|
214
|
+
推荐分层处理:
|
|
215
|
+
|
|
216
|
+
- 网络层:解析、连接、超时错误。
|
|
217
|
+
- Logic:业务失败和重试。
|
|
218
|
+
- Data:不抛 UI 错误。
|
|
219
|
+
- LayerController:展示失败状态、关闭或重试。
|
|
220
|
+
|
|
221
|
+
不要让底层错误直接导致 UI 生命周期中断且没有日志。
|
|
222
|
+
|
|
223
|
+
## Codex 错误处理清单
|
|
224
|
+
|
|
225
|
+
生成代码时必须检查:
|
|
226
|
+
|
|
227
|
+
- 每个 `await` 的失败路径是否可接受。
|
|
228
|
+
- `invoke()` 返回 `undefined` 时是否处理。
|
|
229
|
+
- `openSync()` 返回空是否处理。
|
|
230
|
+
- 节点查找失败是否处理。
|
|
231
|
+
- 事件和定时器是否随 target 清理。
|
|
232
|
+
- 资源路径是否来自 `AssetConfig`。
|
|
233
|
+
- Socket 错误是否在 `Handle` 中有入口。
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# Framework API
|
|
2
|
+
|
|
3
|
+
本文档记录业务开发最常复用的框架 API。除非维护框架本身,不要直接修改 `assets/framework`。
|
|
4
|
+
|
|
5
|
+
## 全局入口
|
|
6
|
+
|
|
7
|
+
### `FW.Entry`
|
|
8
|
+
|
|
9
|
+
常用属性:
|
|
10
|
+
|
|
11
|
+
| 属性 | 用途 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `bundleName` | 当前业务 bundle 名 |
|
|
14
|
+
| `scene` | 当前 `FW.Scene` |
|
|
15
|
+
| `resMgr` | 资源和 bundle 管理 |
|
|
16
|
+
| `layerMgr` | Layer 打开、关闭、栈、队列 |
|
|
17
|
+
| `uiMgr` | UI 事件、节点查找 |
|
|
18
|
+
| `evtMgr` | 框架事件总线 |
|
|
19
|
+
| `timeMgr` | 定时器和 update |
|
|
20
|
+
| `promiseMgr` | 可取消/超时/重试 Promise |
|
|
21
|
+
| `socketMgr` | Socket 连接 |
|
|
22
|
+
| `objectMgr` | 对象池 |
|
|
23
|
+
| `taskMgr` | 分帧任务 |
|
|
24
|
+
| `languageMgr` | 多语言 |
|
|
25
|
+
| `performanceMgr` | 性能采样 |
|
|
26
|
+
| `utils` | 通用工具 |
|
|
27
|
+
|
|
28
|
+
方法:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
FW.Entry.getComponent<T>(identifier): T
|
|
32
|
+
FW.Entry.getComponents<T>(identifier?): T[]
|
|
33
|
+
FW.Entry.launchScene(bundleName, forceRelease?)
|
|
34
|
+
FW.Entry.register({ bundleName, sceneName, depend, autoRelease })
|
|
35
|
+
FW.Entry.unRegister(...)
|
|
36
|
+
FW.Entry.getDepend(bundleName): string[]
|
|
37
|
+
FW.Entry.update(dt)
|
|
38
|
+
FW.Entry.restart()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 依赖容器
|
|
42
|
+
|
|
43
|
+
### `FW.Framework`
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
FW.Framework.register({
|
|
47
|
+
bundleName,
|
|
48
|
+
logic,
|
|
49
|
+
data,
|
|
50
|
+
config,
|
|
51
|
+
sender,
|
|
52
|
+
handle,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
FW.Framework.unRegister(...)
|
|
56
|
+
FW.Framework.getComponent<T>(ClassOrKey)
|
|
57
|
+
FW.Framework.getComponents<T>(BaseClass)
|
|
58
|
+
FW.Framework.addRegistry(bundleName, RegistryClass)
|
|
59
|
+
FW.Framework.createRegistry(bundleName)
|
|
60
|
+
FW.Framework.destroyRegistry(bundleName)
|
|
61
|
+
FW.Framework.restart()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
绑定 key 规则:`${bundleName}${FW.SystemDefine.FWBindTag.*}`。
|
|
65
|
+
|
|
66
|
+
业务代码通常通过 `FW.Entry.getComponent()` 间接使用,不直接操作容器。
|
|
67
|
+
|
|
68
|
+
## 基类
|
|
69
|
+
|
|
70
|
+
### `FW.FrameworkBase`
|
|
71
|
+
|
|
72
|
+
继承者:
|
|
73
|
+
|
|
74
|
+
- `FW.Logic`
|
|
75
|
+
- `FW.Data`
|
|
76
|
+
- `FW.Service`
|
|
77
|
+
- `FW.Sender`
|
|
78
|
+
- `FW.Handle`
|
|
79
|
+
- `FWManager`
|
|
80
|
+
- `FW.LayerController`
|
|
81
|
+
|
|
82
|
+
可用方法:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
this.entry
|
|
86
|
+
this.getLogic<T>()
|
|
87
|
+
this.getData<T>()
|
|
88
|
+
this.getConfig<T>()
|
|
89
|
+
this.getSender<T>()
|
|
90
|
+
this.getHandle<T>()
|
|
91
|
+
this.initializeDependencies()
|
|
92
|
+
await this.invoke(promise, "operationName")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
自动注入依赖依赖类名约定:
|
|
96
|
+
|
|
97
|
+
- `*Logic`
|
|
98
|
+
- `*Data`
|
|
99
|
+
- `*Config` 或 `*AssetConfig`
|
|
100
|
+
- `*Sender` 或 `*SocketSender`
|
|
101
|
+
- `*Handle` 或 `*SocketHandle`
|
|
102
|
+
|
|
103
|
+
类名还必须包含 bundle 名。例如 bundle 为 `shop`,推荐 `ShopLogic`、`ShopData`。
|
|
104
|
+
|
|
105
|
+
## Registry
|
|
106
|
+
|
|
107
|
+
### `FW.Registry`
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
abstract readonly bundleName: string;
|
|
111
|
+
readonly autoRelease?: boolean;
|
|
112
|
+
readonly sceneName?: string;
|
|
113
|
+
readonly depend?: string[];
|
|
114
|
+
readonly logic?: FW.Newable<FW.Logic>;
|
|
115
|
+
readonly data?: FW.Newable<FW.Data>;
|
|
116
|
+
readonly config?: FW.Newable<FW.AssetConfig>;
|
|
117
|
+
readonly sender?: FW.Newable<FW.Sender>;
|
|
118
|
+
readonly handle?: FW.Newable<FW.Handle>;
|
|
119
|
+
register(): void;
|
|
120
|
+
unRegister(): void;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
注册表用于把 bundle 元信息和业务组件交给框架。bundle 加载/释放会自动调用。
|
|
124
|
+
|
|
125
|
+
## Layer API
|
|
126
|
+
|
|
127
|
+
### `FW.Entry.layerMgr`
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
openAsync<Ctr>({ type, parent?, position?, args? }): Promise<Ctr>
|
|
131
|
+
openSync<Ctr>({ type, parent?, position?, args? }): Ctr
|
|
132
|
+
close(ctr): Promise<Ctr>
|
|
133
|
+
closeFromStack(count?)
|
|
134
|
+
closeFromLayerName(name | name[])
|
|
135
|
+
displayLayer(ctr)
|
|
136
|
+
hideLayer(ctr)
|
|
137
|
+
removeAllChildren(node)
|
|
138
|
+
clear()
|
|
139
|
+
openDebug()
|
|
140
|
+
getLayerMap()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`LayerOpenArgs`:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
type LayerOpenArgs = {
|
|
147
|
+
type: new () => FW.LayerController;
|
|
148
|
+
parent?: cc.Node;
|
|
149
|
+
position?: { x: number; y: number };
|
|
150
|
+
args?: any;
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `FW.LayerController`
|
|
155
|
+
|
|
156
|
+
业务控制器必须实现:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
renderOrder: FW.SystemDefine.FWLayerRenderOrder;
|
|
160
|
+
layerType: FW.SystemDefine.FWLayerType;
|
|
161
|
+
layer: FW.Layer;
|
|
162
|
+
layerAssetProperty: FW.AssetProperty;
|
|
163
|
+
autoRelease: boolean;
|
|
164
|
+
isRepeatOpen: boolean;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
生命周期:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
initialize()
|
|
171
|
+
onInit(...args)
|
|
172
|
+
onLoad()
|
|
173
|
+
onStart()
|
|
174
|
+
onEnable()
|
|
175
|
+
onDisable()
|
|
176
|
+
onUpdate(dt)
|
|
177
|
+
onLateUpdate(dt)
|
|
178
|
+
onClose()
|
|
179
|
+
onDestroy()
|
|
180
|
+
destroy()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
便捷方法:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
find(path, referenceNode)
|
|
187
|
+
findComponent<T>(path, referenceNode, type)
|
|
188
|
+
registerEvent(args)
|
|
189
|
+
cc(targetNode, cb, responseInterval?, eventName?)
|
|
190
|
+
fw(eventName, cb, target?, responseInterval?)
|
|
191
|
+
pauseEvent()
|
|
192
|
+
resumeEvent()
|
|
193
|
+
hide()
|
|
194
|
+
display()
|
|
195
|
+
close()
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 资源 API
|
|
199
|
+
|
|
200
|
+
### `FW.AssetProperty`
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
type AssetProperty = {
|
|
204
|
+
resourceId?: number;
|
|
205
|
+
bundle?: string;
|
|
206
|
+
path: string;
|
|
207
|
+
type?: typeof cc.Asset;
|
|
208
|
+
cb?: (asset: FW.AssetData | FW.AssetData[]) => void;
|
|
209
|
+
progress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void;
|
|
210
|
+
user?: string;
|
|
211
|
+
autoRelease?: boolean;
|
|
212
|
+
priorityLoaded?: boolean;
|
|
213
|
+
};
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### `FW.Entry.resMgr`
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
loadBundle(bundleName): Promise<cc.AssetManager.Bundle>
|
|
220
|
+
getBundle(bundleName): cc.AssetManager.Bundle
|
|
221
|
+
releaseBundle(bundleName): void
|
|
222
|
+
hasBundle(bundleName): boolean
|
|
223
|
+
|
|
224
|
+
loadAssetData<T>(assetProperty): Promise<FW.AssetData>
|
|
225
|
+
loadAsset<T>(assetProperty, texture?): Promise<T>
|
|
226
|
+
getAssetData<T>(assetProperty, texture?): FW.AssetData
|
|
227
|
+
getAsset<T>(assetProperty, texture?): T
|
|
228
|
+
preLoad(assetProperty | assetProperty[])
|
|
229
|
+
loadDir(assetProperty): Promise<FW.AssetData[]>
|
|
230
|
+
loadRemote<T>(url, options?): Promise<T>
|
|
231
|
+
loadSpineDataFromRemote({ img, ske, atlas, bin? }): Promise<sp.SkeletonData>
|
|
232
|
+
releaseAsset(assetProperty): void
|
|
233
|
+
hasAsset(assetProperty): boolean
|
|
234
|
+
registerRejectHandler(listener): void
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
纹理注意:默认 `Texture2D` 会转换为 `SpriteFrame`。需要原始纹理时传 `texture: true`。
|
|
238
|
+
|
|
239
|
+
## 事件 API
|
|
240
|
+
|
|
241
|
+
### `FW.Entry.evtMgr`
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
register(eventName, cb, target, options?)
|
|
245
|
+
registerOnce(eventName, cb, target, options?)
|
|
246
|
+
dispatch(eventName, ...args)
|
|
247
|
+
unRegister(eventName, target)
|
|
248
|
+
eventOff(eventName)
|
|
249
|
+
targetOff(target)
|
|
250
|
+
targetPause(target)
|
|
251
|
+
targetResume(target)
|
|
252
|
+
has(eventName, target)
|
|
253
|
+
getListenerCount(eventName)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`options`:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
{
|
|
260
|
+
priority?: FW.SystemDefine.FWPriorityOrder;
|
|
261
|
+
intercept?: boolean;
|
|
262
|
+
once?: boolean;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### `FW.Entry.uiMgr`
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
register({ target?, CCEvent?, FWEvent? })
|
|
270
|
+
find(path, rootNode): cc.Node | null
|
|
271
|
+
pauseEvent(target)
|
|
272
|
+
resumeEvent(target)
|
|
273
|
+
unRegisterEvent(args)
|
|
274
|
+
unRegisterTarget(target)
|
|
275
|
+
unRegisterAll()
|
|
276
|
+
hasRegister(eventName, target)
|
|
277
|
+
buttonEnable(target)
|
|
278
|
+
buttonDisable(target)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Time API
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
FW.Entry.timeMgr.schedule(cb, intervalSeconds?, repeat?, target?, tag?)
|
|
285
|
+
FW.Entry.timeMgr.scheduleOnce(cbOrTime?, timeOrTargetOrTag?, targetOrTag?)
|
|
286
|
+
FW.Entry.timeMgr.update(cb, tagOrTarget?, target?)
|
|
287
|
+
FW.Entry.timeMgr.pauseSchedule(tag | id | target)
|
|
288
|
+
FW.Entry.timeMgr.resumeSchedule(tag | id | target)
|
|
289
|
+
FW.Entry.timeMgr.unSchedule(tag | id | target)
|
|
290
|
+
FW.Entry.timeMgr.onUpdate(dt)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
返回的 `TimerSchedule` 支持:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
unSchedule()
|
|
297
|
+
pauseSchedule()
|
|
298
|
+
resumeSchedule()
|
|
299
|
+
promise? // scheduleOnce
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Promise API
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
const proxy = FW.Entry.promiseMgr.execute(executor, {
|
|
306
|
+
reason,
|
|
307
|
+
timeout,
|
|
308
|
+
retryCount,
|
|
309
|
+
retryInterval,
|
|
310
|
+
retryCondition,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
proxy.id
|
|
314
|
+
proxy.promise
|
|
315
|
+
proxy.status
|
|
316
|
+
proxy.abort(reason?)
|
|
317
|
+
proxy.addAbortEventListener(listener)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
批量:
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
FW.Entry.promiseMgr.all([proxy1, proxy2], options)
|
|
324
|
+
FW.Entry.promiseMgr.cancel(id, reason?)
|
|
325
|
+
FW.Entry.promiseMgr.cancelMultiple(ids, reason?)
|
|
326
|
+
FW.Entry.promiseMgr.cancelAll(reason?)
|
|
327
|
+
FW.Entry.promiseMgr.getStatus(id)
|
|
328
|
+
FW.Entry.promiseMgr.getAllStatus()
|
|
329
|
+
FW.Entry.promiseMgr.getActiveCount()
|
|
330
|
+
FW.Entry.promiseMgr.clearCompletedPromise()
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Socket API
|
|
334
|
+
|
|
335
|
+
### `FW.Entry.socketMgr`
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
createSocket(tag, address, sender, handle, config): Promise<FW.Socket>
|
|
339
|
+
getSocket(tag?): FW.Socket
|
|
340
|
+
getSocketMap(): Map<string, FW.Socket>
|
|
341
|
+
closeSocket(socket)
|
|
342
|
+
closeAll()
|
|
343
|
+
pauseMessageHandle()
|
|
344
|
+
resumeMessageHandle()
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### `FW.Sender`
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
sendHeart?()
|
|
351
|
+
onHeart?(msg): Promise<boolean>
|
|
352
|
+
onBeforeSendingMessage?(msg): Promise<FW.SocketMessage>
|
|
353
|
+
getProtocolKey?(msg): string
|
|
354
|
+
send(msg)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### `FW.Handle`
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
onMessage(msg): void
|
|
361
|
+
onBeforeReceivingMessage?(msg): Promise<FW.SocketMessage>
|
|
362
|
+
onHeart?(msg): Promise<boolean>
|
|
363
|
+
getProtocolKey?(msg): string
|
|
364
|
+
onOpen?()
|
|
365
|
+
onClose?()
|
|
366
|
+
onError?(msg)
|
|
367
|
+
onTimeout?()
|
|
368
|
+
onWeakNetWork?()
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Object Pool API
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
const pool = await FW.Entry.objectMgr.createObjectPool(prefabOrNodeOrAsset, parent, tagOrType?)
|
|
375
|
+
FW.Entry.objectMgr.getObjectPool(tag)
|
|
376
|
+
FW.Entry.objectMgr.destroyObjectPool(tag)
|
|
377
|
+
FW.Entry.objectMgr.getPoolStats()
|
|
378
|
+
FW.Entry.objectMgr.clearAllPools()
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
`FW.ObjectPool`:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
get(...args): FW.ObjectProperty
|
|
385
|
+
put(node | component | uniqueId)
|
|
386
|
+
puts(array)
|
|
387
|
+
findObjectProperty(node | component | uniqueId)
|
|
388
|
+
isEmpty()
|
|
389
|
+
getEnableObjectMap()
|
|
390
|
+
getDisableObjectMap()
|
|
391
|
+
getAllObjectMap()
|
|
392
|
+
onDestroy()
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
池对象组件继承 `FW.Object`,实现 `onInit()`、`onGet()`、`onPut()`、`onDestroy()`。
|
|
396
|
+
|
|
397
|
+
## 装饰器
|
|
398
|
+
|
|
399
|
+
全局装饰器由 `initializeFramework()` 挂到 `globalThis`:
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
@FWPropertyNode({ path? })
|
|
403
|
+
@FWPropertyNodes(...paths)
|
|
404
|
+
@FWPropertyComponent(ComponentClass, childName?, mute?)
|
|
405
|
+
@FWPropertyComponents(ComponentClass, childName?)
|
|
406
|
+
@PerformanceMonitor(operationName?)
|
|
407
|
+
@FWDeprecated(description?)
|
|
408
|
+
@FWSocketAutoProcessPause()
|
|
409
|
+
@FWSocketAutoProcessResume()
|
|
410
|
+
@AutoRegisterCCEvent(nodePath, eventName?)
|
|
411
|
+
@AutoRegisterFWEvent(eventName)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
装饰器会改写 `onLoad` 或方法 descriptor。使用时必须确认目标类生命周期和路径稳定。
|