@ives_xxz/framework 1.4.7 → 1.4.9

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.
@@ -18,7 +18,7 @@ export class FWLayerData<T extends FW.LayerController = FW.LayerController>
18
18
  layerRenderOrder: FWSystemDefine.FWLayerRenderOrder;
19
19
  layerType: FWSystemDefine.FWLayerType;
20
20
  layerParent?: cc.Node;
21
- layerPosition?: cc.Vec3;
21
+ layerPosition?: FW.Vec3;
22
22
  controllerName: string;
23
23
  controller: FW.LayerController;
24
24
  loaded: boolean;
@@ -26,282 +26,570 @@ export class FWLayerData<T extends FW.LayerController = FW.LayerController>
26
26
  externalReference?: Set<(ref: FW.LayerController | null) => void>;
27
27
  }
28
28
 
29
- export class FWLayerManager extends FWManager implements FW.LayerManager {
29
+ class FWLayerDataManager {
30
+ private layerMap: Map<new () => FW.LayerController, FWLayerData> = new Map();
31
+ private layerRegistry: Set<new () => FW.LayerController> = new Set();
32
+
30
33
  /**
31
- * 当前待打开的layer队列
34
+ * 获取已存在的Layer
32
35
  */
33
- private layerQueue: FWQueue<FW.LayerData>;
36
+ getExistingLayer<Ctr extends FW.LayerController = FW.LayerController>(
37
+ type: new () => Ctr,
38
+ ): Ctr | undefined {
39
+ for (const [key, value] of this.layerMap) {
40
+ if (value.controllerConstructor === type) {
41
+ return value.controllerProxy as Ctr;
42
+ }
43
+ }
44
+ return undefined;
45
+ }
46
+
34
47
  /**
35
- * 当前已经打开的layer缓存容器
48
+ * 从类型创建Layer数据
36
49
  */
37
- private layerMap: Map<new () => FW.LayerController, FW.LayerData>;
50
+ createLayerDataFromType<Ctr extends FW.LayerController = FW.LayerController>(
51
+ type: new () => Ctr,
52
+ ): FWLayerData | undefined {
53
+ const ctr = new type();
54
+ const ctrName = cc.js.getClassName(ctr);
55
+ const layerData = this.createBaseLayerData(ctr);
56
+
57
+ layerData.controllerConstructor = type;
58
+ layerData.controller = ctr;
59
+ layerData.controllerName = ctrName;
60
+
61
+ this.layerMap.set(type, layerData);
62
+ return layerData;
63
+ }
38
64
 
39
65
  /**
40
- * 当前所有打开Layer注册表
66
+ * 创建基础Layer数据
41
67
  */
42
- private layerRegistry: Set<new () => FW.LayerController>;
68
+ private createBaseLayerData(ctr: FW.LayerController): FWLayerData {
69
+ const layerData = new FWLayerData();
70
+ const layerType = ctr.layerType;
71
+
72
+ layerData.layerRenderOrder = ctr.renderOrder;
73
+ layerData.layerAssetProperty = ctr.layerAssetProperty;
74
+ layerData.layerType = layerType;
75
+ layerData.controller = ctr;
76
+ layerData.loaded = false;
77
+ layerData.externalReference = new Set();
78
+
79
+ return layerData;
80
+ }
81
+
43
82
  /**
44
- * layer栈队列
83
+ * 检查注册状态并添加
45
84
  */
46
- private layerStack: FWLayerData[];
85
+ checkRegistryAndAdd(type: new () => FW.LayerController): boolean {
86
+ if (this.layerRegistry.has(type)) {
87
+ return true;
88
+ }
89
+ this.layerRegistry.add(type);
90
+ return false;
91
+ }
47
92
 
48
- public initialize(): void {
49
- this.layerQueue = new FWQueue<FW.LayerData>();
50
- this.layerMap = new Map<new () => FW.LayerController, FW.LayerData>();
51
- this.layerRegistry = new Set<new () => FW.LayerController>();
52
- this.layerStack = [];
93
+ /**
94
+ * 获取已存在的代理
95
+ */
96
+ getExistingProxy<Ctr extends FW.LayerController = FW.LayerController>(
97
+ type: new () => Ctr,
98
+ ): Ctr | undefined {
99
+ return this.layerMap.get(type)?.controllerProxy as Ctr;
53
100
  }
54
101
 
55
102
  /**
56
- * 异步打开layer
57
- * @param layerData
58
- * @returns
103
+ * 设置Layer数据
59
104
  */
60
- protected async openLayerAsync(layerData: FWLayerData) {
61
- try {
62
- const res = await FW.Entry.resMgr.loadAssetData<cc.Prefab>(layerData.layerAssetProperty);
105
+ setupLayerData(
106
+ layerData: FWLayerData,
107
+ res: { asset: cc.Prefab; uuid: string },
108
+ layer: FWLayer,
109
+ layerName: string,
110
+ ): void {
111
+ layerData.loaded = true;
112
+ layerData.layer = layer;
113
+ layerData.layerName = layerName;
114
+ layerData.uuid = res.uuid;
63
115
 
64
- /** 保存资源数据 */
65
- res.user = layerData.layerName;
66
- res.autoRelease = layerData.controller.autoRelease;
67
- res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
116
+ layerData.controller.layerData = layerData;
117
+ layerData.controller.layer = layer;
118
+ layerData.controller.uuid = res.uuid;
68
119
 
69
- return res;
70
- } catch (e) {
71
- FWLog.error(`openLayerAsync failed : `, e);
72
- }
120
+ layer.ctr = layerData.controller;
73
121
  }
122
+
74
123
  /**
75
- * 同步打开layer
76
- * @param layerData
77
- * @returns
124
+ * 创建控制器代理
78
125
  */
79
- protected openLayerSync(layerData: FWLayerData) {
80
- layerData.layerAssetProperty.bundle =
81
- layerData.layerAssetProperty.bundle || FW.Entry.bundleName;
82
- const res = FW.Entry.resMgr.getAssetData<cc.Prefab>(layerData.layerAssetProperty);
83
- /** 保存资源数据 */
84
- res.user = layerData.layerName;
85
- res.autoRelease = layerData.controller.autoRelease;
86
- res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
126
+ createControllerProxy(layerData: FWLayerData): FW.LayerController {
127
+ return new Proxy(layerData.controller, {
128
+ get: (target, prop) => {
129
+ if (prop === ADD_EXTERNAL_REFERENCE) {
130
+ return (cb: (ref: FW.LayerController | null) => void) => {
131
+ layerData.externalReference.add(cb);
132
+ };
133
+ }
134
+ return target[prop];
135
+ },
136
+ });
137
+ }
87
138
 
88
- layerData.uuid = res.uuid;
139
+ /**
140
+ * 清理失败的Layer
141
+ */
142
+ cleanupFailedLayer(layerData: FWLayerData): void {
143
+ this.layerMap.delete(layerData.controllerConstructor);
144
+ this.layerRegistry.delete(layerData.controllerConstructor);
145
+ }
89
146
 
90
- return res;
147
+ /**
148
+ * 通知外部引用更新
149
+ */
150
+ notifyExternalRefUpdates(layerData: FWLayerData): void {
151
+ layerData.externalReference.forEach((cb) => {
152
+ try {
153
+ cb?.(null);
154
+ } catch (e) {
155
+ FWLog.error('External ref update callback error:', e);
156
+ }
157
+ });
158
+ layerData.externalReference.clear();
159
+ }
160
+
161
+ getLayerMap(): Map<new () => FW.LayerController, FWLayerData> {
162
+ return this.layerMap;
163
+ }
164
+
165
+ removeFromRegistry(type: new () => FW.LayerController): void {
166
+ this.layerRegistry.delete(type);
167
+ }
168
+
169
+ removeFromMap(type: new () => FW.LayerController): void {
170
+ this.layerMap.delete(type);
171
+ }
172
+
173
+ clear(): void {
174
+ this.layerMap.clear();
175
+ this.layerRegistry.clear();
91
176
  }
177
+ }
178
+
179
+ class FWLayerCreateManager {
180
+ private lifecycleManager: FWLayerLifecycleManager = new FWLayerLifecycleManager();
92
181
 
93
182
  /**
94
- * 创建layer数据
95
- * @param ctr
96
- * @returns
183
+ * 创建Layer节点
97
184
  */
98
- protected createLayerData(ctr: FW.LayerController) {
99
- const layerData = new FWLayerData();
100
- const layerType = ctr.layerType;
185
+ createLayer(
186
+ prefab: cc.Prefab,
187
+ layerComponent: string,
188
+ renderOrder: number,
189
+ parent: cc.Node,
190
+ position: FW.Vec3,
191
+ ): FWLayer {
192
+ parent = parent || FW.Entry.scene?.node;
193
+ position = position || cc.Vec3.ZERO;
101
194
 
102
- /** 记录layer数据 */
103
- layerData.layerRenderOrder = ctr.renderOrder;
104
- layerData.layerAssetProperty = ctr.layerAssetProperty;
105
- layerData.layerType = layerType;
106
- layerData.controller = ctr;
107
- layerData.loaded = false;
108
- layerData.externalReference = new Set();
195
+ if (!parent.activeInHierarchy || !cc.isValid(parent)) {
196
+ FWLog.error(`createLayer failed , parent : ${parent}`);
197
+ return;
198
+ }
109
199
 
110
- return layerData;
200
+ const node = cc.instantiate(prefab);
201
+ const p = cc.v3(position.x, position.y);
202
+ node.setParent(parent);
203
+ node.setPosition(p);
204
+ node.zIndex = renderOrder;
205
+
206
+ !node.getComponent(layerComponent) && node.addComponent(layerComponent);
207
+ return node.getComponent(FWLayer);
111
208
  }
112
209
 
113
210
  /**
114
- * 异步打开layer
115
- * @param data
116
- * @returns
211
+ * 设置Layer生命周期
117
212
  */
118
- async openAsync<Ctr extends FW.LayerController = FW.LayerController>(
213
+ setupLayerLifecycle(layer: FWLayer, ctr: FW.LayerController): void {
214
+ this.lifecycleManager.setupLifecycleHooks(layer, ctr);
215
+ }
216
+
217
+ /**
218
+ * 初始化控制器
219
+ */
220
+ initializeController(ctr: FW.LayerController, data: any): void {
221
+ ctr.initialize();
222
+ ctr.onInit?.(data);
223
+ }
224
+ }
225
+
226
+ class FWLayerOpenManager {
227
+ constructor(
228
+ private dataManager: FWLayerDataManager,
229
+ private resourceManager: FWLayerResourceManager,
230
+ private createManager: FWLayerCreateManager,
231
+ private stackManager: FWLayerStackManager,
232
+ private queueManager: FWLayerQueueManager,
233
+ ) {}
234
+
235
+ /**
236
+ * 统一的Layer打开方法
237
+ */
238
+ async openLayer<Ctr extends FW.LayerController = FW.LayerController>(
119
239
  data: FW.LayerOpenArgs,
240
+ isAsync: boolean,
120
241
  ): Promise<Ctr> {
121
- if (!data) {
122
- FWLog.error(`打开Layer失败:${data},请检查参数!`);
123
- return undefined;
242
+ if (!this.validateOpenData(data)) {
243
+ return this.getUndefinedResult(isAsync);
124
244
  }
125
245
 
126
- for (const [key, value] of this.layerMap) {
127
- if (value.controllerConstructor == data.type) {
128
- return value.controllerProxy as Ctr;
129
- }
246
+ const existingLayer = this.dataManager.getExistingLayer(data.type);
247
+ if (existingLayer) {
248
+ return this.wrapResult(existingLayer, isAsync) as Ctr;
130
249
  }
131
250
 
132
- const ctr = new data.type();
133
- const ctrName = cc.js.getClassName(ctr);
134
- const layerData = this.createLayerData(ctr);
251
+ const layerData = this.dataManager.createLayerDataFromType(data.type);
252
+ if (!layerData) {
253
+ return this.getUndefinedResult(isAsync);
254
+ }
135
255
 
136
- layerData.controllerConstructor = data.type;
137
- layerData.controller = ctr;
138
- layerData.controllerName = ctrName;
256
+ if (this.dataManager.checkRegistryAndAdd(data.type)) {
257
+ const proxy = this.dataManager.getExistingProxy(data.type);
258
+ return this.wrapResult(proxy, isAsync) as Ctr;
259
+ }
139
260
 
140
- this.layerMap.set(data.type, layerData);
261
+ if (this.queueManager.handlePopupQueue(layerData, this.dataManager.getLayerMap())) {
262
+ return this.getUndefinedResult(isAsync);
263
+ }
264
+
265
+ if (isAsync) {
266
+ return this.loadAndCreateLayerAsync(layerData, data);
267
+ } else {
268
+ return this.loadAndCreateLayerSync(layerData, data) as Ctr;
269
+ }
270
+ }
141
271
 
142
- if (this.layerRegistry.has(data.type)) {
143
- return this.layerMap.get(data.type).controllerProxy as Ctr;
272
+ /**
273
+ * 验证打开数据
274
+ */
275
+ private validateOpenData(data: FW.LayerOpenArgs): boolean {
276
+ if (!data) {
277
+ FWLog.error(`打开Layer失败:${data},请检查参数!`);
278
+ return false;
144
279
  }
280
+ return true;
281
+ }
145
282
 
146
- this.layerRegistry.add(data.type);
283
+ /**
284
+ * 获取undefined结果
285
+ */
286
+ private getUndefinedResult<Ctr>(isAsync: boolean): Promise<Ctr> | Ctr {
287
+ return isAsync ? Promise.resolve(undefined) : undefined;
288
+ }
147
289
 
148
- if (ctr.layerType == FWSystemDefine.FWLayerType.POPUP_QUEUE) {
149
- if (this.layerRegistry.size == 0) {
150
- let unclose = true;
151
- for (const [key, value] of this.layerMap) {
152
- if (value.layerType != FWSystemDefine.FWLayerType.PERMANENT) {
153
- unclose = false;
154
- }
155
- }
156
- if (!unclose) {
157
- this.layerQueue.add(ctr.layerData);
158
- return;
159
- }
160
- }
290
+ /**
291
+ * 包装结果
292
+ */
293
+ private wrapResult<Ctr>(result: Ctr, isAsync: boolean): Promise<Ctr> | Ctr {
294
+ return isAsync ? Promise.resolve(result) : result;
295
+ }
296
+
297
+ /**
298
+ * 异步加载资源并创建Layer
299
+ */
300
+ private async loadAndCreateLayerAsync<Ctr extends FW.LayerController = FW.LayerController>(
301
+ layerData: FWLayerData,
302
+ data: FW.LayerOpenArgs,
303
+ ): Promise<Ctr> {
304
+ try {
305
+ const res = await this.resourceManager.loadLayerAsync(layerData);
306
+ return this.createLayerAndSetup(layerData, res, data) as Ctr;
307
+ } catch (e) {
308
+ FWLog.error(`loadAndCreateLayerAsync failed:`, e);
309
+ this.dataManager.cleanupFailedLayer(layerData);
310
+ throw e;
161
311
  }
312
+ }
162
313
 
163
- ctr.initialize();
314
+ /**
315
+ * 同步加载资源并创建Layer
316
+ */
317
+ private loadAndCreateLayerSync<Ctr extends FW.LayerController = FW.LayerController>(
318
+ layerData: FWLayerData,
319
+ data: FW.LayerOpenArgs,
320
+ ): Ctr {
321
+ try {
322
+ const res = this.resourceManager.loadLayerSync(layerData);
323
+ return this.createLayerAndSetup(layerData, res, data);
324
+ } catch (e) {
325
+ FWLog.error(`loadAndCreateLayerSync failed:`, e);
326
+ this.dataManager.cleanupFailedLayer(layerData);
327
+ return undefined;
328
+ }
329
+ }
164
330
 
165
- const res = await this.openLayerAsync(layerData);
166
- const layer = await this.createLayer(
331
+ /**
332
+ * 创建Layer并进行设置
333
+ */
334
+ private createLayerAndSetup<Ctr extends FW.LayerController = FW.LayerController>(
335
+ layerData: FWLayerData,
336
+ res: { asset: cc.Prefab; uuid: string },
337
+ data: FW.LayerOpenArgs,
338
+ ): Ctr {
339
+ const layer = this.createManager.createLayer(
167
340
  res.asset,
168
341
  res.asset.name,
169
- ctr.renderOrder,
342
+ layerData.controller.renderOrder,
170
343
  data.parent,
171
344
  data.position,
172
345
  );
173
-
174
346
  const layerName = cc.js.getClassName(layer);
175
347
 
176
- ctr.layerData = layerData;
177
- ctr.layerData.loaded = true;
178
- ctr.layer = layer;
179
- ctr.layerData.layerName = layerName;
180
- ctr.layerData.uuid = res.uuid;
181
- ctr.uuid = res.uuid;
182
- ctr.onInit?.(data.args);
348
+ this.dataManager.setupLayerData(layerData, res, layer, layerName);
183
349
 
184
- this.lifecycleProcessing(ctr);
350
+ this.createManager.initializeController(layerData.controller, data.args);
185
351
 
186
- if (ctr.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
187
- this.layerStack.push(layerData);
352
+ this.createManager.setupLayerLifecycle(layer, layerData.controller);
353
+
354
+ if (layerData.controller.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
355
+ this.stackManager.push(layerData);
188
356
  }
189
357
 
190
- this.layerRegistry.delete(data.type);
358
+ this.dataManager.removeFromRegistry(layerData.controllerConstructor);
359
+
360
+ const proxy = this.dataManager.createControllerProxy(layerData);
361
+ layerData.controllerProxy = proxy;
191
362
 
192
- const proxy = new Proxy(ctr, {
193
- get: (target, prop) => {
194
- if (prop === ADD_EXTERNAL_REFERENCE) {
195
- return (cb: (ref: FW.LayerController | null) => void) => {
196
- layerData.externalReference.add(cb);
197
- };
198
- }
199
- return target[prop];
200
- },
201
- });
202
- ctr.layerData.controllerProxy = proxy;
203
363
  return proxy as Ctr;
204
364
  }
365
+ }
205
366
 
206
- /**
207
- * 同步打开
208
- * @param data
209
- * @returns
210
- */
211
- openSync<Ctr extends FW.LayerController = FW.LayerController>(data: FW.LayerOpenArgs): Ctr {
212
- if (!data) {
213
- FWLog.error(`open layer failed:${data},please check param!`);
214
- return undefined;
367
+ class FWLayerResourceManager {
368
+ async loadLayerAsync(layerData: FWLayerData): Promise<{ asset: cc.Prefab; uuid: string }> {
369
+ try {
370
+ const res = await FW.Entry.resMgr.loadAssetData<cc.Prefab>(layerData.layerAssetProperty);
371
+ res.user = layerData.layerName;
372
+ res.autoRelease = layerData.controller.autoRelease;
373
+ res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
374
+ return { asset: res.asset as cc.Prefab, uuid: res.uuid };
375
+ } catch (e) {
376
+ FWLog.error(`loadLayerAsync failed:`, e);
377
+ throw e;
215
378
  }
379
+ }
216
380
 
217
- for (const [key, value] of this.layerMap) {
218
- if (value.controllerConstructor == data.type) {
219
- return value.controllerProxy as Ctr;
220
- }
221
- }
381
+ loadLayerSync(layerData: FWLayerData): { asset: cc.Prefab; uuid: string } {
382
+ layerData.layerAssetProperty.bundle =
383
+ layerData.layerAssetProperty.bundle || FW.Entry.bundleName;
384
+ const res = FW.Entry.resMgr.getAssetData<cc.Prefab>(layerData.layerAssetProperty);
385
+ res.user = layerData.layerName;
386
+ res.autoRelease = layerData.controller.autoRelease;
387
+ res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
388
+ return { asset: res.asset as cc.Prefab, uuid: res.uuid };
389
+ }
390
+ }
222
391
 
223
- const ctr = new data.type();
224
- const ctrName = cc.js.getClassName(ctr);
225
- const layerData = this.createLayerData(ctr);
392
+ class FWLayerStackManager {
393
+ private layerStack: FWLayerData[] = [];
226
394
 
227
- layerData.controllerConstructor = data.type;
228
- layerData.controller = ctr;
229
- layerData.controllerName = ctrName;
395
+ push(layerData: FWLayerData): void {
396
+ if (layerData.controller.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
397
+ this.layerStack.push(layerData);
398
+ }
399
+ }
230
400
 
231
- this.layerMap.set(data.type, layerData);
401
+ pop(): FWLayerData | undefined {
402
+ return this.layerStack.pop();
403
+ }
232
404
 
233
- if (this.layerRegistry.has(data.type)) {
234
- return this.layerMap.get(data.type).controllerProxy as Ctr;
405
+ remove(layerData: FWLayerData): void {
406
+ const index = this.layerStack.findIndex((v) => v.controller === layerData.controller);
407
+ if (index > -1) {
408
+ this.layerStack.splice(index, 1);
235
409
  }
410
+ }
236
411
 
237
- this.layerRegistry.add(data.type);
412
+ getStack(): FWLayerData[] {
413
+ return [...this.layerStack];
414
+ }
238
415
 
239
- if (ctr.layerType == FWSystemDefine.FWLayerType.POPUP_QUEUE) {
240
- if (this.layerRegistry.size == 0) {
241
- let unclose = true;
242
- for (const [key, value] of this.layerMap) {
243
- if (value.layerType != FWSystemDefine.FWLayerType.PERMANENT) {
244
- unclose = false;
245
- }
246
- }
247
- if (!unclose) {
248
- this.layerQueue.add(ctr.layerData);
249
- return;
250
- }
416
+ clear(): void {
417
+ this.layerStack = [];
418
+ }
419
+ }
420
+
421
+ class FWLayerStateManager {
422
+ private layerStates = new Map<new () => FW.LayerController, FWSystemDefine.FWLayerState>();
423
+
424
+ setState(ctrType: new () => FW.LayerController, state: FWSystemDefine.FWLayerState): void {
425
+ this.layerStates.set(ctrType, state);
426
+ }
427
+
428
+ getState(ctrType: new () => FW.LayerController): FWSystemDefine.FWLayerState {
429
+ return this.layerStates.get(ctrType) || FWSystemDefine.FWLayerState.CLOSED;
430
+ }
431
+
432
+ isOpening(ctrType: new () => FW.LayerController): boolean {
433
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.OPENING;
434
+ }
435
+
436
+ isOpened(ctrType: new () => FW.LayerController): boolean {
437
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.OPENED;
438
+ }
439
+
440
+ isClosing(ctrType: new () => FW.LayerController): boolean {
441
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.CLOSING;
442
+ }
443
+
444
+ removeState(ctrType: new () => FW.LayerController): void {
445
+ this.layerStates.delete(ctrType);
446
+ }
447
+
448
+ clear(): void {
449
+ this.layerStates.clear();
450
+ }
451
+ }
452
+
453
+ class FWLayerQueueManager {
454
+ private layerQueue: FWQueue<FWLayerData> = new FWQueue<FWLayerData>();
455
+
456
+ handlePopupQueue(
457
+ layerData: FWLayerData,
458
+ layerMap: Map<new () => FW.LayerController, FWLayerData>,
459
+ ): boolean {
460
+ if (layerData.controller.layerType === FWSystemDefine.FWLayerType.POPUP_QUEUE) {
461
+ const hasNonPermanentLayers = Array.from(layerMap.values()).some(
462
+ (value) => value.layerType !== FWSystemDefine.FWLayerType.PERMANENT,
463
+ );
464
+
465
+ if (hasNonPermanentLayers) {
466
+ this.add(layerData);
467
+ return true;
251
468
  }
252
469
  }
470
+ return false;
471
+ }
253
472
 
254
- ctr.initialize();
473
+ getNextLayer(): FWLayerData | undefined {
474
+ return this.shift();
475
+ }
255
476
 
256
- const res = this.openLayerSync(layerData);
257
- const layer = this.createLayer(
258
- res.asset,
259
- res.asset.name,
260
- layerData.layerRenderOrder,
261
- layerData.layerParent,
262
- layerData.layerPosition,
263
- );
264
- const layerName = cc.js.getClassName(layer);
477
+ add(layerData: FWLayerData): void {
478
+ this.layerQueue.add(layerData);
479
+ }
265
480
 
266
- ctr.layerData = layerData;
267
- ctr.layerData.loaded = true;
268
- ctr.layer = layer;
269
- ctr.layerData.layerName = layerName;
270
- ctr.layerData.uuid = res.uuid;
271
- ctr.uuid = res.uuid;
272
- ctr.onInit?.(data.args);
481
+ shift(): FWLayerData | undefined {
482
+ return this.layerQueue.shift();
483
+ }
273
484
 
274
- this.lifecycleProcessing(ctr);
485
+ isEmpty(): boolean {
486
+ return this.layerQueue.isEmpty();
487
+ }
275
488
 
276
- if (ctr.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
277
- this.layerStack.push(layerData);
278
- }
489
+ clear(): void {
490
+ this.layerQueue.clear();
491
+ }
279
492
 
280
- this.layerRegistry.delete(data.type);
493
+ getQueue(): FWLayerData[] {
494
+ return this.layerQueue.getQueue();
495
+ }
496
+ }
281
497
 
282
- const proxy = new Proxy(ctr, {
283
- get: (target, prop) => {
284
- if (prop === 'addExternalReference') {
285
- return (cb: (ref: FW.LayerController | null) => void) => {
286
- layerData.externalReference.add(cb);
287
- };
288
- }
289
- return target[prop];
290
- },
291
- });
292
- ctr.layerData.controllerProxy = proxy;
293
- return proxy as Ctr;
498
+ class FWLayerLifecycleManager {
499
+ setupLifecycleHooks(layer: FWLayer, ctr: FW.LayerController): void {
500
+ const originalOnLoad = layer['onLoad'];
501
+ layer['onLoad'] = function () {
502
+ originalOnLoad?.call(this);
503
+ ctr.onLoad?.();
504
+ };
505
+
506
+ const originalStart = layer['start'];
507
+ layer['start'] = function () {
508
+ originalStart?.call(this);
509
+ ctr.onStart?.();
510
+ };
511
+
512
+ const originalOnEnable = layer['onEnable'];
513
+ layer['onEnable'] = function () {
514
+ originalOnEnable?.call(this);
515
+ ctr.onEnable?.();
516
+ };
517
+
518
+ const originalOnDisable = layer['onDisable'];
519
+ layer['onDisable'] = function () {
520
+ originalOnDisable?.call(this);
521
+ ctr.onDisable?.();
522
+ };
523
+
524
+ const originalOnDestroy = layer['onDestroy'];
525
+ layer['onDestroy'] = function () {
526
+ originalOnDestroy?.call(this);
527
+ ctr.onDestroy?.();
528
+ };
529
+
530
+ const originalUpdate = layer['update'];
531
+ layer['update'] = function (dt: number) {
532
+ originalUpdate?.call(this, dt);
533
+ ctr.onUpdate?.(dt);
534
+ };
535
+
536
+ const originalLateUpdate = layer['lateUpdate'];
537
+ layer['lateUpdate'] = function () {
538
+ originalLateUpdate?.call(this);
539
+ ctr.onLateUpdate?.();
540
+ };
541
+ }
542
+ }
543
+
544
+ export class FWLayerManager extends FWManager implements FW.LayerManager {
545
+ private resourceManager: FWLayerResourceManager;
546
+ private dataManager: FWLayerDataManager;
547
+ private createManager: FWLayerCreateManager;
548
+ private stackManager: FWLayerStackManager;
549
+ private stateManager: FWLayerStateManager;
550
+ private queueManager: FWLayerQueueManager;
551
+ private openManager: FWLayerOpenManager;
552
+
553
+ public initialize(): void {
554
+ this.resourceManager = new FWLayerResourceManager();
555
+ this.dataManager = new FWLayerDataManager();
556
+ this.createManager = new FWLayerCreateManager();
557
+ this.stackManager = new FWLayerStackManager();
558
+ this.stateManager = new FWLayerStateManager();
559
+ this.queueManager = new FWLayerQueueManager();
560
+
561
+ this.openManager = new FWLayerOpenManager(
562
+ this.dataManager,
563
+ this.resourceManager,
564
+ this.createManager,
565
+ this.stackManager,
566
+ this.queueManager,
567
+ );
568
+ }
569
+
570
+ /**
571
+ * 异步打开Layer
572
+ */
573
+ async openAsync<Ctr extends FW.LayerController = FW.LayerController>(
574
+ data: FW.LayerOpenArgs,
575
+ ): Promise<Ctr> {
576
+ return this.openManager.openLayer(data, true) as Promise<Ctr>;
577
+ }
578
+
579
+ /**
580
+ * 同步打开
581
+ */
582
+ openSync<Ctr extends FW.LayerController = FW.LayerController>(data: FW.LayerOpenArgs): Ctr {
583
+ return this.openManager.openLayer(data, false) as unknown as Ctr;
294
584
  }
295
585
 
296
586
  /**
297
587
  * 显示layer并恢复所有节点事件
298
- * @param ctr
299
- * @returns
300
588
  */
301
589
  displayLayer<Ctr extends FW.LayerController = FW.LayerController>(ctr: Ctr): Ctr {
302
590
  const layerData = ctr.layerData;
303
591
 
304
- if (!this.layerMap.has(ctr.layerData.controllerConstructor)) {
592
+ if (!this.dataManager.getLayerMap().has(ctr.layerData.controllerConstructor)) {
305
593
  FWLog.warn(`display layer failed,layer name : ${layerData.layerName}`);
306
594
  return;
307
595
  }
@@ -313,17 +601,17 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
313
601
  node.resumeSystemEvents(true);
314
602
 
315
603
  FW.Entry.evtMgr.targetResume(ctr);
316
- FW.Entry.timeMgr.pauseSchedule(ctr);
604
+ FW.Entry.timeMgr.resumeSchedule(ctr);
605
+
606
+ return ctr;
317
607
  }
318
608
 
319
609
  /**
320
610
  * 隐藏layer并隐藏所有节点事件
321
- * @param ctr
322
- * @returns
323
611
  */
324
612
  hideLayer<Ctr extends FW.LayerController = FW.LayerController>(ctr: Ctr): Ctr {
325
613
  const layerData = ctr.layerData;
326
- if (!this.layerMap.has(ctr.layerData.controllerConstructor)) {
614
+ if (!this.dataManager.getLayerMap().has(ctr.layerData.controllerConstructor)) {
327
615
  FWLog.warn(`hide layer failed,layer name : ${layerData.layerName}`);
328
616
  return;
329
617
  }
@@ -335,15 +623,16 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
335
623
  node.opacity = 0;
336
624
  node.pauseSystemEvents(true);
337
625
  FW.Entry.evtMgr.targetPause(ctr);
338
- FW.Entry.timeMgr.resumeSchedule(ctr);
626
+ FW.Entry.timeMgr.pauseSchedule(ctr);
627
+
628
+ return ctr;
339
629
  }
340
630
 
341
631
  /**
342
632
  * 通过layer名字关闭
343
- * @param name
344
633
  */
345
634
  closeFromLayerName(name: string | string[]): void {
346
- this.layerMap.forEach((v) => {
635
+ this.dataManager.getLayerMap().forEach((v) => {
347
636
  if (Array.isArray(name)) {
348
637
  name.forEach((n) => {
349
638
  if (n === v.layerName) {
@@ -357,15 +646,16 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
357
646
  }
358
647
  });
359
648
  }
649
+
360
650
  /**
361
651
  * 从栈关闭
362
652
  */
363
653
  closeFromStack(count?: number) {
364
654
  count = count ? count : 1;
365
655
  for (let i = 0; i < count; i++) {
366
- let layerData = this.layerStack.pop();
656
+ let layerData = this.stackManager.pop();
367
657
  let ctr = layerData.controller;
368
- if (!this.layerMap.has(layerData.controllerConstructor)) {
658
+ if (!this.dataManager.getLayerMap().has(layerData.controllerConstructor)) {
369
659
  return;
370
660
  }
371
661
  if (cc.isValid(ctr.layer?.node)) {
@@ -373,15 +663,28 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
373
663
  if (ctr.autoRelease) {
374
664
  FW.Entry.resMgr.releaseAsset(ctr.layerData.layerAssetProperty);
375
665
  }
376
- this.notifyExternalRefUpdates(ctr.layerData);
666
+ this.dataManager.notifyExternalRefUpdates(ctr.layerData);
377
667
  }
378
- this.layerMap.delete(layerData.controllerConstructor);
668
+ this.dataManager.removeFromMap(layerData.controllerConstructor);
379
669
  }
380
670
  }
671
+ /**
672
+ * 移除指定Layer所有子Layer
673
+ * @param layer
674
+ * @returns
675
+ */
676
+ async removeAllChildren(layer: FW.Layer) {
677
+ if (cc.isValid(!layer?.node)) return;
678
+ const layers = layer.node.getComponentsInChildren(FWLayer);
679
+ layers.forEach((v) => {
680
+ if (cc.isValid(v?.node)) {
681
+ v?.ctr?.close();
682
+ }
683
+ });
684
+ }
381
685
 
382
686
  /**
383
687
  * 关闭layer
384
- * @param ctr
385
688
  */
386
689
  async close<Ctr extends FW.LayerController = FW.LayerController>(
387
690
  ctr: Ctr,
@@ -397,20 +700,22 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
397
700
  if (ctr.autoRelease) {
398
701
  FW.Entry.resMgr.releaseAsset(ctr.layerData.layerAssetProperty);
399
702
  }
400
- this.notifyExternalRefUpdates(ctr.layerData);
703
+ this.dataManager.notifyExternalRefUpdates(ctr.layerData);
401
704
  }
402
705
 
403
- this.layerMap.delete(layerData.controllerConstructor);
404
- this.layerRegistry.delete(ctr.layerData.controllerConstructor);
706
+ this.dataManager.removeFromMap(layerData.controllerConstructor);
707
+ this.dataManager.removeFromRegistry(ctr.layerData.controllerConstructor);
405
708
 
406
- const index = this.layerStack.findIndex((v) => {
709
+ const index = this.stackManager.getStack().findIndex((v) => {
407
710
  v.controller == ctr;
408
711
  });
409
- this.layerStack.slice(index, 1);
712
+ if (index > -1) {
713
+ this.stackManager.getStack().splice(index, 1);
714
+ }
410
715
 
411
716
  /** 如果队列中还有等待打开的layer */
412
- if (!this.layerQueue.isEmpty()) {
413
- const nextLayerData = this.layerQueue.shift();
717
+ if (!this.queueManager.isEmpty()) {
718
+ const nextLayerData = this.queueManager.getNextLayer();
414
719
  /** 先尝试同步打开 */
415
720
  const nextLayer = this.openSync({
416
721
  parent: nextLayerData.layerParent,
@@ -432,102 +737,19 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
432
737
  }
433
738
  }
434
739
 
435
- private notifyExternalRefUpdates(layerData: FW.LayerData) {
436
- layerData.externalReference.forEach((cb) => {
437
- try {
438
- cb?.(null);
439
- } catch (e) {
440
- FWLog.error('External ref update callback error:', e);
441
- }
442
- });
443
- layerData.externalReference.clear();
444
- }
445
- /** 创建layer */
446
- private createLayer(
447
- prefab: cc.Prefab,
448
- layerComponent: string,
449
- renderOrder: number,
450
- parent: cc.Node,
451
- position: FW.Vec3,
452
- ) {
453
- parent = parent || FW.Entry.scene?.node;
454
-
455
- position = position || cc.Vec3.ZERO;
456
-
457
- if (!parent.activeInHierarchy || !cc.isValid(parent)) {
458
- FWLog.error(`createLayer failed , parent : ${parent}`);
459
- return;
460
- }
461
- const node = cc.instantiate(prefab);
462
- const p = cc.v3(position.x, position.y);
463
- node.setParent(parent);
464
- node.setPosition(p);
465
- node.zIndex = renderOrder;
466
- !node.getComponent(layerComponent) && node.addComponent(layerComponent);
467
- return node.getComponent(FWLayer);
468
- }
469
-
470
- private lifecycleProcessing(ctr: FW.LayerController) {
471
- const layer = ctr.layer;
472
-
473
- const onLoad = layer['onLoad'];
474
- layer['onLoad'] = () => {
475
- onLoad?.call(layer);
476
- ctr.onLoad?.();
477
- };
478
-
479
- const onStart = layer['start'];
480
- layer['start'] = () => {
481
- onStart?.call(layer);
482
- ctr.onStart?.();
483
- };
484
-
485
- const onEnable = layer['onEnable'];
486
- layer['onEnable'] = () => {
487
- onEnable?.call(layer);
488
- ctr.onEnable?.();
489
- };
490
-
491
- const onDisable = layer['onDisable'];
492
- layer['onDisable'] = () => {
493
- onDisable?.call(layer);
494
- ctr.onDisable?.();
495
- };
496
-
497
- const onDestroy = layer['onDestroy'];
498
- layer['onDestroy'] = () => {
499
- onDestroy?.call(layer);
500
- ctr.onDestroy?.();
501
- };
502
-
503
- const onUpdate = layer['update'];
504
- layer['update'] = (dt?: number) => {
505
- onUpdate?.call(layer);
506
- ctr.onUpdate?.(dt);
507
- };
508
-
509
- const onLateUpdate = layer['lateUpdate'];
510
- layer['lateUpdate'] = () => {
511
- onLateUpdate?.call(layer);
512
- ctr.onLateUpdate?.();
513
- };
514
- }
515
-
516
- getLayerMap(): Map<new () => FW.LayerController, FW.LayerData> {
517
- return this.layerMap;
740
+ getLayerMap(): Map<new () => FW.LayerController, FWLayerData> {
741
+ return this.dataManager.getLayerMap();
518
742
  }
519
743
 
520
744
  public clear() {
521
- this.layerQueue = new FWQueue();
522
- this.layerStack = [];
523
- this.layerRegistry = new Set<new () => FW.LayerController>();
524
- this.layerMap.forEach((v) => this.close(v.controller));
525
- this.layerMap.clear();
745
+ this.queueManager.clear();
746
+ this.stackManager.clear();
747
+ this.stateManager.clear();
748
+ this.dataManager.clear();
749
+ this.dataManager.getLayerMap().forEach((v) => this.close(v.controller));
526
750
  }
527
751
 
528
752
  public onDestroy(): void {
529
- this.layerMap.clear();
530
- this.layerMap = null;
531
- this.layerQueue = null;
753
+ this.clear();
532
754
  }
533
755
  }