@ives_xxz/framework 2.1.40 → 2.3.0

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.
@@ -1,16 +1,23 @@
1
- import { FWSystemConfig } from '../config/FWSystemConfig';
2
- import { FWLodash } from '../utils/FWLodash';
3
- import { FWAssetManager } from './FWAssetManager';
4
- import { FWBundleManager } from './FWBundleManager';
5
- import { FWManager } from './FWManager';
1
+ import { injectable, inject } from 'inversify';
2
+ import { FW_TYPES } from '../define/FWTypes';
3
+ import { FWSystemConfig } from "../config/FWSystemConfig";
4
+ import { FWLodash } from "../utils/FWLodash";
5
+ import { FWAssetManager } from "./FWAssetManager";
6
+ import { FWBundleManager } from "./FWBundleManager";
7
+ import { FWManager } from "./FWManager";
6
8
 
9
+ @injectable()
7
10
  export class FWResManager extends FWManager implements FW.ResManager {
8
- private bundleMgr: FW.BundleManager;
9
- private assetMgr: FW.AssetManager;
10
11
  private rejectHandlerListener: FW.ResRejectHandlerListener;
12
+
13
+ constructor(
14
+ @inject(FW_TYPES.BundleManager) private bundleMgr: FW.BundleManager,
15
+ @inject(FW_TYPES.AssetManager) private assetMgr: FW.AssetManager,
16
+ ) {
17
+ super();
18
+ }
19
+
11
20
  public initialize() {
12
- this.bundleMgr = new FWBundleManager(this);
13
- this.assetMgr = new FWAssetManager(this);
14
21
  }
15
22
 
16
23
  registerRejectHandler(listener: FW.ResRejectHandlerListener): void {
@@ -42,27 +49,31 @@ export class FWResManager extends FWManager implements FW.ResManager {
42
49
  const keys = Object.keys(preLoad);
43
50
 
44
51
  if (keys.length > 0) {
45
- const find = (o) => {
46
- Object.keys(o).forEach(async (key) => {
47
- const value: FW.AssetProperty = o[key];
48
- const path: string = value.path;
49
- const type: string = value.type;
50
- const d: string = value.bundle || depend;
51
- const priorityLoaded = value.priorityLoaded || false;
52
- if (path) {
53
- if (priorityLoaded) {
52
+ const preloadRecursive = async (
53
+ obj: FW.LoadConfig | FW.AssetProperty,
54
+ ) => {
55
+ for (const key of Object.keys(obj)) {
56
+ const value: any = (obj as any)[key];
57
+
58
+ if (value && typeof value.path === "string") {
59
+ const path: string = value.path;
60
+ const type: string = value.type;
61
+ const d: string = value.bundle || depend;
62
+ const priorityLoaded = value.priorityLoaded || false;
63
+
64
+ if (path && priorityLoaded) {
54
65
  await this.assetMgr.load({
55
- path: path,
66
+ path,
56
67
  bundle: d,
57
- type: type,
68
+ type,
58
69
  });
59
70
  }
60
- } else {
61
- find(value);
71
+ } else if (value && typeof value === "object") {
72
+ await preloadRecursive(value);
62
73
  }
63
- });
74
+ }
64
75
  };
65
- find(config.preLoad);
76
+ await preloadRecursive(config.preLoad);
66
77
  }
67
78
  }
68
79
  }
@@ -92,7 +103,10 @@ export class FWResManager extends FWManager implements FW.ResManager {
92
103
  return await this.assetMgr.loadSpineDataFromRemote(data);
93
104
  }
94
105
 
95
- async loadRemote<T extends cc.Asset = cc.Asset>(url: string, texture?: boolean): Promise<T> {
106
+ async loadRemote<T extends cc.Asset = cc.Asset>(
107
+ url: string,
108
+ texture?: boolean,
109
+ ): Promise<T> {
96
110
  try {
97
111
  const asset = await this.assetMgr.loadRemote(url);
98
112
  if (texture) {
@@ -184,7 +198,10 @@ export class FWResManager extends FWManager implements FW.ResManager {
184
198
  * @param bundleName
185
199
  * @returns
186
200
  */
187
- getAssetData<T extends cc.Asset>(assetProperty: FW.AssetProperty, texture?: boolean) {
201
+ getAssetData<T extends cc.Asset>(
202
+ assetProperty: FW.AssetProperty,
203
+ texture?: boolean,
204
+ ) {
188
205
  const res = this.assetMgr.get(assetProperty);
189
206
  if (texture) {
190
207
  return res;
@@ -196,7 +213,10 @@ export class FWResManager extends FWManager implements FW.ResManager {
196
213
  * @param assetProperty
197
214
  * @returns
198
215
  */
199
- getAsset<T extends cc.Asset>(assetProperty: FW.AssetProperty, texture?: boolean): T {
216
+ getAsset<T extends cc.Asset>(
217
+ assetProperty: FW.AssetProperty,
218
+ texture?: boolean,
219
+ ): T {
200
220
  const res = this.assetMgr.get(assetProperty);
201
221
  if (texture) {
202
222
  return res.asset as T;
@@ -1,9 +1,11 @@
1
+ import { injectable } from 'inversify';
1
2
  import FWSocket from "../service/socket/FWSocket";
2
3
  import { FWManager } from "./FWManager";
3
4
 
4
5
  /**
5
6
  * socket管理器
6
7
  */
8
+ @injectable()
7
9
  export default class FWSocketManager
8
10
  extends FWManager
9
11
  implements FW.SocketManager
@@ -1,6 +1,8 @@
1
- import { FWManager } from './FWManager';
1
+ import { injectable } from 'inversify';
2
+ import { FWManager } from "./FWManager";
2
3
  import FWStateMachine from '../machine/FWStateMachine';
3
4
 
5
+ @injectable()
4
6
  export class FWStateManager extends FWManager implements FW.StateManager {
5
7
  private stateMap: Map<string, FWStateMachine>;
6
8
 
@@ -1,6 +1,8 @@
1
+ import { injectable } from 'inversify';
1
2
  import FWTask from '../utils/FWTask';
2
3
  import { FWManager } from './FWManager';
3
4
 
5
+ @injectable()
4
6
  export default class FWTaskManager extends FWManager implements FW.TaskManager {
5
7
  public initialize(): void {}
6
8
  public onDestroy(): void {
@@ -1,3 +1,4 @@
1
+ import { injectable } from 'inversify';
1
2
  import { FWManager } from './FWManager';
2
3
 
3
4
  class FWTimer implements FW.Timer {
@@ -21,6 +22,7 @@ class FWTimer implements FW.Timer {
21
22
  /**
22
23
  * 时间管理器
23
24
  */
25
+ @injectable()
24
26
  export class FWTimeManager extends FWManager implements FW.TimeManager {
25
27
  /**
26
28
  * 时间对象合集
@@ -1,6 +1,8 @@
1
- import { searchChild } from '../expand/FWDecorator';
2
- import { FWManager } from './FWManager';
1
+ import { injectable } from 'inversify';
2
+ import { searchChild } from "../expand/FWDecorator";
3
+ import { FWManager } from "./FWManager";
3
4
 
5
+ @injectable()
4
6
  export default class FWUiManager extends FWManager implements FW.UiManager {
5
7
  private eventMap: Map<
6
8
  number,
@@ -22,7 +24,11 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
22
24
  target.pauseSystemEvents(true);
23
25
  }
24
26
 
25
- this.eventMap.forEach((v) => FW.Entry.evtMgr?.targetPause(v));
27
+ this.eventMap.forEach((evt) => {
28
+ if (evt.target === target) {
29
+ FW.Entry.evtMgr?.targetPause(evt.target);
30
+ }
31
+ });
26
32
  }
27
33
 
28
34
  resumeEvent(target: FW.TargetType) {
@@ -32,7 +38,11 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
32
38
  target.resumeSystemEvents(true);
33
39
  }
34
40
 
35
- this.eventMap.forEach((v) => FW.Entry.evtMgr?.targetResume(v));
41
+ this.eventMap.forEach((evt) => {
42
+ if (evt.target === target) {
43
+ FW.Entry.evtMgr?.targetResume(evt.target);
44
+ }
45
+ });
36
46
  }
37
47
 
38
48
  unRegisterEvent(args: FW.RegisterArgs) {
@@ -112,7 +122,7 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
112
122
 
113
123
  register(args: FW.RegisterArgs) {
114
124
  if (!args.target) {
115
- FW.Log.error('注册事件失败,目标为空!');
125
+ FW.Log.error("注册事件失败,目标为空!");
116
126
  return;
117
127
  }
118
128
 
@@ -130,7 +140,10 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
130
140
 
131
141
  if (!evt.enable) return;
132
142
 
133
- if (Date.now() - evt.lastResponseTimestamp < evt.responseInterval) {
143
+ if (
144
+ Date.now() - evt.lastResponseTimestamp <
145
+ evt.responseInterval
146
+ ) {
134
147
  return;
135
148
  }
136
149
 
@@ -139,7 +152,10 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
139
152
 
140
153
  evt.lastResponseTimestamp = Date.now();
141
154
 
142
- FW.Entry.evtMgr.dispatch(FW.EventDefine.SystemEvent.SYSTEM_EVENT_TIRGGER, evt.target);
155
+ FW.Entry.evtMgr.dispatch(
156
+ FW.EventDefine.SystemEvent.SYSTEM_EVENT_TIRGGER,
157
+ evt.target,
158
+ );
143
159
 
144
160
  evt.cb?.bind(args.target)?.(e, c, evt.data);
145
161
  },
@@ -169,7 +185,10 @@ export default class FWUiManager extends FWManager implements FW.UiManager {
169
185
  args9?: FW.EventManagerArgs,
170
186
  args10?: FW.EventManagerArgs,
171
187
  ) => {
172
- if (Date.now() - evt.lastResponseTimestamp < (evt.responseInterval || 0)) {
188
+ if (
189
+ Date.now() - evt.lastResponseTimestamp <
190
+ (evt.responseInterval || 0)
191
+ ) {
173
192
  return;
174
193
  }
175
194
  evt.lastResponseTimestamp = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ives_xxz/framework",
3
- "version": "2.1.40",
3
+ "version": "2.3.0",
4
4
  "description": "cocoscreator 2.x mvc framework",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- import { FWSystemConfig } from '../../config/FWSystemConfig';
1
+ import { FWSystemConfig } from "../../config/FWSystemConfig";
2
2
 
3
3
  export class FWHttp extends FW.Service {
4
4
  public initialize() {}
@@ -11,7 +11,13 @@ export class FWHttp extends FW.Service {
11
11
  cb?: (response: string) => void,
12
12
  tag?: string,
13
13
  ): Promise<string> {
14
- return this.process(url, params, cb, tag, FW.SystemDefine.FWHttpRequestType.GET);
14
+ return this.process(
15
+ url,
16
+ params,
17
+ cb,
18
+ tag,
19
+ FW.SystemDefine.FWHttpRequestType.GET,
20
+ );
15
21
  }
16
22
 
17
23
  protected async postMessage(
@@ -20,7 +26,13 @@ export class FWHttp extends FW.Service {
20
26
  cb?: (response: string) => void,
21
27
  tag?: string,
22
28
  ): Promise<string> {
23
- return this.process(url, params, cb, tag, FW.SystemDefine.FWHttpRequestType.POST);
29
+ return this.process(
30
+ url,
31
+ params,
32
+ cb,
33
+ tag,
34
+ FW.SystemDefine.FWHttpRequestType.POST,
35
+ );
24
36
  }
25
37
 
26
38
  private async process(
@@ -32,44 +44,58 @@ export class FWHttp extends FW.Service {
32
44
  ): Promise<string> {
33
45
  let xhr: XMLHttpRequest;
34
46
 
35
- const promiseProxy: FW.PromiseProxy<string> = FW.Entry.promiseMgr.execute<string>(
36
- (resolve, reject, signal, reason) => {
37
- xhr = new XMLHttpRequest();
47
+ const promiseProxy: FW.PromiseProxy<string> =
48
+ FW.Entry.promiseMgr.execute<string>(
49
+ (resolve, reject, signal, reason) => {
50
+ xhr = new XMLHttpRequest();
51
+
52
+ xhr.onreadystatechange = () => {
53
+ if (xhr.readyState !== 4) return;
54
+
55
+ if (xhr.status >= 200 && xhr.status < 300) {
56
+ cb?.(xhr.response);
57
+ resolve(xhr.response);
58
+ return;
59
+ }
38
60
 
39
- xhr.onreadystatechange = () => {
40
- if (xhr.readyState == 4 && xhr.status === 200) {
41
- cb?.(xhr.response);
42
- resolve(xhr.response);
43
- }
44
- };
61
+ const errMsg = `http request failed, status: ${xhr.status}, url: ${url}`;
62
+ FW.Log.warn(errMsg);
63
+ reject(errMsg);
64
+ };
45
65
 
46
- xhr.onerror = (err: any) => {
47
- FW.Log.error(err);
48
- this.onError?.(err);
49
- reject(`http request error:${err}`);
50
- };
66
+ xhr.onerror = (err: any) => {
67
+ FW.Log.error("http request error:", err);
68
+ this.onError?.(err);
69
+ reject(`http request error:${err}`);
70
+ };
51
71
 
52
- xhr.ontimeout = () => {
53
- this.onTimeout?.();
54
- reject(`http request timeout!`);
55
- };
72
+ xhr.ontimeout = () => {
73
+ this.onTimeout?.();
74
+ reject(`http request timeout!`);
75
+ };
56
76
 
57
- xhr.open(type as string, url, true);
58
- xhr.send(params);
59
- },
60
- {
61
- ...FWSystemConfig.PromiseConfig.http,
62
- retryCondition(error, retryCount) {
63
- return error || xhr.readyState != 4 || (xhr.status !== 200 && retryCount < 3);
77
+ xhr.open(type as string, url, true);
78
+ xhr.send(params);
64
79
  },
65
- },
66
- );
80
+ {
81
+ ...FWSystemConfig.PromiseConfig.http,
82
+ retryCondition(error, retryCount) {
83
+ return (
84
+ !!error &&
85
+ retryCount < (FWSystemConfig.PromiseConfig.http.retryCount || 0)
86
+ );
87
+ },
88
+ },
89
+ );
67
90
 
68
91
  promiseProxy.addAbortEventListener(() => {
69
92
  xhr.abort();
70
93
  });
71
94
 
72
- return await this.invoke(promiseProxy.promise, tag ? `http request ->${tag}` : '');
95
+ return await this.invoke(
96
+ promiseProxy.promise,
97
+ tag ? `http request ->${tag}` : "",
98
+ );
73
99
  }
74
100
 
75
101
  onError?(err: any);
@@ -1,4 +1,4 @@
1
- import { FWSystemConfig } from '../../config/FWSystemConfig';
1
+ import { FWSystemConfig } from "../../config/FWSystemConfig";
2
2
 
3
3
  /**
4
4
  * TODO 犹豫socket没有改版暂时已老的cmd字符串映射方式做,后期优化
@@ -106,10 +106,14 @@ export default class FWSocket extends FW.Service implements FW.Socket {
106
106
  this.heartInternal = config?.heartInternal || defaultConfig.heartInternal;
107
107
  this.heartTimeout = config?.heartTimeout || defaultConfig.heartTimeout;
108
108
  this.heartWeakTime = config?.heartWeakTime || defaultConfig.heartWeakTime;
109
- this.maxReconnectTimes = config?.maxReconnectTimes || defaultConfig.maxReconnectTimes;
110
- this.reconnectInternal = config?.reconnectInternal || defaultConfig.reconnectInternal;
111
- this.protocolSymbol = config?.protocolSymbol || defaultConfig.protocolSymbol;
112
- this.protocolPollingTime = config?.protocolPollingTime || defaultConfig.protocolPollingTime;
109
+ this.maxReconnectTimes =
110
+ config?.maxReconnectTimes || defaultConfig.maxReconnectTimes;
111
+ this.reconnectInternal =
112
+ config?.reconnectInternal || defaultConfig.reconnectInternal;
113
+ this.protocolSymbol =
114
+ config?.protocolSymbol || defaultConfig.protocolSymbol;
115
+ this.protocolPollingTime =
116
+ config?.protocolPollingTime || defaultConfig.protocolPollingTime;
113
117
 
114
118
  this.promiseProxy = {
115
119
  promise: undefined,
@@ -123,7 +127,7 @@ export default class FWSocket extends FW.Service implements FW.Socket {
123
127
 
124
128
  return this.promiseProxy;
125
129
  } catch (e) {
126
- FW.Log.error('创建socket失败:', e);
130
+ FW.Log.error("创建socket失败:", e);
127
131
  }
128
132
  }
129
133
  /**
@@ -201,16 +205,22 @@ export default class FWSocket extends FW.Service implements FW.Socket {
201
205
  this.socket?.close();
202
206
  this.socket = null;
203
207
 
204
- this.createSocket(this.address, this.tag, this.socketSender, this.socketHandle, {
205
- heartInternal: this.heartInternal,
206
- heartTimeout: this.heartTimeout,
207
- heartWeakTime: this.heartWeakTime,
208
- maxReconnectTimes: this.maxReconnectTimes,
209
- reconnectInternal: this.reconnectInternal,
210
- protocolSymbol: this.protocolSymbol,
211
- protocolPollingTime: this.protocolPollingTime,
212
- certificate: this.certificate,
213
- });
208
+ this.createSocket(
209
+ this.address,
210
+ this.tag,
211
+ this.socketSender,
212
+ this.socketHandle,
213
+ {
214
+ heartInternal: this.heartInternal,
215
+ heartTimeout: this.heartTimeout,
216
+ heartWeakTime: this.heartWeakTime,
217
+ maxReconnectTimes: this.maxReconnectTimes,
218
+ reconnectInternal: this.reconnectInternal,
219
+ protocolSymbol: this.protocolSymbol,
220
+ protocolPollingTime: this.protocolPollingTime,
221
+ certificate: this.certificate,
222
+ },
223
+ );
214
224
  }
215
225
 
216
226
  async send(msg: string) {
@@ -220,14 +230,15 @@ export default class FWSocket extends FW.Service implements FW.Socket {
220
230
  const protocolKey = this.socketSender.getProtocolKey?.(msg);
221
231
  if (protocolKey) {
222
232
  const symbol = Symbol(protocolKey);
223
- const registry = this.protocolRegistry.get(protocolKey) || new Set<Symbol>();
233
+ const registry =
234
+ this.protocolRegistry.get(protocolKey) || new Set<Symbol>();
224
235
  const protocolPolling: FW.ProtocolPolling = {
225
236
  msg: msg,
226
237
  schedule: FW.Entry.timeMgr.schedule(
227
238
  () => {
228
239
  this.sendMessage(msg);
229
240
  },
230
- this.protocolPollingTime,
241
+ this.protocolPollingTime / 1000,
231
242
  cc.macro.REPEAT_FOREVER,
232
243
  this,
233
244
  ),
@@ -241,7 +252,7 @@ export default class FWSocket extends FW.Service implements FW.Socket {
241
252
 
242
253
  /** 连接打开 */
243
254
  private onSocketOpen() {
244
- FW.Log.debug('on open!');
255
+ FW.Log.debug("on open!");
245
256
  FW.Entry.timeMgr.unSchedule(this);
246
257
  this.reconnectTimes = 0;
247
258
  this.sendHeartTimestamp = 0;
@@ -285,16 +296,19 @@ export default class FWSocket extends FW.Service implements FW.Socket {
285
296
 
286
297
  /** socket关闭 */
287
298
  private onSocketClose() {
288
- FW.Log.debug('on close!');
299
+ FW.Log.debug("on close!");
289
300
  this.socketHandle?.onClose?.();
290
301
  FW.Entry.timeMgr.scheduleOnce(
291
302
  () => {
292
- if (this.getReadyState() == WebSocket.CLOSING || this.getReadyState() == WebSocket.CLOSED) {
293
- FW.Log.debug('on close!');
303
+ if (
304
+ this.getReadyState() == WebSocket.CLOSING ||
305
+ this.getReadyState() == WebSocket.CLOSED
306
+ ) {
307
+ FW.Log.debug("on close!");
294
308
  this.reconnect();
295
309
  }
296
310
  },
297
- this.reconnectInternal,
311
+ this.reconnectInternal / 1000,
298
312
  this,
299
313
  );
300
314
  }
@@ -0,0 +1,139 @@
1
+ export default class FWResLoader {
2
+ /**
3
+ * 通过任务系统按帧加载资源
4
+ */
5
+ public static threadLoad(options: {
6
+ assets: FW.AssetProperty[];
7
+ cb?: (progress: number) => void;
8
+ }): void {
9
+ const totalAssetsCount = options.assets.length;
10
+ let loadedAssetsCount = 0;
11
+
12
+ const task = FW.Entry.taskMgr.createTask({
13
+ frameBudget: 1 / 20,
14
+ tasksFrameCount: 5,
15
+ log: true,
16
+ });
17
+
18
+ const loadTask = async function* (): FW.TaskGenerator {
19
+ yield {
20
+ type: FW.EventDefine.TaskEvent.START,
21
+ progress: 0,
22
+ message: "资源加载开始",
23
+ };
24
+
25
+ for (const asset of options.assets) {
26
+ try {
27
+ await FW.Entry.resMgr.loadAsset({
28
+ bundle: asset.bundle,
29
+ path: asset.path,
30
+ type: asset.type,
31
+ });
32
+
33
+ loadedAssetsCount++;
34
+
35
+ const currentProgress = loadedAssetsCount / totalAssetsCount;
36
+
37
+ options.cb?.(currentProgress);
38
+
39
+ yield {
40
+ type: FW.EventDefine.TaskEvent.PROGRESS,
41
+ progress: currentProgress,
42
+ message: `资源加载中-> 资源路径:${asset.path} ,资源数:${loadedAssetsCount}/${totalAssetsCount},进度百分比:${currentProgress}`,
43
+ };
44
+ } catch (error) {
45
+ FW.Log.error(`加载资源失败: ${asset.path}`, error);
46
+ loadedAssetsCount++;
47
+ yield {
48
+ type: FW.EventDefine.TaskEvent.PROGRESS,
49
+ progress: loadedAssetsCount / totalAssetsCount,
50
+ message: `资源加载失败->: ${asset.path}`,
51
+ };
52
+ }
53
+ }
54
+
55
+ yield {
56
+ type: FW.EventDefine.TaskEvent.COMPLETE,
57
+ progress: 1,
58
+ message: "资源加载完成",
59
+ };
60
+ };
61
+
62
+ task.start(loadTask);
63
+ }
64
+
65
+ /**
66
+ * 加载bundle并收集预加载资源
67
+ */
68
+ public static async loadBundlesAndCollectAssets(
69
+ bundles: string[],
70
+ ): Promise<{
71
+ priorityAssets: FW.AssetProperty[];
72
+ backStageAssets: FW.AssetProperty[];
73
+ }> {
74
+ const priorityAssets: FW.AssetProperty[] = [];
75
+ const backStageAssets: FW.AssetProperty[] = [];
76
+
77
+ for (const bundleName of bundles) {
78
+ await FW.Entry.resMgr.loadBundle(bundleName);
79
+ const assetsConfig = FW.Entry.getComponent<FW.AssetConfig>(
80
+ `${bundleName}${FW.SystemDefine.FWBindTag.CONFIG}`,
81
+ );
82
+
83
+ if (!assetsConfig) continue;
84
+
85
+ const find = (o: any) => {
86
+ if (!o) return;
87
+ Object.keys(o).forEach((key) => {
88
+ const value: FW.AssetProperty | any = o[key];
89
+ const path: string = (value as any)?.path;
90
+ const priorityLoaded: boolean = (value as any)?.priorityLoaded;
91
+ if (path) {
92
+ (priorityLoaded ? priorityAssets : backStageAssets).push({
93
+ bundle: bundleName,
94
+ path,
95
+ });
96
+ } else if (typeof value === "object") {
97
+ find(value);
98
+ }
99
+ });
100
+ };
101
+
102
+ find((assetsConfig as any).preLoad);
103
+ }
104
+
105
+ return {
106
+ priorityAssets,
107
+ backStageAssets,
108
+ };
109
+ }
110
+
111
+ /**
112
+ * 通过线程任务加载资源并返回完成Promise
113
+ */
114
+ public static async loadAssetsWithThread(options: {
115
+ assets: FW.AssetProperty[];
116
+ cb?: (progress: number) => void;
117
+ }): Promise<void> {
118
+ const { assets, cb } = options;
119
+ if (!assets || assets.length === 0) {
120
+ cb?.(1);
121
+ return;
122
+ }
123
+
124
+ return new Promise<void>((resolve) => {
125
+ let loadedCount = 0;
126
+
127
+ FWResLoader.threadLoad({
128
+ assets,
129
+ cb: (progress: number) => {
130
+ cb?.(progress);
131
+ if (++loadedCount >= assets.length) {
132
+ resolve();
133
+ }
134
+ },
135
+ });
136
+ });
137
+ }
138
+ }
139
+
@@ -0,0 +1,10 @@
1
+ {
2
+ "ver": "1.1.0",
3
+ "uuid": "ca26ad6e-2aad-45c8-84b3-9a5052e47023",
4
+ "importer": "typescript",
5
+ "isPlugin": false,
6
+ "loadPluginInWeb": true,
7
+ "loadPluginInNative": true,
8
+ "loadPluginInEditor": false,
9
+ "subMetas": {}
10
+ }
package/utils/FWUtils.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { injectable } from 'inversify';
2
+
3
+ @injectable()
1
4
  export default class FWUtils {
2
5
  /**
3
6
  * 从 URL 中获取完整文件名(含扩展名)