@cc-component/cc-core 1.8.2 → 1.8.4
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.
|
@@ -4,12 +4,18 @@ import { EnvironmentConfig, IConfig } from './IConfig';
|
|
|
4
4
|
import { LayerType } from './LayerType';
|
|
5
5
|
import { Canvas, director } from 'cc';
|
|
6
6
|
import { ResourceManager } from '../home/ResourceManager';
|
|
7
|
-
import { IBundleConfig, IInitConfig } from './CommonEnum';
|
|
7
|
+
import { IBundleConfig, IInitConfig, IWindowParam, SystemMessage } from './CommonEnum';
|
|
8
8
|
import { ISceneParam } from '../interface/ISceneParam';
|
|
9
9
|
import { BlockInputEvents } from 'cc';
|
|
10
10
|
import { BaseLaunchComponent } from '../home/BaseLaunchComponent';
|
|
11
11
|
import { AssetManager } from 'cc';
|
|
12
|
-
import {
|
|
12
|
+
import { Component } from 'cc';
|
|
13
|
+
import { Prefab, instantiate, isValid } from 'cc';
|
|
14
|
+
import { sp } from 'cc';
|
|
15
|
+
import { SkeletonAnim } from '../home/BaseSkeleton';
|
|
16
|
+
import { Sprite, SpriteFrame } from 'cc';
|
|
17
|
+
import { Game } from 'cc';
|
|
18
|
+
import { game } from 'cc';
|
|
13
19
|
|
|
14
20
|
const { ccclass, property } = _decorator;
|
|
15
21
|
|
|
@@ -20,14 +26,24 @@ export class LayerUI {
|
|
|
20
26
|
public get current_config(): EnvironmentConfig {
|
|
21
27
|
return this.config.config[this.config.type]
|
|
22
28
|
}
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
|
|
30
|
+
private openWindowLayer: Map<string, string[]> = new Map();
|
|
31
|
+
private openedWindows: Map<string, Component> = new Map();
|
|
32
|
+
private openedWindowsConfig: Map<string, IBundleConfig> = new Map();
|
|
33
|
+
|
|
34
|
+
/** 最上层的UI */
|
|
35
|
+
public topUI(layer: LayerType) { return this.getTopView(layer) }
|
|
36
|
+
/**事件阻挡遮罩 */
|
|
37
|
+
public blockEvents: Node;
|
|
38
|
+
/**事件阻挡遮罩-用户输入事件时间(秒),小于0表示立即停止屏蔽触摸事件 */
|
|
39
|
+
public set blockEventsTime(value: number) {
|
|
40
|
+
this.blockEvents.active = true
|
|
41
|
+
this.launch.scheduleOnce(() => this.blockEvents.active = false, value);
|
|
42
|
+
}
|
|
25
43
|
|
|
26
44
|
/**加载转圈窗口 */
|
|
27
|
-
public loadingWindow: Node;
|
|
28
45
|
public LayerWindow: Node;
|
|
29
46
|
|
|
30
|
-
|
|
31
47
|
private ui_map: Map<string, Node> = new Map();
|
|
32
48
|
bundleName: string = "";
|
|
33
49
|
|
|
@@ -36,22 +52,22 @@ export class LayerUI {
|
|
|
36
52
|
window: { willOpen: (comp: IBundleConfig, param: any) => void, open: (comp: IBundleConfig) => void, willClose: (comp: IBundleConfig) => void, close: (comp: IBundleConfig) => void }
|
|
37
53
|
scene: ISceneParam
|
|
38
54
|
launch: BaseLaunchComponent;
|
|
55
|
+
scenesParm: ISceneParam = { param: undefined, bundleName: "", sceneName: "", };
|
|
39
56
|
|
|
40
57
|
async loadConfig(params: IInitConfig) {
|
|
58
|
+
//创建常驻节点
|
|
41
59
|
this.launch = await this.LoadLayerWindow(params);
|
|
42
60
|
const parent = this.launch.node
|
|
43
61
|
const data = await App.LoadAsset<JsonAsset>(params.bundleName, "config", JsonAsset)
|
|
44
62
|
this.config = data.json as IConfig;
|
|
45
63
|
App.ReleaseAssetPath('config', params.bundleName)
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
//创建UI层
|
|
48
65
|
const config = this.config;
|
|
49
66
|
config.gui.forEach(element => {
|
|
50
67
|
const node = LayerUI.CreateNnode(element.name);
|
|
51
68
|
node.parent = parent
|
|
52
69
|
this.ui_map.set(element.name, node);
|
|
53
70
|
});
|
|
54
|
-
this.initLog();
|
|
55
71
|
|
|
56
72
|
//事件阻挡层
|
|
57
73
|
[LayerType.LayerBlockEventsUI, LayerType.LayerBlockEventsNet].forEach(element => {
|
|
@@ -69,6 +85,8 @@ export class LayerUI {
|
|
|
69
85
|
Promise.all(list).then(() => {
|
|
70
86
|
this.launch.InitGame();
|
|
71
87
|
});
|
|
88
|
+
// 👇 设置 FPS(例如 60 帧)
|
|
89
|
+
game.frameRate = this.current_config.frameRate;
|
|
72
90
|
}
|
|
73
91
|
|
|
74
92
|
public static CreateNnode(name: string) {
|
|
@@ -94,27 +112,343 @@ export class LayerUI {
|
|
|
94
112
|
});
|
|
95
113
|
}
|
|
96
114
|
setBundleName(value: string) { this.bundleName = value; }
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// } else {
|
|
102
|
-
// console.log("发布模式");
|
|
103
|
-
// console.log = function () { }; // 关闭普通日志输出
|
|
104
|
-
// console.warn = function () { }; // 关闭警告输出
|
|
105
|
-
// // console.error = function () { }; // 关闭错误输出
|
|
106
|
-
// console.info = function () { }
|
|
107
|
-
// }
|
|
115
|
+
getTopView(layer: LayerType) {
|
|
116
|
+
const list = this.openWindowLayer.get(layer)
|
|
117
|
+
if (list && list.length > 0) { return this.openedWindows.get(list[list.length - 1]); }
|
|
118
|
+
else return null
|
|
108
119
|
}
|
|
109
120
|
|
|
121
|
+
/**获取指定ui层 */
|
|
122
|
+
public GetLayer(type: LayerType) { return this.ui_map.get(type); }
|
|
110
123
|
/**重置网络配置 */
|
|
111
|
-
ResetHttpServer(config: EnvironmentConfig) {
|
|
112
|
-
|
|
124
|
+
public ResetHttpServer(config: EnvironmentConfig) { Object.assign(this.current_config, config); }
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async OpenWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
129
|
+
return new Promise<T>(async (resolve, reject) => {
|
|
130
|
+
try {
|
|
131
|
+
const className = config.name ?? config.path.split('/').pop();
|
|
132
|
+
config.name = className;
|
|
133
|
+
if (this.IsWindowOpen(className)) {
|
|
134
|
+
const view = this.GetOpenWindow<Component>(config);
|
|
135
|
+
resolve(view as T);
|
|
136
|
+
//延迟100毫秒防止连点
|
|
137
|
+
setTimeout(() => { this.OpenBlockEvents(LayerType.LayerBlockEventsUI, false) }, 100);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
else if (this.IsWindowOpen(className)) {
|
|
141
|
+
Logger.warn("重复打开窗口-请检查", config.path)
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (!param) { param = {} }
|
|
145
|
+
this.window?.willOpen?.(config, param)
|
|
146
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsUI, true)
|
|
147
|
+
|
|
148
|
+
const view = await this.LoadWindow<T>(config, param);
|
|
149
|
+
|
|
150
|
+
this.GetLayer(config.layer).addChild(view.node);
|
|
151
|
+
|
|
152
|
+
// 添加关闭事件监听
|
|
153
|
+
this.setupCloseListener(view, className);
|
|
154
|
+
|
|
155
|
+
if (config.is_load_sub) {
|
|
156
|
+
(view as any).root.active = false;
|
|
157
|
+
await new Promise<void>((resolve, reject) => { (view as any).finish_sub = resolve; });
|
|
158
|
+
(view as any).root.active = true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
view.node.getComponent(Widget)?.updateAlignment();
|
|
162
|
+
|
|
163
|
+
//隐藏底层的UI
|
|
164
|
+
this.ShowLayerUI(config, false)
|
|
165
|
+
//收集打开的窗口
|
|
166
|
+
if (!this.openWindowLayer.has(config.layer)) {
|
|
167
|
+
this.openWindowLayer.set(config.layer, []);//LayerUI层
|
|
168
|
+
}
|
|
169
|
+
const list = this.openWindowLayer.get(config.layer)
|
|
170
|
+
list.push(className);
|
|
171
|
+
const layerUI_list = this.openWindowLayer.get(LayerType.LayerUI)
|
|
172
|
+
if (layerUI_list && layerUI_list.length > 0) this.GetLayer(LayerType.LayerGame).active = false;
|
|
173
|
+
if (App.GetDebug()) Logger.debug('LayerType.LayerUI 打开窗口记录:', className, list);
|
|
174
|
+
App.Emit(SystemMessage.OpenWindow, className)
|
|
175
|
+
this.window?.open?.(config)
|
|
176
|
+
|
|
177
|
+
resolve(view);
|
|
178
|
+
//延迟100毫秒防止连点
|
|
179
|
+
setTimeout(() => { this.OpenBlockEvents(LayerType.LayerBlockEventsUI, false) }, 100);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error("打开窗口失败:", error);
|
|
182
|
+
this.CloseLoading()
|
|
183
|
+
reject(error);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
113
186
|
}
|
|
114
187
|
|
|
188
|
+
async LoadWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
189
|
+
return new Promise<T>(async (resolve, reject) => {
|
|
190
|
+
try {
|
|
191
|
+
const className = config.name ?? config.path.split('/').pop();
|
|
192
|
+
//@ts-ignore
|
|
193
|
+
config.name = className;
|
|
194
|
+
// 记录打开的窗口--先占位
|
|
195
|
+
if (config.is_record === undefined || config.is_record) {//默认记录
|
|
196
|
+
this.openedWindows.set(className, null);
|
|
197
|
+
this.openedWindowsConfig.set(className, config);
|
|
198
|
+
}
|
|
199
|
+
//await Await(1000)
|
|
200
|
+
const prefab = await ResourceManager.loadAsset<Prefab>(config.bundle, config.path)
|
|
201
|
+
const node = instantiate(prefab);
|
|
202
|
+
|
|
203
|
+
const view = ((node.getComponent(className)) || (node.addComponent(className))) as T;
|
|
204
|
+
if (config.is_record === undefined || config.is_record) {//默认记录
|
|
205
|
+
this.openedWindows.set(className, view);
|
|
206
|
+
this.openedWindowsConfig.set(className, config);
|
|
207
|
+
}
|
|
208
|
+
//@ts-ignore
|
|
209
|
+
view.config = config;
|
|
210
|
+
//@ts-ignore
|
|
211
|
+
if (param) view.param = param;
|
|
115
212
|
|
|
213
|
+
resolve(view);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error("加载窗口失败:", config.path, error);
|
|
216
|
+
reject(error);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
116
220
|
|
|
221
|
+
async RootWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
222
|
+
await this.CloseAll([LayerType.LayerUI, LayerType.LayerDialog, LayerType.LayerPopUp])
|
|
223
|
+
return this.OpenWindow(config)
|
|
224
|
+
}
|
|
117
225
|
|
|
226
|
+
async CloseAll(layer_list: LayerType[]) {
|
|
227
|
+
const windows = this.GetOpenedWindowNames()
|
|
228
|
+
await new Promise<void>((resolve, reject) => {
|
|
229
|
+
//销毁已有的窗口
|
|
230
|
+
const destroyPromises: Promise<void>[] = []; // 用于存储每个销毁事件的 Promise
|
|
231
|
+
windows.forEach(className => {
|
|
232
|
+
const config = this.openedWindowsConfig.get(className);
|
|
233
|
+
if (layer_list.includes(config.layer)) {
|
|
234
|
+
const view = this.GetOpenWindow<any>(config);
|
|
235
|
+
// 创建一个 Promise 来等待 NODE_DESTROYED 事件完成
|
|
236
|
+
const destroyPromise = new Promise<void>((destroyResolve) => {
|
|
237
|
+
if (view.node && isValid(view.node, true)) {
|
|
238
|
+
view.node.once(Node.EventType.NODE_DESTROYED, () => {
|
|
239
|
+
destroyResolve(); // 当前节点销毁后 resolve
|
|
240
|
+
});
|
|
241
|
+
} else {
|
|
242
|
+
destroyResolve(); // 当前节点销毁后 resolve
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
destroyPromises.push(destroyPromise); // 将 Promise 添加到集合中
|
|
246
|
+
if (view && view.node && isValid(view.node, true)) {
|
|
247
|
+
/**关闭事件-当系统级关闭所有打开的界面时。如果关闭界面时需要执行自己的业务逻辑,使用此属性
|
|
248
|
+
* eventName:关闭方法名称
|
|
249
|
+
* param:参数
|
|
250
|
+
*/
|
|
251
|
+
const closeEvent: { eventName: string, param?: any } = view.closeEvent?.()
|
|
252
|
+
if (closeEvent) {
|
|
253
|
+
const close: Function = view[closeEvent.eventName]
|
|
254
|
+
if (close) { close.call(view, closeEvent.param) }
|
|
255
|
+
}
|
|
256
|
+
if (view && view.node && view.node.isValid) view.node.destroy(); // 关闭窗口
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
// 等待所有销毁事件完成后再 resolve 外层 Promise
|
|
261
|
+
Promise.all(destroyPromises).then(() => resolve());
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
OpenBlockEvents(type: LayerType, is_show: boolean) { this.GetLayer(type).active = is_show; }
|
|
265
|
+
async CloseLoading() {
|
|
266
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsUI, false)
|
|
267
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsNet, false)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
//#region 记录打开的窗口
|
|
272
|
+
// 关闭指定窗口
|
|
273
|
+
CloseWindow(className: string): boolean {
|
|
274
|
+
const instance = this
|
|
275
|
+
const window = instance.openedWindows.get(className);
|
|
276
|
+
if (window) {
|
|
277
|
+
try {
|
|
278
|
+
// 调用窗口的关闭方法(如果存在)
|
|
279
|
+
if (typeof (window as any).onClose === 'function') {
|
|
280
|
+
(window as any).onClose();
|
|
281
|
+
}
|
|
282
|
+
// 销毁节点
|
|
283
|
+
if (window.node && isValid(window.node, true)) {
|
|
284
|
+
window.node.destroy();
|
|
285
|
+
}
|
|
286
|
+
// 清除记录
|
|
287
|
+
instance.openedWindows.delete(className);
|
|
288
|
+
instance.openedWindowsConfig.delete(className);
|
|
289
|
+
return true;
|
|
290
|
+
} catch (error) {
|
|
291
|
+
console.error(`关闭窗口 ${className} 时出错:`, error);
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
} else {
|
|
295
|
+
Logger.warn(`窗口 ${className} 未找到或未打开`);
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 设置窗口关闭监听
|
|
301
|
+
private setupCloseListener(view: Component, className: string) {
|
|
302
|
+
const config = this.openedWindowsConfig.get(className);
|
|
303
|
+
const old_destroy = view.node.destroy
|
|
304
|
+
view.node.destroy = () => {
|
|
305
|
+
this.removeWindowRecord(className);
|
|
306
|
+
return old_destroy.call(view.node)
|
|
307
|
+
}
|
|
308
|
+
// 监听节点销毁事件
|
|
309
|
+
// view.node.once(Node.EventType.NODE_DESTROYED, () => {
|
|
310
|
+
// this.removeWindowRecord(className);
|
|
311
|
+
// });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
ShowLayerUI(config: IBundleConfig, is_show: boolean) {
|
|
315
|
+
if (config.layer === LayerType.LayerUI) {
|
|
316
|
+
const list_layer = this.openWindowLayer.get(config.layer)
|
|
317
|
+
if (list_layer && list_layer.length > 0) {
|
|
318
|
+
const last_name = list_layer[list_layer.length - 1];
|
|
319
|
+
const com = this.openedWindows.get(last_name);
|
|
320
|
+
if (com && com.isValid) {
|
|
321
|
+
com.node.active = is_show;
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
this.GetLayer(LayerType.LayerGame).active = true;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// 移除窗口记录
|
|
329
|
+
private removeWindowRecord(className: string) {
|
|
330
|
+
const config = this.openedWindowsConfig.get(className);
|
|
331
|
+
const list_layer = this.openWindowLayer.get(config.layer)
|
|
332
|
+
list_layer.pop();//移除最后一个
|
|
333
|
+
if (config.layer === LayerType.LayerUI) {
|
|
334
|
+
this.ShowLayerUI(config, true)
|
|
335
|
+
}
|
|
336
|
+
if (App.GetDebug()) Logger.debug('LayerType.LayerUI 移除窗口记录:', className, list_layer);
|
|
337
|
+
this.openedWindows.delete(className);
|
|
338
|
+
this.openedWindowsConfig.delete(className);
|
|
339
|
+
App.Emit(SystemMessage.CloseWindow, className)
|
|
340
|
+
this.window?.close?.(config)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// 通过配置关闭窗口
|
|
344
|
+
CloseWindowTarget(config: IBundleConfig): boolean { return this.CloseWindow(config.name ?? config.path.split('/').pop()!); }
|
|
345
|
+
|
|
346
|
+
// 关闭所有窗口
|
|
347
|
+
CloseAllWindows(): number {
|
|
348
|
+
const instance = this;
|
|
349
|
+
let closedCount = 0;
|
|
350
|
+
// 创建副本以避免在迭代时修改Map
|
|
351
|
+
const windowsToClose = new Array(...this.openedWindows.entries());
|
|
352
|
+
for (const [className, window] of windowsToClose) {
|
|
353
|
+
if (this.CloseWindow(className)) {
|
|
354
|
+
closedCount++;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (App.GetDebug()) Logger.debug(`共关闭 ${closedCount} 个窗口`);
|
|
358
|
+
return closedCount;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// 检查窗口是否已打开
|
|
362
|
+
IsWindowOpen(className: string): boolean { return this.openedWindows.has(className); }
|
|
363
|
+
// 获取已打开的窗口实例
|
|
364
|
+
GetOpenWindow<T extends Component>(config: IBundleConfig): T {
|
|
365
|
+
const className = config.name ?? config.path.split('/').pop();
|
|
366
|
+
const window = this.openedWindows.get(className);
|
|
367
|
+
return window ? window as T : null;
|
|
368
|
+
}
|
|
369
|
+
// 获取已打开的窗口实例
|
|
370
|
+
GetOpenWindows<T extends Component>(): T[] { return Array.from(this.openedWindows.values()) as T[]; }
|
|
371
|
+
// 获取已打开的窗口实例
|
|
372
|
+
GetOpenWindowsConfig(): IBundleConfig[] { return Array.from(this.openedWindowsConfig.values()); }
|
|
373
|
+
// 获取所有已打开的窗口名称
|
|
374
|
+
GetOpenedWindowNames(): string[] { return Array.from(this.openedWindows.keys()); }
|
|
375
|
+
OpenLoading(is_show: boolean) {
|
|
376
|
+
if (is_show) this.loading_call.open?.(() => { })
|
|
377
|
+
else this.loading_call.close?.()
|
|
378
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsUI, is_show)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**播放skpine动画 */
|
|
382
|
+
PlaySpine(skeleton: sp.Skeleton, animations: { name: string, loop?: boolean, call?: (name?: string) => void, event?: (name?: string) => void }[]) { SkeletonAnim.Play(skeleton, animations); }
|
|
383
|
+
|
|
384
|
+
LoadSprite(sp: Sprite, params: { path: string, bundle?: string, callback?: () => void }) {
|
|
385
|
+
const path = params.path + '/spriteFrame'
|
|
386
|
+
const bundleName = params ? (params.bundle ?? 'game') : "game"
|
|
387
|
+
const sprite = App.GetAsset<SpriteFrame>(bundleName, path, SpriteFrame)
|
|
388
|
+
if (sprite) {
|
|
389
|
+
if (isValid(sp, true)) {
|
|
390
|
+
sp.spriteFrame = sprite;
|
|
391
|
+
params?.callback?.()
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
if (App.GetDebug()) Logger.debug("图片已销毁")
|
|
395
|
+
}
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
App.LoadAsset(bundleName, path, SpriteFrame).then((spriteFrame) => {
|
|
399
|
+
if (sp) {
|
|
400
|
+
if (isValid(sp, true)) {
|
|
401
|
+
sp.spriteFrame = spriteFrame;
|
|
402
|
+
params?.callback?.()
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
if (App.GetDebug()) Logger.debug("图片已销毁")
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
})
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
LoadSpine(spine: sp.Skeleton, params: { path: string, bundle?: string, callback?: () => void }) {
|
|
413
|
+
const path = params.path
|
|
414
|
+
const bundleName = params ? (params.bundle ?? 'game') : "game"
|
|
415
|
+
const skeletonData = App.GetAsset<sp.SkeletonData>(bundleName, path, sp.SkeletonData)
|
|
416
|
+
if (skeletonData) {
|
|
417
|
+
if (spine) {
|
|
418
|
+
if (isValid(spine, true)) {
|
|
419
|
+
spine.skeletonData = skeletonData;
|
|
420
|
+
params?.callback?.()
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
App.LoadAsset(bundleName, path, sp.SkeletonData).then((skeletonData) => {
|
|
426
|
+
if (spine) {
|
|
427
|
+
if (isValid(spine, true)) {
|
|
428
|
+
spine.skeletonData = skeletonData;
|
|
429
|
+
params?.callback?.()
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
if (App.GetDebug()) Logger.debug("动画已销毁")
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
})
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async OpenScene(param: ISceneParam) {
|
|
439
|
+
this.scenesParm = param;
|
|
440
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsUI, true)
|
|
441
|
+
await new Promise<void>(resolve => { this.progess?.open?.(param, () => { resolve() }) })
|
|
442
|
+
//关闭所有窗口
|
|
443
|
+
await this.CloseAll([LayerType.LayerUI, LayerType.LayerDialog, LayerType.LayerPopUp, LayerType.LayerGame])
|
|
444
|
+
let scene = await ResourceManager.loadScene(param.bundleName, param.sceneName, (pro) => { });
|
|
445
|
+
if (scene) {
|
|
446
|
+
ResourceManager.runScene(scene);
|
|
447
|
+
} else {
|
|
448
|
+
param.error?.("加载场景失败");
|
|
449
|
+
}
|
|
450
|
+
this.OpenBlockEvents(LayerType.LayerBlockEventsUI, false)
|
|
451
|
+
}
|
|
118
452
|
}
|
|
119
453
|
|
|
120
454
|
|
|
@@ -267,7 +267,7 @@ export class EffectSingleCase {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
|
|
270
|
+
/**获取节点-同步 */
|
|
271
271
|
getNode(params: IPoolParams): Node {
|
|
272
272
|
const name = params.path.split(':').pop();
|
|
273
273
|
var np = this.effects.get(name);
|
|
@@ -276,6 +276,19 @@ export class EffectSingleCase {
|
|
|
276
276
|
return node
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
/**获取节点-异步 */
|
|
280
|
+
async loadNode(params: IPoolParams): Promise<Node> {
|
|
281
|
+
let node = this.getNode(params)
|
|
282
|
+
if (!node || (node && !node.isValid)) {
|
|
283
|
+
if ((node && !node.isValid)) {
|
|
284
|
+
Logger.debug('节点已销毁,请检测业务逻辑。节点没有进行回收就销毁了界面', params.path)
|
|
285
|
+
}
|
|
286
|
+
node = await App.pool.load(params)
|
|
287
|
+
}
|
|
288
|
+
this.updateNode(node, params)
|
|
289
|
+
return node
|
|
290
|
+
}
|
|
291
|
+
|
|
279
292
|
/** 加载节点对象 */
|
|
280
293
|
load(params: IPoolParams): Promise<Node> {
|
|
281
294
|
return new Promise(async (resolve, reject) => {
|
|
@@ -32,7 +32,7 @@ export class App {
|
|
|
32
32
|
/**存储层 */
|
|
33
33
|
static get storage(): StorageManager { return this.instance._storage };
|
|
34
34
|
/**场景参数 */
|
|
35
|
-
static get scenesParm(): ISceneParam { return this.instance.
|
|
35
|
+
static get scenesParm(): ISceneParam { return this.instance._gui.scenesParm };
|
|
36
36
|
/**时间管理 */
|
|
37
37
|
static get time(): TimeManager { return this.instance._timeManager };
|
|
38
38
|
/**多语言模块 */
|
|
@@ -69,9 +69,7 @@ export class App {
|
|
|
69
69
|
|
|
70
70
|
time: number = 0
|
|
71
71
|
isDebug = false;
|
|
72
|
-
|
|
73
|
-
private openedWindowsConfig: Map<string, IBundleConfig> = new Map();
|
|
74
|
-
private openWindowLayer: Map<string, string[]> = new Map();
|
|
72
|
+
|
|
75
73
|
|
|
76
74
|
static async InitGameConfig(param: IInitConfig) {
|
|
77
75
|
if (!EDITOR) { if (App.Ins._gui) { return } }
|
|
@@ -105,12 +103,6 @@ export class App {
|
|
|
105
103
|
console.log("初始化完成")
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
static OpenLoading(is_show: boolean) {
|
|
109
|
-
if (is_show) App.gui.loading_call.open?.(() => { })
|
|
110
|
-
else App.gui.loading_call.close?.()
|
|
111
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsUI, is_show)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
106
|
/**
|
|
115
107
|
* 加载资源并自动记录
|
|
116
108
|
* @param bundleName Bundle 名称
|
|
@@ -139,395 +131,39 @@ export class App {
|
|
|
139
131
|
static OnLoading(param: { open: (finish: () => void) => void, close: () => void }) { App.gui.loading_call = param; }
|
|
140
132
|
static OnProgess(param: { open: (param: ISceneParam, finish: () => void) => void, close: (param: ISceneParam) => void, progess: (param: ISceneParam, progress: number, time?: number) => void }) { App.gui.progess = param; }
|
|
141
133
|
static OnWindow(param: { willOpen: (comp: IBundleConfig) => void, open: (comp: IBundleConfig) => void, willClose: (comp: IBundleConfig) => void, close: (comp: IBundleConfig) => void }) { App.gui.window = param; }
|
|
142
|
-
static async Requst<T>(config: IHttpConfig, params?: any, ext?: IExtData): Promise<{ code: number, data: T, msg: string }> {
|
|
143
|
-
return new Promise<{ code: number, data: T, msg: string }>(async (originalResolve, originalReject) => {
|
|
144
|
-
let retries = 0; // 当前重试次数
|
|
145
|
-
const maxRetries = 5; // 最大重试次数
|
|
146
|
-
// 内部辅助函数,用于执行请求逻辑
|
|
147
|
-
const attemptRequest = async () => {
|
|
148
|
-
try {
|
|
149
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsNet, true);
|
|
150
|
-
|
|
151
|
-
const url = App.gui.current_config.httpServer + config.url
|
|
152
|
-
if (App.GetDebug()) Logger.debug(`${config.type === HttpType.GET ? "GET请求" : "POST请求"} url:${url} `, `\n 参数:`, params);
|
|
153
|
-
let ret: HttpReturn<any>;
|
|
154
|
-
if (config.type === HttpType.GET) {
|
|
155
|
-
ret = await App.http.getJson(config.url, params);
|
|
156
|
-
} else if (config.type === HttpType.POST) {
|
|
157
|
-
ret = await App.http.postJson(config.url, params, ext);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (App.GetDebug()) Logger.debug(`${config.type === HttpType.GET ? "GET请求" : "POST请求"} 结果 url:${url}\n`, ` 参数:`, params);
|
|
161
|
-
if (App.GetDebug()) Logger.debug(`返回结果:`, ret.res);
|
|
162
|
-
//Logger.warn(`返回结果:${JSON.stringify(ret.res)}`);
|
|
163
|
-
|
|
164
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsNet, false);
|
|
165
|
-
if (ret.isSucc) {
|
|
166
|
-
originalResolve(ret.res); // 请求成功,调用原始 resolve
|
|
167
|
-
} else {
|
|
168
|
-
throw new Error(ret.err); // 请求失败,抛出错误以触发重试逻辑
|
|
169
|
-
}
|
|
170
|
-
} catch (error) {
|
|
171
|
-
console.error(`请求失败: ${error.message}`);
|
|
172
|
-
retries++;
|
|
173
|
-
|
|
174
|
-
if (retries > maxRetries) {
|
|
175
|
-
console.error("达到最大重试次数,请求失败");
|
|
176
|
-
originalReject(error); // 达到最大重试次数后调用原始 reject
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (ext && ext.is_show_alert || (ext === undefined || ext.is_show_alert === undefined)) {
|
|
181
|
-
|
|
182
|
-
const userChoice = await new Promise<boolean>((resolve) => {
|
|
183
|
-
const finish = (isOk: boolean) => { resolve(isOk) }
|
|
184
|
-
App.http.param?.open?.(finish)
|
|
185
|
-
//param.callBack = (isOk: boolean) => resolve(isOk);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
if (!userChoice) {
|
|
189
|
-
if (App.GetDebug()) Logger.debug("用户取消请求");
|
|
190
|
-
originalReject("取消了"); // 用户取消,调用原始 reject
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsNet, true);
|
|
195
|
-
// 继续重试,但避免直接递归调用
|
|
196
|
-
setTimeout(attemptRequest, 100); // 使用 setTimeout 避免栈溢出
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
// 开始第一次请求
|
|
200
|
-
attemptRequest();
|
|
201
|
-
});
|
|
202
|
-
}
|
|
134
|
+
static async Requst<T>(config: IHttpConfig, params?: any, ext?: IExtData): Promise<{ code: number, data: T, msg: string }> { return App.http.Requst<T>(config, params, ext); }
|
|
203
135
|
/**重置网络配置 */
|
|
204
136
|
static ResetHttpServer(config: EnvironmentConfig) { App.instance._gui.ResetHttpServer(config); }
|
|
205
137
|
|
|
206
|
-
|
|
207
|
-
static async OpenWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
208
|
-
return new Promise<T>(async (resolve, reject) => {
|
|
209
|
-
try {
|
|
210
|
-
const className = config.name ?? config.path.split('/').pop();
|
|
211
|
-
config.name = className;
|
|
212
|
-
if (App.IsWindowOpen(className)) {
|
|
213
|
-
const view = App.GetOpenWindow<Component>(config);
|
|
214
|
-
resolve(view as T);
|
|
215
|
-
//延迟100毫秒防止连点
|
|
216
|
-
setTimeout(() => { App.OpenBlockEvents(LayerType.LayerBlockEventsUI, false) }, 100);
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
else if (App.IsWindowOpen(className)) {
|
|
220
|
-
Logger.warn("重复打开窗口-请检查", config.path)
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
if (!param) { param = {} }
|
|
224
|
-
App.gui.window?.willOpen?.(config, param)
|
|
225
|
-
//console.error('打开:', Array.from(App.Instance.openedWindows.keys()), config.path);
|
|
226
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsUI, true)
|
|
227
|
-
|
|
228
|
-
const view = await App.LoadWindow<T>(config, param);
|
|
229
|
-
|
|
230
|
-
App.gui.GetLayer(config.layer).addChild(view.node);
|
|
231
|
-
|
|
232
|
-
// 添加关闭事件监听
|
|
233
|
-
App.Ins.setupCloseListener(view, className);
|
|
234
|
-
|
|
235
|
-
if (config.is_load_sub) {
|
|
236
|
-
(view as any).root.active = false;
|
|
237
|
-
await new Promise<void>((resolve, reject) => { (view as any).finish_sub = resolve; });
|
|
238
|
-
(view as any).root.active = true;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
view.node.getComponent(Widget)?.updateAlignment();
|
|
242
|
-
|
|
243
|
-
//隐藏底层的UI
|
|
244
|
-
App.instance.ShowLayerUI(config, false)
|
|
245
|
-
//收集打开的窗口
|
|
246
|
-
if (!App.Ins.openWindowLayer.has(config.layer)) {
|
|
247
|
-
App.Ins.openWindowLayer.set(config.layer, []);//LayerUI层
|
|
248
|
-
}
|
|
249
|
-
const list = App.Ins.openWindowLayer.get(config.layer)
|
|
250
|
-
list.push(className);
|
|
251
|
-
const layerUI_list = App.Ins.openWindowLayer.get(LayerType.LayerUI)
|
|
252
|
-
if (layerUI_list && layerUI_list.length > 0) App.gui.GetLayer(LayerType.LayerGame).active = false;
|
|
253
|
-
if (App.GetDebug()) Logger.debug('LayerType.LayerUI 打开窗口记录:', className, list);
|
|
254
|
-
App.Emit(SystemMessage.OpenWindow, className)
|
|
255
|
-
App.gui.window?.open?.(config)
|
|
256
|
-
|
|
257
|
-
resolve(view);
|
|
258
|
-
//延迟100毫秒防止连点
|
|
259
|
-
setTimeout(() => { App.OpenBlockEvents(LayerType.LayerBlockEventsUI, false) }, 100);
|
|
260
|
-
} catch (error) {
|
|
261
|
-
console.error("打开窗口失败:", error);
|
|
262
|
-
App.CloseLoading()
|
|
263
|
-
reject(error);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
static async LoadWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
269
|
-
return new Promise<T>(async (resolve, reject) => {
|
|
270
|
-
try {
|
|
271
|
-
const className = config.name ?? config.path.split('/').pop();
|
|
272
|
-
//@ts-ignore
|
|
273
|
-
config.name = className;
|
|
274
|
-
// 记录打开的窗口--先占位
|
|
275
|
-
if (config.is_record === undefined || config.is_record) {//默认记录
|
|
276
|
-
App.Ins.openedWindows.set(className, null);
|
|
277
|
-
App.Ins.openedWindowsConfig.set(className, config);
|
|
278
|
-
}
|
|
279
|
-
//await Await(1000)
|
|
280
|
-
const prefab = await ResourceManager.loadAsset<Prefab>(config.bundle, config.path)
|
|
281
|
-
const node = instantiate(prefab);
|
|
282
|
-
|
|
283
|
-
const view = ((node.getComponent(className)) || (node.addComponent(className))) as T;
|
|
284
|
-
if (config.is_record === undefined || config.is_record) {//默认记录
|
|
285
|
-
App.Ins.openedWindows.set(className, view);
|
|
286
|
-
App.Ins.openedWindowsConfig.set(className, config);
|
|
287
|
-
}
|
|
288
|
-
//@ts-ignore
|
|
289
|
-
view.config = config;
|
|
290
|
-
//@ts-ignore
|
|
291
|
-
if (param) view.param = param;
|
|
292
|
-
|
|
293
|
-
resolve(view);
|
|
294
|
-
} catch (error) {
|
|
295
|
-
console.error("加载窗口失败:", config.path, error);
|
|
296
|
-
reject(error);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
static async RootWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> {
|
|
302
|
-
await App.CloseAll([LayerType.LayerUI, LayerType.LayerDialog, LayerType.LayerPopUp])
|
|
303
|
-
return App.OpenWindow(config)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
static async CloseAll(layer_list: LayerType[]) {
|
|
307
|
-
const windows = App.GetOpenedWindowNames()
|
|
308
|
-
await new Promise<void>((resolve, reject) => {
|
|
309
|
-
//销毁已有的窗口
|
|
310
|
-
const destroyPromises: Promise<void>[] = []; // 用于存储每个销毁事件的 Promise
|
|
311
|
-
windows.forEach(className => {
|
|
312
|
-
const config = App.Ins.openedWindowsConfig.get(className);
|
|
313
|
-
if (layer_list.includes(config.layer)) {
|
|
314
|
-
const view = App.GetOpenWindow<any>(config);
|
|
315
|
-
// 创建一个 Promise 来等待 NODE_DESTROYED 事件完成
|
|
316
|
-
const destroyPromise = new Promise<void>((destroyResolve) => {
|
|
317
|
-
if (view.node && isValid(view.node, true)) {
|
|
318
|
-
view.node.once(Node.EventType.NODE_DESTROYED, () => {
|
|
319
|
-
destroyResolve(); // 当前节点销毁后 resolve
|
|
320
|
-
});
|
|
321
|
-
} else {
|
|
322
|
-
destroyResolve(); // 当前节点销毁后 resolve
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
destroyPromises.push(destroyPromise); // 将 Promise 添加到集合中
|
|
326
|
-
if (view && view.node && isValid(view.node, true)) {
|
|
327
|
-
/**关闭事件-当系统级关闭所有打开的界面时。如果关闭界面时需要执行自己的业务逻辑,使用此属性
|
|
328
|
-
* eventName:关闭方法名称
|
|
329
|
-
* param:参数
|
|
330
|
-
*/
|
|
331
|
-
const closeEvent: { eventName: string, param?: any } = view.closeEvent?.()
|
|
332
|
-
if (closeEvent) {
|
|
333
|
-
const close: Function = view[closeEvent.eventName]
|
|
334
|
-
if (close) { close.call(view, closeEvent.param) }
|
|
335
|
-
}
|
|
336
|
-
if (view && view.node && view.node.isValid) view.node.destroy(); // 关闭窗口
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
})
|
|
340
|
-
// 等待所有销毁事件完成后再 resolve 外层 Promise
|
|
341
|
-
Promise.all(destroyPromises).then(() => resolve());
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
static OpenBlockEvents(type: LayerType, is_show: boolean) { App.gui.GetLayer(type).active = is_show; }
|
|
345
|
-
static async CloseLoading() {
|
|
346
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsUI, false)
|
|
347
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsNet, false)
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
static async OpenScene(param: ISceneParam) {
|
|
351
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsUI, true)
|
|
352
|
-
await new Promise<void>(resolve => { App.gui.progess?.open?.(param, () => { resolve() }) })
|
|
353
|
-
//关闭所有窗口
|
|
354
|
-
await App.CloseAll([LayerType.LayerUI, LayerType.LayerDialog, LayerType.LayerPopUp, LayerType.LayerGame])
|
|
355
|
-
App.Ins._scenesParm = param
|
|
356
|
-
let scene = await ResourceManager.loadScene(param.bundleName, param.sceneName, (pro) => { });
|
|
357
|
-
if (scene) {
|
|
358
|
-
ResourceManager.runScene(scene);
|
|
359
|
-
} else {
|
|
360
|
-
param.error?.("加载场景失败");
|
|
361
|
-
}
|
|
362
|
-
App.OpenBlockEvents(LayerType.LayerBlockEventsUI, false)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
//#region 记录打开的窗口
|
|
366
|
-
// 关闭指定窗口
|
|
367
|
-
static CloseWindow(className: string): boolean {
|
|
368
|
-
const instance = App.Ins;
|
|
369
|
-
const window = instance.openedWindows.get(className);
|
|
370
|
-
if (window) {
|
|
371
|
-
try {
|
|
372
|
-
// 调用窗口的关闭方法(如果存在)
|
|
373
|
-
if (typeof (window as any).onClose === 'function') {
|
|
374
|
-
(window as any).onClose();
|
|
375
|
-
}
|
|
376
|
-
// 销毁节点
|
|
377
|
-
if (window.node && isValid(window.node, true)) {
|
|
378
|
-
window.node.destroy();
|
|
379
|
-
}
|
|
380
|
-
// 清除记录
|
|
381
|
-
instance.openedWindows.delete(className);
|
|
382
|
-
instance.openedWindowsConfig.delete(className);
|
|
383
|
-
return true;
|
|
384
|
-
} catch (error) {
|
|
385
|
-
console.error(`关闭窗口 ${className} 时出错:`, error);
|
|
386
|
-
return false;
|
|
387
|
-
}
|
|
388
|
-
} else {
|
|
389
|
-
Logger.warn(`窗口 ${className} 未找到或未打开`);
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// 设置窗口关闭监听
|
|
395
|
-
private setupCloseListener(view: Component, className: string) {
|
|
396
|
-
const config = App.Ins.openedWindowsConfig.get(className);
|
|
397
|
-
const old_destroy = view.node.destroy
|
|
398
|
-
view.node.destroy = () => {
|
|
399
|
-
this.removeWindowRecord(className);
|
|
400
|
-
return old_destroy.call(view.node)
|
|
401
|
-
}
|
|
402
|
-
// 监听节点销毁事件
|
|
403
|
-
// view.node.once(Node.EventType.NODE_DESTROYED, () => {
|
|
404
|
-
// this.removeWindowRecord(className);
|
|
405
|
-
// });
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
ShowLayerUI(config: IBundleConfig, is_show: boolean) {
|
|
409
|
-
if (config.layer === LayerType.LayerUI) {
|
|
410
|
-
const list_layer = App.Ins.openWindowLayer.get(config.layer)
|
|
411
|
-
if (list_layer && list_layer.length > 0) {
|
|
412
|
-
const last_name = list_layer[list_layer.length - 1];
|
|
413
|
-
const com = this.openedWindows.get(last_name);
|
|
414
|
-
if (com && com.isValid) {
|
|
415
|
-
com.node.active = is_show;
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
App.gui.GetLayer(LayerType.LayerGame).active = true;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
// 移除窗口记录
|
|
423
|
-
private removeWindowRecord(className: string) {
|
|
424
|
-
const config = App.Ins.openedWindowsConfig.get(className);
|
|
425
|
-
const list_layer = App.Ins.openWindowLayer.get(config.layer)
|
|
426
|
-
list_layer.pop();//移除最后一个
|
|
427
|
-
if (config.layer === LayerType.LayerUI) {
|
|
428
|
-
this.ShowLayerUI(config, true)
|
|
429
|
-
}
|
|
430
|
-
if (App.GetDebug()) Logger.debug('LayerType.LayerUI 移除窗口记录:', className, list_layer);
|
|
431
|
-
this.openedWindows.delete(className);
|
|
432
|
-
this.openedWindowsConfig.delete(className);
|
|
433
|
-
App.Emit(SystemMessage.CloseWindow, className)
|
|
434
|
-
App.gui.window?.close?.(config)
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// 通过配置关闭窗口
|
|
438
|
-
static CloseWindowTarget(config: IBundleConfig): boolean { return App.CloseWindow(config.name ?? config.path.split('/').pop()!); }
|
|
439
|
-
|
|
440
|
-
// 关闭所有窗口
|
|
441
|
-
static CloseAllWindows(): number {
|
|
442
|
-
const instance = App.Ins;
|
|
443
|
-
let closedCount = 0;
|
|
444
|
-
// 创建副本以避免在迭代时修改Map
|
|
445
|
-
const windowsToClose = new Array(...instance.openedWindows.entries());
|
|
446
|
-
for (const [className, window] of windowsToClose) {
|
|
447
|
-
if (App.CloseWindow(className)) {
|
|
448
|
-
closedCount++;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
if (App.GetDebug()) Logger.debug(`共关闭 ${closedCount} 个窗口`);
|
|
452
|
-
return closedCount;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// 检查窗口是否已打开
|
|
456
|
-
static IsWindowOpen(className: string): boolean { return App.Ins.openedWindows.has(className); }
|
|
457
|
-
// 获取已打开的窗口实例
|
|
458
|
-
static GetOpenWindow<T extends Component>(config: IBundleConfig): T {
|
|
459
|
-
const className = config.name ?? config.path.split('/').pop();
|
|
460
|
-
const window = App.Ins.openedWindows.get(className);
|
|
461
|
-
return window ? window as T : null;
|
|
462
|
-
}
|
|
463
|
-
// 获取已打开的窗口实例
|
|
464
|
-
static GetOpenWindows<T extends Component>(): T[] { return Array.from(App.Ins.openedWindows.values()) as T[]; }
|
|
465
|
-
// 获取已打开的窗口实例
|
|
466
|
-
static GetOpenWindowsConfig(): IBundleConfig[] { return Array.from(App.Ins.openedWindowsConfig.values()); }
|
|
467
|
-
// 获取所有已打开的窗口名称
|
|
468
|
-
static GetOpenedWindowNames(): string[] { return Array.from(App.Ins.openedWindows.keys()); }
|
|
469
|
-
|
|
470
|
-
|
|
471
138
|
//#region 常用
|
|
472
139
|
static Debug(isDebug: boolean) { this.instance.isDebug = isDebug }
|
|
473
140
|
static GetDebug() { return this.instance.isDebug }
|
|
141
|
+
/**打开场景 */
|
|
142
|
+
static async OpenScene(param: ISceneParam) { await this.gui.OpenScene(param); }
|
|
474
143
|
/**播放skpine动画 */
|
|
475
144
|
static PlaySpine(skeleton: sp.Skeleton, animations: { name: string, loop?: boolean, call?: (name?: string) => void, event?: (name?: string) => void }[]) { SkeletonAnim.Play(skeleton, animations); }
|
|
476
|
-
|
|
477
|
-
static
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (App.GetDebug()) Logger.debug("图片已销毁")
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
})
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
static LoadSpine(spine: sp.Skeleton, params: { path: string, bundle?: string, callback?: () => void }) {
|
|
506
|
-
const path = params.path
|
|
507
|
-
const bundleName = params ? (params.bundle ?? 'game') : "game"
|
|
508
|
-
const skeletonData = App.GetAsset<sp.SkeletonData>(bundleName, path, sp.SkeletonData)
|
|
509
|
-
if (skeletonData) {
|
|
510
|
-
if (spine) {
|
|
511
|
-
if (isValid(spine, true)) {
|
|
512
|
-
spine.skeletonData = skeletonData;
|
|
513
|
-
params?.callback?.()
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
App.LoadAsset(bundleName, path, sp.SkeletonData).then((skeletonData) => {
|
|
519
|
-
if (spine) {
|
|
520
|
-
if (isValid(spine, true)) {
|
|
521
|
-
spine.skeletonData = skeletonData;
|
|
522
|
-
params?.callback?.()
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
if (App.GetDebug()) Logger.debug("动画已销毁")
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
})
|
|
529
|
-
}
|
|
530
|
-
|
|
145
|
+
static LoadSprite(sp: Sprite, params: { path: string, bundle?: string, callback?: () => void }) { App.gui.LoadSprite(sp, params) }
|
|
146
|
+
static LoadSpine(spine: sp.Skeleton, params: { path: string, bundle?: string, callback?: () => void }) { App.gui.LoadSpine(spine, params) }
|
|
147
|
+
/**打开遮罩 */
|
|
148
|
+
static OpenBlockEvents(type: LayerType, is_show: boolean) { App.gui.OpenBlockEvents(type, is_show) }
|
|
149
|
+
/**加载窗口 */
|
|
150
|
+
static LoadWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> { return App.gui.LoadWindow(config, param) }
|
|
151
|
+
/**打开窗口 */
|
|
152
|
+
static OpenWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> { return App.gui.OpenWindow(config, param) }
|
|
153
|
+
/**打开窗口--根窗口 备注移除层: LayerType.LayerUI, LayerType.LayerDialog, LayerType.LayerPopUp 里的窗口*/
|
|
154
|
+
static RootWindow<T extends Component>(config: IBundleConfig, param?: IWindowParam): Promise<T> { return App.gui.RootWindow(config, param) }
|
|
155
|
+
/**通过配置关闭窗口*/
|
|
156
|
+
static CloseWindowTarget(config: IBundleConfig): boolean { return App.gui.CloseWindowTarget(config) }
|
|
157
|
+
/**获取所有已打开的窗口名称 */
|
|
158
|
+
static GetOpenedWindowNames(): string[] { return App.gui.GetOpenedWindowNames() }
|
|
159
|
+
/**获取已打开的窗口实例*/
|
|
160
|
+
static GetOpenWindow<T extends Component>(config: IBundleConfig): T { return App.gui.GetOpenWindow(config) }
|
|
161
|
+
// 获取已打开的窗口实例-对象
|
|
162
|
+
static GetOpenWindows<T extends Component>(): T[] { return App.gui.GetOpenWindows<T>() }
|
|
163
|
+
// 获取已打开的窗口实例-配置
|
|
164
|
+
static GetOpenWindowsConfig(): IBundleConfig[] { return App.gui.GetOpenWindowsConfig() }
|
|
165
|
+
/** 显示加载转圈*/
|
|
166
|
+
static OpenLoading(is_show: boolean) { App.gui.OpenLoading(is_show) }
|
|
531
167
|
//#region 运行补丁
|
|
532
168
|
// 默认实现函数
|
|
533
169
|
static DefaultFunction(param?: any, callBack?: Function) {
|
|
@@ -552,6 +188,8 @@ s */
|
|
|
552
188
|
}
|
|
553
189
|
|
|
554
190
|
static PromiseQueue<T>(promises: Promise<T>[], onProgress: (completed: number, total: number) => void): Promise<T[]> { return App.Ins._tools.PromiseQueue(promises, onProgress) }
|
|
191
|
+
|
|
192
|
+
|
|
555
193
|
}
|
|
556
194
|
|
|
557
195
|
window.App = App;
|
|
@@ -114,10 +114,6 @@ declare global {
|
|
|
114
114
|
function CloseWindowTarget(config: { path: string; bundle: string }): boolean;
|
|
115
115
|
/**为 target 补全缺失的方法 */
|
|
116
116
|
function RegisterModule(target: any)
|
|
117
|
-
/**✅✅✅监听窗口的打开 */
|
|
118
|
-
//App.On(SystemMessage.OpenWindow)
|
|
119
|
-
/**✅✅✅监听窗口的关闭 */
|
|
120
|
-
//App.On(SystemMessage.CloseWindow)
|
|
121
117
|
/**获取所有已打开的窗口名称 */
|
|
122
118
|
function GetOpenedWindowNames(): string[]
|
|
123
119
|
/**获取已打开的窗口实例*/
|
|
@@ -132,8 +128,6 @@ declare global {
|
|
|
132
128
|
/**开启打印日志 */
|
|
133
129
|
function Debug(isDebug: boolean);
|
|
134
130
|
function GetDebug(): boolean;
|
|
135
|
-
|
|
136
|
-
|
|
137
131
|
/**=======================================✅✅常用工具======================= */
|
|
138
132
|
// function TwoBezier(param1, param2, param3, param4);
|
|
139
133
|
// function CustomEaseOutInWithSpeed(param)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @LastEditTime: 2022-09-09 18:10:50
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { IExtData } from "db://assets/cc-core";
|
|
8
|
+
import { HttpType, IExtData, IHttpConfig, LayerType } from "db://assets/cc-core";
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
/** HTTP请求返回值 */
|
|
@@ -304,4 +304,70 @@ export class HttpManager {
|
|
|
304
304
|
}
|
|
305
305
|
return result.substring(0, result.length - 1);
|
|
306
306
|
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
/**扩展请求 */
|
|
311
|
+
async Requst<T>(config: IHttpConfig, params?: any, ext?: IExtData): Promise<{ code: number, data: T, msg: string }> {
|
|
312
|
+
return new Promise<{ code: number, data: T, msg: string }>(async (originalResolve, originalReject) => {
|
|
313
|
+
let retries = 0; // 当前重试次数
|
|
314
|
+
const maxRetries = 5; // 最大重试次数
|
|
315
|
+
// 内部辅助函数,用于执行请求逻辑
|
|
316
|
+
const attemptRequest = async () => {
|
|
317
|
+
try {
|
|
318
|
+
App.gui.OpenBlockEvents(LayerType.LayerBlockEventsNet, true);
|
|
319
|
+
|
|
320
|
+
const url = App.gui.current_config.httpServer + config.url
|
|
321
|
+
if (App.GetDebug()) Logger.debug(`${config.type === HttpType.GET ? "GET请求" : "POST请求"} url:${url} `, `\n 参数:`, params);
|
|
322
|
+
let ret: HttpReturn<any>;
|
|
323
|
+
if (config.type === HttpType.GET) {
|
|
324
|
+
ret = await App.http.getJson(config.url, params);
|
|
325
|
+
} else if (config.type === HttpType.POST) {
|
|
326
|
+
ret = await App.http.postJson(config.url, params, ext);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (App.GetDebug()) Logger.debug(`${config.type === HttpType.GET ? "GET请求" : "POST请求"} 结果 url:${url}\n`, ` 参数:`, params);
|
|
330
|
+
if (App.GetDebug()) Logger.debug(`返回结果:`, ret.res);
|
|
331
|
+
//Logger.warn(`返回结果:${JSON.stringify(ret.res)}`);
|
|
332
|
+
|
|
333
|
+
App.gui.OpenBlockEvents(LayerType.LayerBlockEventsNet, false);
|
|
334
|
+
if (ret.isSucc) {
|
|
335
|
+
originalResolve(ret.res); // 请求成功,调用原始 resolve
|
|
336
|
+
} else {
|
|
337
|
+
throw new Error(ret.err); // 请求失败,抛出错误以触发重试逻辑
|
|
338
|
+
}
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error(`请求失败: ${error.message}`);
|
|
341
|
+
retries++;
|
|
342
|
+
|
|
343
|
+
if (retries > maxRetries) {
|
|
344
|
+
console.error("达到最大重试次数,请求失败");
|
|
345
|
+
originalReject(error); // 达到最大重试次数后调用原始 reject
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (ext && ext.is_show_alert || (ext === undefined || ext.is_show_alert === undefined)) {
|
|
350
|
+
|
|
351
|
+
const userChoice = await new Promise<boolean>((resolve) => {
|
|
352
|
+
const finish = (isOk: boolean) => { resolve(isOk) }
|
|
353
|
+
App.http.param?.open?.(finish)
|
|
354
|
+
//param.callBack = (isOk: boolean) => resolve(isOk);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
if (!userChoice) {
|
|
358
|
+
if (App.GetDebug()) Logger.debug("用户取消请求");
|
|
359
|
+
originalReject("取消了"); // 用户取消,调用原始 reject
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
App.gui.OpenBlockEvents(LayerType.LayerBlockEventsNet, true);
|
|
364
|
+
// 继续重试,但避免直接递归调用
|
|
365
|
+
setTimeout(attemptRequest, 100); // 使用 setTimeout 避免栈溢出
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
// 开始第一次请求
|
|
369
|
+
attemptRequest();
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
307
373
|
}
|