@ives_xxz/framework 1.4.8 → 1.4.10

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/FW.d.ts CHANGED
@@ -660,6 +660,11 @@ declare namespace FW {
660
660
  * @param name
661
661
  */
662
662
  closeFromLayerName(name: string | string[]);
663
+ /**
664
+ * 移除所有子Layer
665
+ * @param layer
666
+ */
667
+ removeAllChildren(node: cc.Node);
663
668
 
664
669
  getLayerMap(): Map<new () => LayerController, LayerData>;
665
670
  };
@@ -968,6 +973,8 @@ declare namespace FW {
968
973
 
969
974
  type Layer = {
970
975
  readonly entry: FW.Entry;
976
+ node: cc.Node;
977
+ ctr: LayerController;
971
978
  onLoad(): void;
972
979
  start(): void;
973
980
  onEnable(): void;
@@ -1219,33 +1226,6 @@ declare namespace FW {
1219
1226
  * @returns
1220
1227
  */
1221
1228
  createSkeleton(skeleton: sp.Skeleton): FW.Skeleton;
1222
- /**
1223
- * 获取一个skeleton动画
1224
- * @param animationName
1225
- * @returns
1226
- */
1227
- getSkeleton(animationName: string): FW.Skeleton;
1228
-
1229
- /**
1230
- * 暂停一个skeleton动画
1231
- * @param animationName
1232
- * @returns
1233
- */
1234
- pauseSkeleton(animationName: string): void;
1235
-
1236
- /**
1237
- * 恢复一个skeleton动画
1238
- * @param animationName
1239
- * @returns
1240
- */
1241
- resumeSkeleton(animationName: string): void;
1242
-
1243
- /**
1244
- * 移除一个skeleton动画
1245
- * @param animationName
1246
- * @returns
1247
- */
1248
- removeSkeleton(animationName: string): void;
1249
1229
 
1250
1230
  /**
1251
1231
  * 暂停所有动画
@@ -1255,19 +1235,6 @@ declare namespace FW {
1255
1235
  * 恢复所有动画
1256
1236
  * */
1257
1237
  resumeAll(): void;
1258
- /**
1259
- * 创建动画机
1260
- * @param animationMachineName
1261
- * @returns
1262
- */
1263
- createAnimationMachine(animationMachineName: string): void;
1264
-
1265
- /**
1266
- * 移除动画机
1267
- * @param animationMachineName
1268
- * @returns
1269
- */
1270
- removeAnimationMachine(animationMachineName: string): void;
1271
1238
  };
1272
1239
 
1273
1240
  type Tween = {
package/Framework.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import 'reflect-metadata';
2
2
  import { Container, interfaces } from 'inversify';
3
3
  import { FWSystemDefine } from './define/FWSystemDefine';
4
- import FWLog from './log/FWLog';
5
4
 
6
5
  class Framework {
7
6
  private container: Container;
@@ -140,15 +139,12 @@ class Framework {
140
139
  */
141
140
  register(data: FW.RegisterFramework) {
142
141
  const classes = [data.logic, data.data, data.config, data.sender, data.handle];
143
- FWLog.debug('framework注册->', classes);
144
142
  classes.forEach((cls, index) => {
145
143
  if (cls && !this.container.isBound(cls)) {
146
- FWLog.debug('framework容器绑定成功->', cls);
147
144
  this.container.bind(cls).toSelf().inSingletonScope();
148
145
  this.container.bind(this.getKey(data.bundleName, index)).toService(cls);
149
146
  }
150
147
  });
151
- FWLog.debug('framework注册完成->', this.container);
152
148
  }
153
149
  /**
154
150
  * 注销数据
@@ -157,21 +153,17 @@ class Framework {
157
153
  */
158
154
  unRegister(data: FW.RegisterFramework) {
159
155
  const classes = [data.logic, data.data, data.config, data.sender, data.handle];
160
- FWLog.debug('framework注销->', classes);
161
156
  classes.forEach((cls, index) => {
162
157
  const key = this.getKey(data.bundleName, index);
163
158
  if (cls && this.container.isBound(cls)) {
164
159
  this.container.get(key)['onDestroy']?.();
165
160
  this.container.unbind(cls);
166
- FWLog.debug('framework容器解开绑定->', cls);
167
161
  }
168
162
  if (this.container.isBound(key)) {
169
163
  this.container.get(key)['onDestroy']?.();
170
164
  this.container.unbind(this.getKey(data.bundleName, index));
171
- FWLog.debug('framework容器解开绑定->', this.getKey(data.bundleName, index));
172
165
  }
173
166
  });
174
- FWLog.debug('framework注销完成->', this.container);
175
167
  }
176
168
 
177
169
  private getKey(bundleName: string, tag: FWSystemDefine.FWBindTag) {
@@ -28,7 +28,6 @@ export class FWSkeleton extends FWAnimation implements FW.Skeleton {
28
28
  return new Promise((resolve) => {
29
29
  this.animation.setCompleteListener(() => {
30
30
  this.animation.setCompleteListener(null);
31
- FW.Entry.animationMgr.removeSkeleton(this.animationName);
32
31
  args?.cb?.();
33
32
  resolve();
34
33
  });
@@ -137,4 +137,11 @@ export namespace FWSystemDefine {
137
137
  REJECTED = 'rejected',
138
138
  CANCELLED = 'cancelled',
139
139
  }
140
+
141
+ export enum FWLayerState {
142
+ CLOSED = 'closed',
143
+ OPENING = 'opening',
144
+ OPENED = 'opened',
145
+ CLOSING = 'closing',
146
+ }
140
147
  }
package/layer/FWLayer.ts CHANGED
@@ -3,6 +3,7 @@ const { ccclass, property } = cc._decorator;
3
3
  @ccclass
4
4
  export default class FWLayer extends cc.Component implements FW.Layer {
5
5
  public readonly entry: FW.Entry = FW.Entry;
6
+ public ctr: FW.LayerController;
6
7
  public onLoad(): void {}
7
8
  public start(): void {}
8
9
  public onEnable(): void {}
@@ -44,47 +44,6 @@ export default class FWAnimationManager extends FWManager {
44
44
  return s;
45
45
  }
46
46
 
47
- /**
48
- * 获取一个skeleton动画
49
- * @param animationName
50
- * @returns
51
- */
52
- getSkeleton(animationName: string) {
53
- if (!this.animationMachineMap.has(FWSystemDefine.FWAnimationMachineType.SKELETON)) return;
54
- return this.animationMachineMap
55
- .get(FWSystemDefine.FWAnimationMachineType.SKELETON)
56
- .getAnimation(animationName) as FWSkeleton;
57
- }
58
-
59
- /**
60
- * 暂停一个skeleton动画
61
- * @param animationName
62
- * @returns
63
- */
64
- pauseSkeleton(animationName: string) {
65
- if (!this.animationMachineMap.has(FWSystemDefine.FWAnimationMachineType.SKELETON)) return;
66
- this.animationMachineMap.get(animationName).pause();
67
- }
68
-
69
- /**
70
- * 恢复一个skeleton动画
71
- * @param animationName
72
- * @returns
73
- */
74
- resumeSkeleton(animationName: string) {
75
- if (!this.animationMachineMap.has(FWSystemDefine.FWAnimationMachineType.SKELETON)) return;
76
- this.animationMachineMap.get(animationName).resume();
77
- }
78
- /**
79
- * 移除一个skeleton动画
80
- * @param animationName
81
- * @returns
82
- */
83
- removeSkeleton(animationName: string) {
84
- if (!this.animationMachineMap.has(FWSystemDefine.FWAnimationMachineType.SKELETON)) return;
85
- this.animationMachineMap.delete(animationName);
86
- }
87
-
88
47
  /**
89
48
  * 暂停所有动画
90
49
  */
@@ -102,7 +61,7 @@ export default class FWAnimationManager extends FWManager {
102
61
  * @param animationMachineName
103
62
  * @returns
104
63
  */
105
- createAnimationMachine(animationMachineName: string) {
64
+ private createAnimationMachine(animationMachineName: string) {
106
65
  if (this.animationMachineMap.has(animationMachineName)) {
107
66
  FWLog.warn(`已创建动画机:${animationMachineName},请勿重复注册!`);
108
67
  return;
@@ -117,12 +76,16 @@ export default class FWAnimationManager extends FWManager {
117
76
  * @param animationMachineName
118
77
  * @returns
119
78
  */
120
- removeAnimationMachine(animationMachineName: string) {
79
+ private removeAnimationMachine(animationMachineName: string) {
121
80
  if (!this.animationMachineMap.has(animationMachineName)) {
122
81
  return;
123
82
  }
124
83
  this.animationMachineMap.delete(animationMachineName);
125
84
  }
126
85
 
127
- onDestroy(): void {}
86
+ onDestroy(): void {
87
+ this.animationMachineMap.forEach((v, k) => {
88
+ this.removeAnimationMachine(k);
89
+ });
90
+ }
128
91
  }
@@ -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,578 @@ 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
+ createLayerData<Ctr extends FW.LayerController = FW.LayerController>(
51
+ type: new () => Ctr,
52
+ ): FW.LayerData {
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
+ return layerData;
62
+ }
63
+
64
+ addLayerData(ctr: new () => FW.LayerController, layerData: FW.LayerData) {
65
+ if (!this.layerMap.has(ctr)) {
66
+ this.layerMap.set(ctr, layerData);
67
+ }
68
+ }
38
69
 
39
70
  /**
40
- * 当前所有打开Layer注册表
71
+ * 创建基础Layer数据
41
72
  */
42
- private layerRegistry: Set<new () => FW.LayerController>;
73
+ private createBaseLayerData(ctr: FW.LayerController): FWLayerData {
74
+ const layerData = new FWLayerData();
75
+ const layerType = ctr.layerType;
76
+
77
+ layerData.layerRenderOrder = ctr.renderOrder;
78
+ layerData.layerAssetProperty = ctr.layerAssetProperty;
79
+ layerData.layerType = layerType;
80
+ layerData.controller = ctr;
81
+ layerData.loaded = false;
82
+ layerData.externalReference = new Set();
83
+
84
+ return layerData;
85
+ }
86
+
43
87
  /**
44
- * layer栈队列
88
+ * 检查注册状态并添加
45
89
  */
46
- private layerStack: FWLayerData[];
90
+ checkRegistryAndAdd(type: new () => FW.LayerController): boolean {
91
+ if (this.layerRegistry.has(type)) {
92
+ return true;
93
+ }
94
+ this.layerRegistry.add(type);
95
+ return false;
96
+ }
47
97
 
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 = [];
98
+ /**
99
+ * 获取已存在的代理
100
+ */
101
+ getExistingProxy<Ctr extends FW.LayerController = FW.LayerController>(
102
+ type: new () => Ctr,
103
+ ): Ctr | undefined {
104
+ return this.layerMap.get(type)?.controllerProxy as Ctr;
53
105
  }
54
106
 
55
107
  /**
56
- * 异步打开layer
57
- * @param layerData
58
- * @returns
108
+ * 设置Layer数据
59
109
  */
60
- protected async openLayerAsync(layerData: FWLayerData) {
61
- try {
62
- const res = await FW.Entry.resMgr.loadAssetData<cc.Prefab>(layerData.layerAssetProperty);
110
+ setupLayerData(
111
+ layerData: FWLayerData,
112
+ res: { asset: cc.Prefab; uuid: string },
113
+ layer: FWLayer,
114
+ layerName: string,
115
+ ): void {
116
+ layerData.loaded = true;
117
+ layerData.layer = layer;
118
+ layerData.layerName = layerName;
119
+ layerData.uuid = res.uuid;
63
120
 
64
- /** 保存资源数据 */
65
- res.user = layerData.layerName;
66
- res.autoRelease = layerData.controller.autoRelease;
67
- res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
121
+ layerData.controller.layerData = layerData;
122
+ layerData.controller.layer = layer;
123
+ layerData.controller.uuid = res.uuid;
68
124
 
69
- return res;
70
- } catch (e) {
71
- FWLog.error(`openLayerAsync failed : `, e);
72
- }
125
+ layer.ctr = layerData.controller;
73
126
  }
127
+
74
128
  /**
75
- * 同步打开layer
76
- * @param layerData
77
- * @returns
129
+ * 创建控制器代理
78
130
  */
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;
131
+ createControllerProxy(layerData: FWLayerData): FW.LayerController {
132
+ return new Proxy(layerData.controller, {
133
+ get: (target, prop) => {
134
+ if (prop === ADD_EXTERNAL_REFERENCE) {
135
+ return (cb: (ref: FW.LayerController | null) => void) => {
136
+ layerData.externalReference.add(cb);
137
+ };
138
+ }
139
+ return target[prop];
140
+ },
141
+ });
142
+ }
87
143
 
88
- layerData.uuid = res.uuid;
144
+ /**
145
+ * 清理失败的Layer
146
+ */
147
+ cleanupFailedLayer(layerData: FWLayerData): void {
148
+ this.layerMap.delete(layerData.controllerConstructor);
149
+ this.layerRegistry.delete(layerData.controllerConstructor);
150
+ }
151
+
152
+ /**
153
+ * 通知外部引用更新
154
+ */
155
+ notifyExternalRefUpdates(layerData: FWLayerData): void {
156
+ layerData.externalReference.forEach((cb) => {
157
+ try {
158
+ cb?.(null);
159
+ } catch (e) {
160
+ FWLog.error('External ref update callback error:', e);
161
+ }
162
+ });
163
+ layerData.externalReference.clear();
164
+ }
89
165
 
90
- return res;
166
+ getLayerMap(): Map<new () => FW.LayerController, FWLayerData> {
167
+ return this.layerMap;
91
168
  }
92
169
 
170
+ removeFromRegistry(type: new () => FW.LayerController): void {
171
+ this.layerRegistry.delete(type);
172
+ }
173
+
174
+ removeFromMap(type: new () => FW.LayerController): void {
175
+ this.layerMap.delete(type);
176
+ }
177
+
178
+ clear(): void {
179
+ this.layerMap.clear();
180
+ this.layerRegistry.clear();
181
+ }
182
+ }
183
+
184
+ class FWLayerCreateManager {
185
+ private lifecycleManager: FWLayerLifecycleManager = new FWLayerLifecycleManager();
186
+
93
187
  /**
94
- * 创建layer数据
95
- * @param ctr
96
- * @returns
188
+ * 创建Layer节点
97
189
  */
98
- protected createLayerData(ctr: FW.LayerController) {
99
- const layerData = new FWLayerData();
100
- const layerType = ctr.layerType;
190
+ createLayer(
191
+ prefab: cc.Prefab,
192
+ layerComponent: string,
193
+ renderOrder: number,
194
+ parent: cc.Node,
195
+ position: FW.Vec3,
196
+ ): FWLayer {
197
+ parent = parent || FW.Entry.scene?.node;
198
+ position = position || cc.Vec3.ZERO;
101
199
 
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();
200
+ if (!parent.activeInHierarchy || !cc.isValid(parent)) {
201
+ FWLog.error(`createLayer failed , parent : ${parent}`);
202
+ return;
203
+ }
109
204
 
110
- return layerData;
205
+ const node = cc.instantiate(prefab);
206
+ const p = cc.v3(position.x, position.y);
207
+ node.setParent(parent);
208
+ node.setPosition(p);
209
+ node.zIndex = renderOrder;
210
+
211
+ !node.getComponent(layerComponent) && node.addComponent(layerComponent);
212
+ return node.getComponent(FWLayer);
111
213
  }
112
214
 
113
215
  /**
114
- * 异步打开layer
115
- * @param data
116
- * @returns
216
+ * 设置Layer生命周期
117
217
  */
118
- async openAsync<Ctr extends FW.LayerController = FW.LayerController>(
218
+ setupLayerLifecycle(layer: FWLayer, ctr: FW.LayerController): void {
219
+ this.lifecycleManager.setupLifecycleHooks(layer, ctr);
220
+ }
221
+
222
+ /**
223
+ * 初始化控制器
224
+ */
225
+ initializeController(ctr: FW.LayerController, data: any): void {
226
+ ctr.initialize();
227
+ ctr.onInit?.(data);
228
+ }
229
+ }
230
+
231
+ class FWLayerOpenManager {
232
+ constructor(
233
+ private dataManager: FWLayerDataManager,
234
+ private resourceManager: FWLayerResourceManager,
235
+ private createManager: FWLayerCreateManager,
236
+ private stackManager: FWLayerStackManager,
237
+ private queueManager: FWLayerQueueManager,
238
+ ) {}
239
+
240
+ /**
241
+ * 统一的Layer打开方法
242
+ */
243
+ async openLayer<Ctr extends FW.LayerController = FW.LayerController>(
119
244
  data: FW.LayerOpenArgs,
245
+ isAsync: boolean,
120
246
  ): Promise<Ctr> {
121
- if (!data) {
122
- FWLog.error(`打开Layer失败:${data},请检查参数!`);
123
- return undefined;
247
+ if (!this.validateOpenData(data)) {
248
+ return this.getUndefinedResult(isAsync);
124
249
  }
125
250
 
126
- for (const [key, value] of this.layerMap) {
127
- if (value.controllerConstructor == data.type) {
128
- return value.controllerProxy as Ctr;
129
- }
251
+ const existingLayer = this.dataManager.getExistingLayer(data.type);
252
+ if (existingLayer) {
253
+ return this.wrapResult(existingLayer, isAsync) as Ctr;
130
254
  }
131
255
 
132
- const ctr = new data.type();
133
- const ctrName = cc.js.getClassName(ctr);
134
- const layerData = this.createLayerData(ctr);
256
+ const layerData = this.dataManager.createLayerData(data.type);
135
257
 
136
- layerData.controllerConstructor = data.type;
137
- layerData.controller = ctr;
138
- layerData.controllerName = ctrName;
258
+ if (!layerData) {
259
+ return this.getUndefinedResult(isAsync);
260
+ }
139
261
 
140
- this.layerMap.set(data.type, layerData);
262
+ if (this.dataManager.checkRegistryAndAdd(data.type)) {
263
+ const proxy = this.dataManager.getExistingProxy(data.type);
264
+ return this.wrapResult(proxy, isAsync) as Ctr;
265
+ }
141
266
 
142
- if (this.layerRegistry.has(data.type)) {
143
- return this.layerMap.get(data.type).controllerProxy as Ctr;
267
+ if (this.queueManager.handlePopupQueue(layerData, this.dataManager.getLayerMap())) {
268
+ return this.getUndefinedResult(isAsync);
144
269
  }
145
270
 
146
- this.layerRegistry.add(data.type);
271
+ this.dataManager.addLayerData(data.type, layerData);
147
272
 
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
- }
273
+ if (isAsync) {
274
+ return this.loadAndCreateLayerAsync(layerData, data);
275
+ } else {
276
+ return this.loadAndCreateLayerSync(layerData, data) as Ctr;
161
277
  }
278
+ }
162
279
 
163
- ctr.initialize();
280
+ /**
281
+ * 验证打开数据
282
+ */
283
+ private validateOpenData(data: FW.LayerOpenArgs): boolean {
284
+ if (!data) {
285
+ FWLog.error(`打开Layer失败:${data},请检查参数!`);
286
+ return false;
287
+ }
288
+ return true;
289
+ }
164
290
 
165
- const res = await this.openLayerAsync(layerData);
166
- const layer = await this.createLayer(
291
+ /**
292
+ * 获取undefined结果
293
+ */
294
+ private getUndefinedResult<Ctr>(isAsync: boolean): Promise<Ctr> | Ctr {
295
+ return isAsync ? Promise.resolve(undefined) : undefined;
296
+ }
297
+
298
+ /**
299
+ * 包装结果
300
+ */
301
+ private wrapResult<Ctr>(result: Ctr, isAsync: boolean): Promise<Ctr> | Ctr {
302
+ return isAsync ? Promise.resolve(result) : result;
303
+ }
304
+
305
+ /**
306
+ * 异步加载资源并创建Layer
307
+ */
308
+ private async loadAndCreateLayerAsync<Ctr extends FW.LayerController = FW.LayerController>(
309
+ layerData: FWLayerData,
310
+ data: FW.LayerOpenArgs,
311
+ ): Promise<Ctr> {
312
+ try {
313
+ const res = await this.resourceManager.loadLayerAsync(layerData);
314
+ return this.createLayerAndSetup(layerData, res, data) as Ctr;
315
+ } catch (e) {
316
+ FWLog.error(`loadAndCreateLayerAsync failed:`, e);
317
+ this.dataManager.cleanupFailedLayer(layerData);
318
+ throw e;
319
+ }
320
+ }
321
+
322
+ /**
323
+ * 同步加载资源并创建Layer
324
+ */
325
+ private loadAndCreateLayerSync<Ctr extends FW.LayerController = FW.LayerController>(
326
+ layerData: FWLayerData,
327
+ data: FW.LayerOpenArgs,
328
+ ): Ctr {
329
+ try {
330
+ const res = this.resourceManager.loadLayerSync(layerData);
331
+ return this.createLayerAndSetup(layerData, res, data);
332
+ } catch (e) {
333
+ FWLog.error(`loadAndCreateLayerSync failed:`, e);
334
+ this.dataManager.cleanupFailedLayer(layerData);
335
+ return undefined;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * 创建Layer并进行设置
341
+ */
342
+ private createLayerAndSetup<Ctr extends FW.LayerController = FW.LayerController>(
343
+ layerData: FWLayerData,
344
+ res: { asset: cc.Prefab; uuid: string },
345
+ data: FW.LayerOpenArgs,
346
+ ): Ctr {
347
+ const layer = this.createManager.createLayer(
167
348
  res.asset,
168
349
  res.asset.name,
169
- ctr.renderOrder,
350
+ layerData.controller.renderOrder,
170
351
  data.parent,
171
352
  data.position,
172
353
  );
173
-
174
354
  const layerName = cc.js.getClassName(layer);
175
355
 
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);
356
+ this.dataManager.setupLayerData(layerData, res, layer, layerName);
183
357
 
184
- this.lifecycleProcessing(ctr);
358
+ this.createManager.initializeController(layerData.controller, data.args);
185
359
 
186
- if (ctr.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
187
- this.layerStack.push(layerData);
360
+ this.createManager.setupLayerLifecycle(layer, layerData.controller);
361
+
362
+ if (layerData.controller.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
363
+ this.stackManager.push(layerData);
188
364
  }
189
365
 
190
- this.layerRegistry.delete(data.type);
366
+ this.dataManager.removeFromRegistry(layerData.controllerConstructor);
367
+
368
+ const proxy = this.dataManager.createControllerProxy(layerData);
369
+ layerData.controllerProxy = proxy;
191
370
 
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
371
  return proxy as Ctr;
204
372
  }
373
+ }
205
374
 
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;
375
+ class FWLayerResourceManager {
376
+ async loadLayerAsync(layerData: FWLayerData): Promise<{ asset: cc.Prefab; uuid: string }> {
377
+ try {
378
+ const res = await FW.Entry.resMgr.loadAssetData<cc.Prefab>(layerData.layerAssetProperty);
379
+ res.user = layerData.layerName;
380
+ res.autoRelease = layerData.controller.autoRelease;
381
+ res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
382
+ return { asset: res.asset as cc.Prefab, uuid: res.uuid };
383
+ } catch (e) {
384
+ FWLog.error(`loadLayerAsync failed:`, e);
385
+ throw e;
215
386
  }
387
+ }
216
388
 
217
- for (const [key, value] of this.layerMap) {
218
- if (value.controllerConstructor == data.type) {
219
- return value.controllerProxy as Ctr;
220
- }
221
- }
389
+ loadLayerSync(layerData: FWLayerData): { asset: cc.Prefab; uuid: string } {
390
+ layerData.layerAssetProperty.bundle =
391
+ layerData.layerAssetProperty.bundle || FW.Entry.bundleName;
392
+ const res = FW.Entry.resMgr.getAssetData<cc.Prefab>(layerData.layerAssetProperty);
393
+ res.user = layerData.layerName;
394
+ res.autoRelease = layerData.controller.autoRelease;
395
+ res.dependentBundle = layerData.controller.layerAssetProperty.bundle;
396
+ return { asset: res.asset as cc.Prefab, uuid: res.uuid };
397
+ }
398
+ }
222
399
 
223
- const ctr = new data.type();
224
- const ctrName = cc.js.getClassName(ctr);
225
- const layerData = this.createLayerData(ctr);
400
+ class FWLayerStackManager {
401
+ private layerStack: FWLayerData[] = [];
226
402
 
227
- layerData.controllerConstructor = data.type;
228
- layerData.controller = ctr;
229
- layerData.controllerName = ctrName;
403
+ push(layerData: FWLayerData): void {
404
+ if (layerData.controller.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
405
+ this.layerStack.push(layerData);
406
+ }
407
+ }
230
408
 
231
- this.layerMap.set(data.type, layerData);
409
+ pop(): FWLayerData | undefined {
410
+ return this.layerStack.pop();
411
+ }
232
412
 
233
- if (this.layerRegistry.has(data.type)) {
234
- return this.layerMap.get(data.type).controllerProxy as Ctr;
413
+ remove(layerData: FWLayerData): void {
414
+ const index = this.layerStack.findIndex((v) => v.controller === layerData.controller);
415
+ if (index > -1) {
416
+ this.layerStack.splice(index, 1);
235
417
  }
418
+ }
236
419
 
237
- this.layerRegistry.add(data.type);
420
+ getStack(): FWLayerData[] {
421
+ return [...this.layerStack];
422
+ }
238
423
 
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
- }
424
+ clear(): void {
425
+ this.layerStack = [];
426
+ }
427
+ }
428
+
429
+ class FWLayerStateManager {
430
+ private layerStates = new Map<new () => FW.LayerController, FWSystemDefine.FWLayerState>();
431
+
432
+ setState(ctrType: new () => FW.LayerController, state: FWSystemDefine.FWLayerState): void {
433
+ this.layerStates.set(ctrType, state);
434
+ }
435
+
436
+ getState(ctrType: new () => FW.LayerController): FWSystemDefine.FWLayerState {
437
+ return this.layerStates.get(ctrType) || FWSystemDefine.FWLayerState.CLOSED;
438
+ }
439
+
440
+ isOpening(ctrType: new () => FW.LayerController): boolean {
441
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.OPENING;
442
+ }
443
+
444
+ isOpened(ctrType: new () => FW.LayerController): boolean {
445
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.OPENED;
446
+ }
447
+
448
+ isClosing(ctrType: new () => FW.LayerController): boolean {
449
+ return this.getState(ctrType) === FWSystemDefine.FWLayerState.CLOSING;
450
+ }
451
+
452
+ removeState(ctrType: new () => FW.LayerController): void {
453
+ this.layerStates.delete(ctrType);
454
+ }
455
+
456
+ clear(): void {
457
+ this.layerStates.clear();
458
+ }
459
+ }
460
+
461
+ class FWLayerQueueManager {
462
+ private layerQueue: FWQueue<FWLayerData> = new FWQueue<FWLayerData>();
463
+
464
+ handlePopupQueue(
465
+ layerData: FWLayerData,
466
+ layerMap: Map<new () => FW.LayerController, FWLayerData>,
467
+ ): boolean {
468
+ if (layerData.controller.layerType === FWSystemDefine.FWLayerType.POPUP_QUEUE) {
469
+ const hasNonPermanentLayers = Array.from(layerMap.values()).some(
470
+ (value) => value.layerType === FWSystemDefine.FWLayerType.POPUP_QUEUE,
471
+ );
472
+
473
+ if (hasNonPermanentLayers) {
474
+ this.add(layerData);
475
+ return true;
251
476
  }
252
477
  }
478
+ return false;
479
+ }
253
480
 
254
- ctr.initialize();
481
+ getNextLayer(): FWLayerData | undefined {
482
+ return this.shift();
483
+ }
255
484
 
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);
485
+ add(layerData: FWLayerData): void {
486
+ this.layerQueue.add(layerData);
487
+ }
265
488
 
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);
489
+ shift(): FWLayerData | undefined {
490
+ return this.layerQueue.shift();
491
+ }
273
492
 
274
- this.lifecycleProcessing(ctr);
493
+ isEmpty(): boolean {
494
+ return this.layerQueue.isEmpty();
495
+ }
275
496
 
276
- if (ctr.layerType !== FWSystemDefine.FWLayerType.PERMANENT) {
277
- this.layerStack.push(layerData);
278
- }
497
+ clear(): void {
498
+ this.layerQueue.clear();
499
+ }
279
500
 
280
- this.layerRegistry.delete(data.type);
501
+ getQueue(): FWLayerData[] {
502
+ return this.layerQueue.getQueue();
503
+ }
504
+ }
281
505
 
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;
506
+ class FWLayerLifecycleManager {
507
+ setupLifecycleHooks(layer: FWLayer, ctr: FW.LayerController): void {
508
+ const originalOnLoad = layer['onLoad'];
509
+ layer['onLoad'] = function () {
510
+ originalOnLoad?.call(this);
511
+ ctr.onLoad?.();
512
+ };
513
+
514
+ const originalStart = layer['start'];
515
+ layer['start'] = function () {
516
+ originalStart?.call(this);
517
+ ctr.onStart?.();
518
+ };
519
+
520
+ const originalOnEnable = layer['onEnable'];
521
+ layer['onEnable'] = function () {
522
+ originalOnEnable?.call(this);
523
+ ctr.onEnable?.();
524
+ };
525
+
526
+ const originalOnDisable = layer['onDisable'];
527
+ layer['onDisable'] = function () {
528
+ originalOnDisable?.call(this);
529
+ ctr.onDisable?.();
530
+ };
531
+
532
+ const originalOnDestroy = layer['onDestroy'];
533
+ layer['onDestroy'] = function () {
534
+ originalOnDestroy?.call(this);
535
+ ctr.onDestroy?.();
536
+ };
537
+
538
+ const originalUpdate = layer['update'];
539
+ layer['update'] = function (dt: number) {
540
+ originalUpdate?.call(this, dt);
541
+ ctr.onUpdate?.(dt);
542
+ };
543
+
544
+ const originalLateUpdate = layer['lateUpdate'];
545
+ layer['lateUpdate'] = function () {
546
+ originalLateUpdate?.call(this);
547
+ ctr.onLateUpdate?.();
548
+ };
549
+ }
550
+ }
551
+
552
+ export class FWLayerManager extends FWManager implements FW.LayerManager {
553
+ private resourceManager: FWLayerResourceManager;
554
+ private dataManager: FWLayerDataManager;
555
+ private createManager: FWLayerCreateManager;
556
+ private stackManager: FWLayerStackManager;
557
+ private stateManager: FWLayerStateManager;
558
+ private queueManager: FWLayerQueueManager;
559
+ private openManager: FWLayerOpenManager;
560
+
561
+ public initialize(): void {
562
+ this.resourceManager = new FWLayerResourceManager();
563
+ this.dataManager = new FWLayerDataManager();
564
+ this.createManager = new FWLayerCreateManager();
565
+ this.stackManager = new FWLayerStackManager();
566
+ this.stateManager = new FWLayerStateManager();
567
+ this.queueManager = new FWLayerQueueManager();
568
+
569
+ this.openManager = new FWLayerOpenManager(
570
+ this.dataManager,
571
+ this.resourceManager,
572
+ this.createManager,
573
+ this.stackManager,
574
+ this.queueManager,
575
+ );
576
+ }
577
+
578
+ /**
579
+ * 异步打开Layer
580
+ */
581
+ async openAsync<Ctr extends FW.LayerController = FW.LayerController>(
582
+ data: FW.LayerOpenArgs,
583
+ ): Promise<Ctr> {
584
+ return this.openManager.openLayer(data, true) as Promise<Ctr>;
585
+ }
586
+
587
+ /**
588
+ * 同步打开
589
+ */
590
+ openSync<Ctr extends FW.LayerController = FW.LayerController>(data: FW.LayerOpenArgs): Ctr {
591
+ return this.openManager.openLayer(data, false) as unknown as Ctr;
294
592
  }
295
593
 
296
594
  /**
297
595
  * 显示layer并恢复所有节点事件
298
- * @param ctr
299
- * @returns
300
596
  */
301
597
  displayLayer<Ctr extends FW.LayerController = FW.LayerController>(ctr: Ctr): Ctr {
302
598
  const layerData = ctr.layerData;
303
599
 
304
- if (!this.layerMap.has(ctr.layerData.controllerConstructor)) {
600
+ if (!this.dataManager.getLayerMap().has(ctr.layerData.controllerConstructor)) {
305
601
  FWLog.warn(`display layer failed,layer name : ${layerData.layerName}`);
306
602
  return;
307
603
  }
@@ -313,17 +609,17 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
313
609
  node.resumeSystemEvents(true);
314
610
 
315
611
  FW.Entry.evtMgr.targetResume(ctr);
316
- FW.Entry.timeMgr.pauseSchedule(ctr);
612
+ FW.Entry.timeMgr.resumeSchedule(ctr);
613
+
614
+ return ctr;
317
615
  }
318
616
 
319
617
  /**
320
618
  * 隐藏layer并隐藏所有节点事件
321
- * @param ctr
322
- * @returns
323
619
  */
324
620
  hideLayer<Ctr extends FW.LayerController = FW.LayerController>(ctr: Ctr): Ctr {
325
621
  const layerData = ctr.layerData;
326
- if (!this.layerMap.has(ctr.layerData.controllerConstructor)) {
622
+ if (!this.dataManager.getLayerMap().has(ctr.layerData.controllerConstructor)) {
327
623
  FWLog.warn(`hide layer failed,layer name : ${layerData.layerName}`);
328
624
  return;
329
625
  }
@@ -335,15 +631,16 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
335
631
  node.opacity = 0;
336
632
  node.pauseSystemEvents(true);
337
633
  FW.Entry.evtMgr.targetPause(ctr);
338
- FW.Entry.timeMgr.resumeSchedule(ctr);
634
+ FW.Entry.timeMgr.pauseSchedule(ctr);
635
+
636
+ return ctr;
339
637
  }
340
638
 
341
639
  /**
342
640
  * 通过layer名字关闭
343
- * @param name
344
641
  */
345
642
  closeFromLayerName(name: string | string[]): void {
346
- this.layerMap.forEach((v) => {
643
+ this.dataManager.getLayerMap().forEach((v) => {
347
644
  if (Array.isArray(name)) {
348
645
  name.forEach((n) => {
349
646
  if (n === v.layerName) {
@@ -357,15 +654,16 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
357
654
  }
358
655
  });
359
656
  }
657
+
360
658
  /**
361
659
  * 从栈关闭
362
660
  */
363
661
  closeFromStack(count?: number) {
364
662
  count = count ? count : 1;
365
663
  for (let i = 0; i < count; i++) {
366
- let layerData = this.layerStack.pop();
664
+ let layerData = this.stackManager.pop();
367
665
  let ctr = layerData.controller;
368
- if (!this.layerMap.has(layerData.controllerConstructor)) {
666
+ if (!this.dataManager.getLayerMap().has(layerData.controllerConstructor)) {
369
667
  return;
370
668
  }
371
669
  if (cc.isValid(ctr.layer?.node)) {
@@ -373,15 +671,28 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
373
671
  if (ctr.autoRelease) {
374
672
  FW.Entry.resMgr.releaseAsset(ctr.layerData.layerAssetProperty);
375
673
  }
376
- this.notifyExternalRefUpdates(ctr.layerData);
674
+ this.dataManager.notifyExternalRefUpdates(ctr.layerData);
377
675
  }
378
- this.layerMap.delete(layerData.controllerConstructor);
676
+ this.dataManager.removeFromMap(layerData.controllerConstructor);
379
677
  }
380
678
  }
679
+ /**
680
+ * 移除指定Layer所有子Layer
681
+ * @param layer
682
+ * @returns
683
+ */
684
+ async removeAllChildren(node: cc.Node) {
685
+ if (!cc.isValid(node)) return;
686
+ const layers = node.getComponentsInChildren(FWLayer);
687
+ layers.forEach((v) => {
688
+ if (cc.isValid(v?.node)) {
689
+ v?.ctr?.close();
690
+ }
691
+ });
692
+ }
381
693
 
382
694
  /**
383
695
  * 关闭layer
384
- * @param ctr
385
696
  */
386
697
  async close<Ctr extends FW.LayerController = FW.LayerController>(
387
698
  ctr: Ctr,
@@ -397,20 +708,22 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
397
708
  if (ctr.autoRelease) {
398
709
  FW.Entry.resMgr.releaseAsset(ctr.layerData.layerAssetProperty);
399
710
  }
400
- this.notifyExternalRefUpdates(ctr.layerData);
711
+ this.dataManager.notifyExternalRefUpdates(ctr.layerData);
401
712
  }
402
713
 
403
- this.layerMap.delete(layerData.controllerConstructor);
404
- this.layerRegistry.delete(ctr.layerData.controllerConstructor);
714
+ this.dataManager.removeFromMap(layerData.controllerConstructor);
715
+ this.dataManager.removeFromRegistry(ctr.layerData.controllerConstructor);
405
716
 
406
- const index = this.layerStack.findIndex((v) => {
717
+ const index = this.stackManager.getStack().findIndex((v) => {
407
718
  v.controller == ctr;
408
719
  });
409
- this.layerStack.slice(index, 1);
720
+ if (index > -1) {
721
+ this.stackManager.getStack().splice(index, 1);
722
+ }
410
723
 
411
724
  /** 如果队列中还有等待打开的layer */
412
- if (!this.layerQueue.isEmpty()) {
413
- const nextLayerData = this.layerQueue.shift();
725
+ if (!this.queueManager.isEmpty()) {
726
+ const nextLayerData = this.queueManager.getNextLayer();
414
727
  /** 先尝试同步打开 */
415
728
  const nextLayer = this.openSync({
416
729
  parent: nextLayerData.layerParent,
@@ -432,102 +745,19 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
432
745
  }
433
746
  }
434
747
 
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;
748
+ getLayerMap(): Map<new () => FW.LayerController, FWLayerData> {
749
+ return this.dataManager.getLayerMap();
518
750
  }
519
751
 
520
752
  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();
753
+ this.queueManager.clear();
754
+ this.stackManager.clear();
755
+ this.stateManager.clear();
756
+ this.dataManager.clear();
757
+ this.dataManager.getLayerMap().forEach((v) => this.close(v.controller));
526
758
  }
527
759
 
528
760
  public onDestroy(): void {
529
- this.layerMap.clear();
530
- this.layerMap = null;
531
- this.layerQueue = null;
761
+ this.clear();
532
762
  }
533
763
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ives_xxz/framework",
3
- "version": "1.4.8",
3
+ "version": "1.4.10",
4
4
  "description": "cocoscreator 2.x mvc framework",
5
5
  "main": "index.js",
6
6
  "keywords": ["123456"],
package/utils/FWQueue.ts CHANGED
@@ -44,4 +44,12 @@ export class FWQueue<T> {
44
44
  public size() {
45
45
  return this.queue.length;
46
46
  }
47
+
48
+ public clear() {
49
+ this.queue = [];
50
+ }
51
+
52
+ public getQueue() {
53
+ return this.queue;
54
+ }
47
55
  }