@ives_xxz/framework 1.4.15 → 1.5.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.
- package/FW.d.ts +61 -44
- package/Framework.ts +95 -3
- package/FrameworkBase.ts +62 -0
- package/FrameworkBase.ts.meta +10 -0
- package/config/FWSystemConfig.ts +18 -0
- package/controller/FWLayerController.ts +3 -2
- package/data/FWData.ts +2 -5
- package/define/FWEventDefine.ts +4 -0
- package/define/FWSystemDefine.ts +5 -0
- package/entry/FWEntry.ts +9 -18
- package/logic/FWLogic.ts +4 -7
- package/manager/FWAssetManager.ts +62 -67
- package/manager/FWAudioManager.ts +230 -185
- package/manager/FWBundleManager.ts +6 -7
- package/manager/FWEngineManager.ts +8 -0
- package/manager/FWEventManager.ts +91 -2
- package/manager/FWLayerManager.ts +2 -2
- package/manager/FWManager.ts +4 -51
- package/manager/FWObjectManager.ts +100 -33
- package/manager/FWPerformanceManager.ts +32 -34
- package/manager/FWPromiseManager.ts +21 -24
- package/manager/FWResManager.ts +5 -5
- package/manager/FWTaskManager.ts +3 -1
- package/manager/FWTimeManager.ts +12 -40
- package/package.json +1 -1
- package/service/FWService.ts +6 -50
- package/service/http/FWHttp.ts +39 -34
- package/service/socket/FWSocket.ts +7 -11
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FWManager } from './FWManager';
|
|
2
2
|
import FWLog from '../log/FWLog';
|
|
3
3
|
import Framework from '../Framework';
|
|
4
|
+
import { FWSystemConfig } from '../config/FWSystemConfig';
|
|
4
5
|
|
|
5
6
|
export class FWBundleManager extends FWManager implements FW.BundleManager {
|
|
6
7
|
bundleMap: Map<string, cc.AssetManager.Bundle>;
|
|
@@ -31,11 +32,8 @@ export class FWBundleManager extends FWManager implements FW.BundleManager {
|
|
|
31
32
|
if (!bundleName) return;
|
|
32
33
|
if (this.bundleMap.has(bundleName)) return this.bundleMap.get(bundleName);
|
|
33
34
|
|
|
34
|
-
return
|
|
35
|
-
(
|
|
36
|
-
resolve: (value: cc.AssetManager.Bundle | PromiseLike<cc.AssetManager.Bundle>) => void,
|
|
37
|
-
reject: (reason?: any) => void,
|
|
38
|
-
) => {
|
|
35
|
+
return await this.invoke(
|
|
36
|
+
FW.Entry.promiseMgr.execute((resolve, reject, signal) => {
|
|
39
37
|
const remote = this.remoteBundleConfigMap.get(bundleName);
|
|
40
38
|
const url = remote ? remote.url : '';
|
|
41
39
|
const path = `${url}${bundleName}`;
|
|
@@ -54,7 +52,8 @@ export class FWBundleManager extends FWManager implements FW.BundleManager {
|
|
|
54
52
|
resolve(bundle);
|
|
55
53
|
},
|
|
56
54
|
);
|
|
57
|
-
},
|
|
55
|
+
}, FWSystemConfig.PromiseConfig.loadBundle).promise,
|
|
56
|
+
`loadBundle -> ${bundleName}`,
|
|
58
57
|
);
|
|
59
58
|
}
|
|
60
59
|
|
|
@@ -93,7 +92,7 @@ export class FWBundleManager extends FWManager implements FW.BundleManager {
|
|
|
93
92
|
|
|
94
93
|
public onDestroy(): void {
|
|
95
94
|
this.bundleMap.forEach((bundle) => {
|
|
96
|
-
|
|
95
|
+
cc.assetManager.removeBundle(bundle);
|
|
97
96
|
});
|
|
98
97
|
this.bundleMap.clear();
|
|
99
98
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { FWEventDefine } from '../define/FWEventDefine';
|
|
1
2
|
import { FWSystemDefine } from '../define/FWSystemDefine';
|
|
3
|
+
import Framework from '../Framework';
|
|
2
4
|
import FWLog from '../log/FWLog';
|
|
3
5
|
import { FWManager } from './FWManager';
|
|
4
6
|
|
|
@@ -14,6 +16,12 @@ export default class FWEngineManager extends FWManager implements FW.EngineManag
|
|
|
14
16
|
cc.game.off(cc.game.EVENT_HIDE, this.onAppHide, this);
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
restart() {
|
|
20
|
+
FW.Entry.evtMgr.dispatch(FWEventDefine.SystemEvent.SYSTEM_RESTART);
|
|
21
|
+
Framework.restart();
|
|
22
|
+
cc.game.restart();
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
getMemory() {
|
|
18
26
|
if (!this.debug) return;
|
|
19
27
|
if (window.performance && window.performance['memory']) {
|
|
@@ -18,6 +18,7 @@ class FWObserver implements FW.Observer {
|
|
|
18
18
|
private readonly target: FW.TargetType,
|
|
19
19
|
public readonly priority: number,
|
|
20
20
|
public readonly intercept: boolean,
|
|
21
|
+
public readonly once: boolean = false,
|
|
21
22
|
) {
|
|
22
23
|
this.cb = cb;
|
|
23
24
|
this.target = target;
|
|
@@ -55,6 +56,7 @@ class FWObserver implements FW.Observer {
|
|
|
55
56
|
args10,
|
|
56
57
|
);
|
|
57
58
|
}
|
|
59
|
+
|
|
58
60
|
/**
|
|
59
61
|
* 目标比较
|
|
60
62
|
* @param target 目标对象
|
|
@@ -115,14 +117,31 @@ export default class FWEventManager implements FW.EventManager {
|
|
|
115
117
|
) {
|
|
116
118
|
const observers = this.listeners[eventName];
|
|
117
119
|
if (!observers) return;
|
|
120
|
+
|
|
118
121
|
let shouldStopPropagation = false;
|
|
119
|
-
|
|
122
|
+
const observersToRemove: FW.Observer[] = [];
|
|
123
|
+
|
|
124
|
+
const observersCopy = [...observers];
|
|
125
|
+
|
|
126
|
+
for (const observer of observersCopy) {
|
|
120
127
|
if (shouldStopPropagation) break;
|
|
128
|
+
|
|
129
|
+
if (observers.indexOf(observer) === -1) continue;
|
|
130
|
+
|
|
121
131
|
observer.notify(args1, args2, args3, args4, args5, args6, args7, args8, args9, args10);
|
|
132
|
+
|
|
133
|
+
if (observer.once) {
|
|
134
|
+
observersToRemove.push(observer);
|
|
135
|
+
}
|
|
136
|
+
|
|
122
137
|
if (observer.intercept) {
|
|
123
138
|
shouldStopPropagation = true;
|
|
124
139
|
}
|
|
125
140
|
}
|
|
141
|
+
|
|
142
|
+
if (observersToRemove.length > 0) {
|
|
143
|
+
this.removeObservers(eventName, observersToRemove);
|
|
144
|
+
}
|
|
126
145
|
}
|
|
127
146
|
|
|
128
147
|
/**
|
|
@@ -149,20 +168,26 @@ export default class FWEventManager implements FW.EventManager {
|
|
|
149
168
|
options?: {
|
|
150
169
|
priority?: FWSystemDefine.FWPriorityOrder;
|
|
151
170
|
intercept?: boolean;
|
|
171
|
+
once?: boolean;
|
|
152
172
|
},
|
|
153
173
|
) {
|
|
154
174
|
const observers = this.listeners[eventName];
|
|
155
175
|
const define = FWSystemDefine.FWPriorityOrder;
|
|
156
176
|
const priority = options?.priority === undefined ? define.NORMAL : options.priority;
|
|
157
177
|
const intercept = options?.intercept === undefined ? false : options.intercept;
|
|
158
|
-
const
|
|
178
|
+
const once = options?.once === undefined ? false : options.once;
|
|
179
|
+
|
|
180
|
+
const observer = new FWObserver(eventName, cb, target, priority, intercept, once);
|
|
181
|
+
|
|
159
182
|
if (!observers) {
|
|
160
183
|
this.listeners[eventName] = [];
|
|
161
184
|
}
|
|
185
|
+
|
|
162
186
|
const order = Object.values(define);
|
|
163
187
|
const insertIndex = this.listeners[eventName].findIndex(
|
|
164
188
|
(o) => order[o.priority] > order[priority],
|
|
165
189
|
);
|
|
190
|
+
|
|
166
191
|
if (insertIndex === -1) {
|
|
167
192
|
this.listeners[eventName].push(observer);
|
|
168
193
|
} else {
|
|
@@ -170,6 +195,39 @@ export default class FWEventManager implements FW.EventManager {
|
|
|
170
195
|
}
|
|
171
196
|
}
|
|
172
197
|
|
|
198
|
+
/**
|
|
199
|
+
* 注册一次性事件
|
|
200
|
+
* @param eventName 事件名
|
|
201
|
+
* @param cb 回调函数
|
|
202
|
+
* @param target 事件回调绑定目标
|
|
203
|
+
* @param options 选项
|
|
204
|
+
*/
|
|
205
|
+
public registerOnce(
|
|
206
|
+
eventName: string | number,
|
|
207
|
+
cb: (
|
|
208
|
+
args1?: FW.EventManagerArgs,
|
|
209
|
+
args2?: FW.EventManagerArgs,
|
|
210
|
+
args3?: FW.EventManagerArgs,
|
|
211
|
+
args4?: FW.EventManagerArgs,
|
|
212
|
+
args5?: FW.EventManagerArgs,
|
|
213
|
+
args6?: FW.EventManagerArgs,
|
|
214
|
+
args7?: FW.EventManagerArgs,
|
|
215
|
+
args8?: FW.EventManagerArgs,
|
|
216
|
+
args9?: FW.EventManagerArgs,
|
|
217
|
+
args10?: FW.EventManagerArgs,
|
|
218
|
+
) => void,
|
|
219
|
+
target: FW.TargetType,
|
|
220
|
+
options?: {
|
|
221
|
+
priority?: FWSystemDefine.FWPriorityOrder;
|
|
222
|
+
intercept?: boolean;
|
|
223
|
+
},
|
|
224
|
+
) {
|
|
225
|
+
this.register(eventName, cb, target, {
|
|
226
|
+
...options,
|
|
227
|
+
once: true, // 强制设置为一次性事件
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
173
231
|
/**
|
|
174
232
|
* 注销事件
|
|
175
233
|
* @param eventName
|
|
@@ -268,6 +326,37 @@ export default class FWEventManager implements FW.EventManager {
|
|
|
268
326
|
});
|
|
269
327
|
}
|
|
270
328
|
|
|
329
|
+
/**
|
|
330
|
+
* 移除指定的观察者列表
|
|
331
|
+
* @param eventName 事件名
|
|
332
|
+
* @param observersToRemove 待移除的观察者列表
|
|
333
|
+
*/
|
|
334
|
+
private removeObservers(eventName: string | number, observersToRemove: FW.Observer[]): void {
|
|
335
|
+
const observers = this.listeners[eventName];
|
|
336
|
+
if (!observers) return;
|
|
337
|
+
|
|
338
|
+
for (const observerToRemove of observersToRemove) {
|
|
339
|
+
const index = observers.indexOf(observerToRemove);
|
|
340
|
+
if (index !== -1) {
|
|
341
|
+
observers.splice(index, 1);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (observers.length === 0) {
|
|
346
|
+
delete this.listeners[eventName];
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* 获取事件监听器数量
|
|
352
|
+
* @param eventName 事件名
|
|
353
|
+
* @returns 监听器数量
|
|
354
|
+
*/
|
|
355
|
+
public getListenerCount(eventName: string | number): number {
|
|
356
|
+
const observers = this.listeners[eventName];
|
|
357
|
+
return observers ? observers.length : 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
271
360
|
/** 销毁 */
|
|
272
361
|
public onDestroy(): void {
|
|
273
362
|
this.listeners = cc.js.createMap();
|
|
@@ -168,8 +168,8 @@ export class FWLayerManager extends FWManager implements FW.LayerManager {
|
|
|
168
168
|
this.dataManager.notifyExternalRefUpdates(ctr.layerData);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
this.dataManager.removeFromMap(layerData
|
|
172
|
-
this.dataManager.removeFromRegistry(ctr.layerData
|
|
171
|
+
this.dataManager.removeFromMap(layerData?.controllerConstructor);
|
|
172
|
+
this.dataManager.removeFromRegistry(ctr.layerData?.controllerConstructor);
|
|
173
173
|
|
|
174
174
|
const index = this.stackManager.getStack().findIndex((v) => {
|
|
175
175
|
v.controller == ctr;
|
package/manager/FWManager.ts
CHANGED
|
@@ -1,58 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export abstract class FWManager implements FW.Manager {
|
|
4
|
-
public readonly entry: FW.Entry = FW.Entry;
|
|
5
|
-
public readonly managerName: string = this.constructor.name;
|
|
1
|
+
import { FrameworkBase } from '../FrameworkBase';
|
|
6
2
|
|
|
3
|
+
export abstract class FWManager extends FrameworkBase implements FW.Manager {
|
|
7
4
|
public abstract initialize(): void;
|
|
8
5
|
public abstract onDestroy(): void;
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
protected onRestart() {
|
|
8
|
+
this.onDestroy();
|
|
11
9
|
this.initialize();
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
protected async invoke<T>(operation: Promise<T>, operationName: string = 'unknown'): Promise<T> {
|
|
15
|
-
const startTime = this.getCurrentTime();
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
const result = await operation;
|
|
19
|
-
const duration = this.getCurrentTime() - startTime;
|
|
20
|
-
|
|
21
|
-
this.recordPerformanceMetric(operationName, duration);
|
|
22
|
-
return result;
|
|
23
|
-
} catch (error) {
|
|
24
|
-
this.handleError(operationName, error);
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
private recordPerformanceMetric(operationName: string, duration: number): void {
|
|
30
|
-
if (FW.Entry.performanceMgr) {
|
|
31
|
-
FW.Entry.performanceMgr.recordOperationMetric(this.managerName, operationName, duration);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (duration > 1000) {
|
|
35
|
-
FWLog.warn(`Operation ${operationName} took ${duration}ms`);
|
|
36
|
-
} else if (FW.Entry.engineMgr.debug) {
|
|
37
|
-
FWLog.debug(`Operation ${operationName} took ${duration}ms`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
protected handleError(operation: string, error: any): void {
|
|
42
|
-
const errorInfo = {
|
|
43
|
-
manager: this.managerName,
|
|
44
|
-
operation,
|
|
45
|
-
error: error?.message || error,
|
|
46
|
-
stack: error?.stack,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
FWLog.error(`Manager error in ${this.managerName}.${operation}:`, errorInfo);
|
|
50
|
-
|
|
51
|
-
if (CC_DEBUG && FW.Entry.engineMgr.debug) {
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
protected getCurrentTime(): number {
|
|
56
|
-
return Date.now();
|
|
57
|
-
}
|
|
58
11
|
}
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import { FWSystemDefine } from '../define/FWSystemDefine';
|
|
2
|
-
import Framework from '../Framework';
|
|
3
2
|
import FWObject from '../utils/FWObject';
|
|
4
3
|
import { FWObjectPool } from '../utils/FWObjectPool';
|
|
5
4
|
import { FWManager } from './FWManager';
|
|
5
|
+
import FWLog from '../log/FWLog';
|
|
6
6
|
|
|
7
7
|
export default class FWObjectManager extends FWManager implements FW.ObjectManager {
|
|
8
8
|
public initialize(): void {
|
|
9
9
|
this.poolMap = new Map<string, FWObjectPool>();
|
|
10
|
+
this.poolIdCounter = 0;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
public onDestroy(): void {
|
|
14
|
+
this.poolMap.forEach((pool, tag) => {
|
|
15
|
+
try {
|
|
16
|
+
pool.onDestroy();
|
|
17
|
+
} catch (error) {
|
|
18
|
+
FWLog.error(`销毁对象池失败: ${tag}`, error);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
this.poolMap.clear();
|
|
22
|
+
}
|
|
23
|
+
|
|
12
24
|
private poolMap: Map<string, FWObjectPool>;
|
|
25
|
+
private poolIdCounter: number = 0;
|
|
13
26
|
|
|
14
|
-
/** 创建一个对象池 */
|
|
15
27
|
async createObjectPool<T extends FWObject = FWObject>(
|
|
16
28
|
node: cc.Node,
|
|
17
29
|
parent: cc.Node,
|
|
@@ -43,49 +55,104 @@ export default class FWObjectManager extends FWManager implements FW.ObjectManag
|
|
|
43
55
|
type?: number,
|
|
44
56
|
): Promise<FWObjectPool>;
|
|
45
57
|
async createObjectPool<T extends FWObject = FWObject>(): Promise<FWObjectPool> {
|
|
58
|
+
if (arguments.length < 2 || arguments.length > 3) {
|
|
59
|
+
FWLog.error('createObjectPool 参数数量错误,需要2-3个参数');
|
|
60
|
+
throw new Error('Invalid arguments count');
|
|
61
|
+
}
|
|
62
|
+
|
|
46
63
|
let objectNode: cc.Node = null;
|
|
47
64
|
let objectPrefab: cc.Prefab = null;
|
|
48
65
|
let objectAssetProperty: FW.AssetProperty = null;
|
|
49
66
|
let objectParent: cc.Node;
|
|
50
67
|
let objectTag: string;
|
|
51
68
|
let objectType: FWSystemDefine.FWObjectType;
|
|
52
|
-
if (arguments.length > 3) return;
|
|
53
|
-
if (arguments[0] instanceof cc.Node) {
|
|
54
|
-
objectNode = arguments[0];
|
|
55
|
-
} else if (arguments[0] instanceof cc.Prefab) {
|
|
56
|
-
objectPrefab = arguments[0];
|
|
57
|
-
objectNode = cc.instantiate(objectPrefab);
|
|
58
|
-
} else {
|
|
59
|
-
objectAssetProperty = arguments[0];
|
|
60
|
-
objectPrefab = await FW.Entry.resMgr.loadAsset<cc.Prefab>(objectAssetProperty);
|
|
61
|
-
objectNode = cc.instantiate(objectPrefab);
|
|
62
|
-
}
|
|
63
|
-
objectParent = arguments[1];
|
|
64
|
-
if (arguments[2] && typeof arguments[2] === 'string') {
|
|
65
|
-
objectTag = arguments[2];
|
|
66
|
-
objectType = FWSystemDefine.FWObjectType.OPACITY;
|
|
67
|
-
} else {
|
|
68
|
-
objectTag = this.poolMap.size?.toString() || '';
|
|
69
|
-
objectType = arguments[2];
|
|
70
|
-
}
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
try {
|
|
71
|
+
const resources = arguments[0];
|
|
72
|
+
if (resources instanceof cc.Node) {
|
|
73
|
+
objectNode = resources;
|
|
74
|
+
} else if (resources instanceof cc.Prefab) {
|
|
75
|
+
objectPrefab = resources;
|
|
76
|
+
objectNode = cc.instantiate(objectPrefab);
|
|
77
|
+
} else {
|
|
78
|
+
objectAssetProperty = resources;
|
|
79
|
+
objectPrefab = await FW.Entry.resMgr.loadAsset<cc.Prefab>(objectAssetProperty);
|
|
80
|
+
if (!objectPrefab) {
|
|
81
|
+
throw new Error(`加载预制体失败: ${objectAssetProperty.path}`);
|
|
82
|
+
}
|
|
83
|
+
objectNode = cc.instantiate(objectPrefab);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
objectParent = arguments[1];
|
|
87
|
+
if (!(objectParent instanceof cc.Node)) {
|
|
88
|
+
throw new Error('第二个参数必须是 cc.Node 类型');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const arg = arguments[2];
|
|
92
|
+
if (typeof arg === 'string') {
|
|
93
|
+
objectTag = arg;
|
|
94
|
+
objectType = FWSystemDefine.FWObjectType.OPACITY;
|
|
95
|
+
} else if (typeof arg === 'number') {
|
|
96
|
+
objectTag = `pool_${this.poolIdCounter++}`;
|
|
97
|
+
objectType = arg;
|
|
98
|
+
} else {
|
|
99
|
+
objectTag = `pool_${this.poolIdCounter++}`;
|
|
100
|
+
objectType = FWSystemDefine.FWObjectType.OPACITY;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (this.poolMap.has(objectTag)) {
|
|
104
|
+
this.destroyObjectPool(objectTag);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const pool = new FWObjectPool<T>(objectNode, objectParent, objectType);
|
|
108
|
+
this.poolMap.set(objectTag, pool);
|
|
73
109
|
|
|
74
|
-
|
|
110
|
+
return pool;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
FWLog.error('创建对象池失败:', error);
|
|
75
113
|
|
|
76
|
-
|
|
114
|
+
if (objectNode && objectNode.isValid) {
|
|
115
|
+
objectNode.destroy();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
77
120
|
}
|
|
78
121
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
122
|
+
getObjectPool(tag: string): FWObjectPool | undefined {
|
|
123
|
+
if (!this.poolMap.has(tag)) {
|
|
124
|
+
FWLog.warn(`对象池不存在: ${tag}`);
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
82
127
|
return this.poolMap.get(tag);
|
|
83
128
|
}
|
|
84
129
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
130
|
+
destroyObjectPool(tag: string): boolean {
|
|
131
|
+
if (!this.poolMap.has(tag)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const pool = this.poolMap.get(tag);
|
|
137
|
+
pool.onDestroy();
|
|
138
|
+
this.poolMap.delete(tag);
|
|
139
|
+
return true;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getPoolStats(): { total: number; tags: string[] } {
|
|
146
|
+
return {
|
|
147
|
+
total: this.poolMap.size,
|
|
148
|
+
tags: Array.from(this.poolMap.keys()),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
clearAllPools(): void {
|
|
153
|
+
const tags = Array.from(this.poolMap.keys());
|
|
154
|
+
tags.forEach((tag) => {
|
|
155
|
+
this.destroyObjectPool(tag);
|
|
156
|
+
});
|
|
90
157
|
}
|
|
91
158
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// FWPerformanceManager.ts
|
|
2
|
-
|
|
3
1
|
import FWLog from '../log/FWLog';
|
|
4
2
|
import { FWManager } from './FWManager';
|
|
5
3
|
|
|
@@ -8,7 +6,7 @@ import { FWManager } from './FWManager';
|
|
|
8
6
|
*/
|
|
9
7
|
export class FWPerformanceManager extends FWManager implements FW.PerformanceManager {
|
|
10
8
|
private metrics: FW.PerformanceMetric[] = [];
|
|
11
|
-
private
|
|
9
|
+
private moduleStats: Map<
|
|
12
10
|
string,
|
|
13
11
|
{
|
|
14
12
|
totalDuration: number;
|
|
@@ -18,7 +16,7 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
18
16
|
}
|
|
19
17
|
> = new Map();
|
|
20
18
|
|
|
21
|
-
private performanceOptions: FW.
|
|
19
|
+
private performanceOptions: FW.PerformanceModuleOptions;
|
|
22
20
|
|
|
23
21
|
public async initialize(): Promise<void> {
|
|
24
22
|
this.performanceOptions = {
|
|
@@ -28,13 +26,13 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
28
26
|
warningThreshold: 1000,
|
|
29
27
|
};
|
|
30
28
|
if (this.performanceOptions.autoCollect) {
|
|
31
|
-
this.
|
|
29
|
+
this.autoClear();
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
public onDestroy(): void {
|
|
36
34
|
this.metrics = [];
|
|
37
|
-
this.
|
|
35
|
+
this.moduleStats.clear();
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
protected onCleanup(): void {}
|
|
@@ -42,38 +40,38 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
42
40
|
/**
|
|
43
41
|
* 记录操作性能指标
|
|
44
42
|
*/
|
|
45
|
-
public recordOperationMetric(
|
|
43
|
+
public recordOperationMetric(module: string, operation: string, duration: number): void {
|
|
46
44
|
if (Math.random() > this.performanceOptions.samplingRate!) {
|
|
47
45
|
return;
|
|
48
46
|
}
|
|
49
47
|
const metric: FW.PerformanceMetric = {
|
|
50
|
-
|
|
48
|
+
module,
|
|
51
49
|
operation,
|
|
52
50
|
duration,
|
|
53
51
|
timestamp: Date.now(),
|
|
54
52
|
};
|
|
55
53
|
|
|
56
54
|
this.metrics.push(metric);
|
|
57
|
-
this.
|
|
55
|
+
this.updateModuleStats(module, duration);
|
|
58
56
|
|
|
59
57
|
if (duration > this.performanceOptions.warningThreshold!) {
|
|
60
|
-
FWLog.warn(`Performance warning: ${
|
|
58
|
+
FWLog.warn(`Performance warning: ${module}.${operation} took ${duration}ms`);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
/**
|
|
65
|
-
*
|
|
63
|
+
* 获取指定模块的性能报告
|
|
66
64
|
*/
|
|
67
|
-
public
|
|
68
|
-
const stats = this.
|
|
65
|
+
public getModuleReport(module: string): FW.PerformanceReport | null {
|
|
66
|
+
const stats = this.moduleStats.get(module);
|
|
69
67
|
if (!stats) {
|
|
70
68
|
return null;
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
const recentMetrics = this.metrics.filter((m) => m.
|
|
71
|
+
const recentMetrics = this.metrics.filter((m) => m.module === module).slice(-500);
|
|
74
72
|
|
|
75
73
|
return {
|
|
76
|
-
|
|
74
|
+
module,
|
|
77
75
|
totalOperations: stats.operationCount,
|
|
78
76
|
averageDuration: stats.totalDuration / stats.operationCount,
|
|
79
77
|
minDuration: stats.minDuration,
|
|
@@ -88,10 +86,10 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
88
86
|
public getAllReports(): Map<string, FW.PerformanceReport> {
|
|
89
87
|
const reports = new Map<string, FW.PerformanceReport>();
|
|
90
88
|
|
|
91
|
-
this.
|
|
92
|
-
const recentMetrics = this.metrics.filter((m) => m.
|
|
93
|
-
reports.set(
|
|
94
|
-
|
|
89
|
+
this.moduleStats.forEach((stats, module) => {
|
|
90
|
+
const recentMetrics = this.metrics.filter((m) => m.module === module).slice(-500);
|
|
91
|
+
reports.set(module, {
|
|
92
|
+
module,
|
|
95
93
|
totalOperations: stats.operationCount,
|
|
96
94
|
averageDuration: stats.totalDuration / stats.operationCount,
|
|
97
95
|
minDuration: stats.minDuration,
|
|
@@ -109,37 +107,37 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
109
107
|
public getPerformanceSummary(): {
|
|
110
108
|
totalOperations: number;
|
|
111
109
|
averageOperationTime: number;
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
slowestModule: string;
|
|
111
|
+
mostActiveModule: string;
|
|
114
112
|
} {
|
|
115
113
|
let totalOperations = 0;
|
|
116
114
|
let totalDuration = 0;
|
|
117
|
-
let
|
|
115
|
+
let slowestModule = '';
|
|
118
116
|
let maxAvgDuration = 0;
|
|
119
|
-
let
|
|
117
|
+
let mostActiveModule = '';
|
|
120
118
|
let maxOperations = 0;
|
|
121
119
|
|
|
122
|
-
this.
|
|
120
|
+
this.moduleStats.forEach((stats, module) => {
|
|
123
121
|
totalOperations += stats.operationCount;
|
|
124
122
|
totalDuration += stats.totalDuration;
|
|
125
123
|
|
|
126
124
|
const avgDuration = stats.totalDuration / stats.operationCount;
|
|
127
125
|
if (avgDuration > maxAvgDuration) {
|
|
128
126
|
maxAvgDuration = avgDuration;
|
|
129
|
-
|
|
127
|
+
slowestModule = module;
|
|
130
128
|
}
|
|
131
129
|
|
|
132
130
|
if (stats.operationCount > maxOperations) {
|
|
133
131
|
maxOperations = stats.operationCount;
|
|
134
|
-
|
|
132
|
+
mostActiveModule = module;
|
|
135
133
|
}
|
|
136
134
|
});
|
|
137
135
|
|
|
138
136
|
return {
|
|
139
137
|
totalOperations,
|
|
140
138
|
averageOperationTime: totalOperations > 0 ? totalDuration / totalOperations : 0,
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
slowestModule: slowestModule,
|
|
140
|
+
mostActiveModule: mostActiveModule,
|
|
143
141
|
};
|
|
144
142
|
}
|
|
145
143
|
|
|
@@ -167,15 +165,15 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
167
165
|
*/
|
|
168
166
|
public resetAllData(): void {
|
|
169
167
|
this.metrics = [];
|
|
170
|
-
this.
|
|
168
|
+
this.moduleStats.clear();
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
/**
|
|
174
172
|
* 更新管理器统计信息
|
|
175
173
|
*/
|
|
176
|
-
private
|
|
177
|
-
if (!this.
|
|
178
|
-
this.
|
|
174
|
+
private updateModuleStats(module: string, duration: number): void {
|
|
175
|
+
if (!this.moduleStats.has(module)) {
|
|
176
|
+
this.moduleStats.set(module, {
|
|
179
177
|
totalDuration: 0,
|
|
180
178
|
operationCount: 0,
|
|
181
179
|
minDuration: Infinity,
|
|
@@ -183,7 +181,7 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
183
181
|
});
|
|
184
182
|
}
|
|
185
183
|
|
|
186
|
-
const stats = this.
|
|
184
|
+
const stats = this.moduleStats.get(module)!;
|
|
187
185
|
stats.totalDuration += duration;
|
|
188
186
|
stats.operationCount++;
|
|
189
187
|
stats.minDuration = Math.min(stats.minDuration, duration);
|
|
@@ -193,7 +191,7 @@ export class FWPerformanceManager extends FWManager implements FW.PerformanceMan
|
|
|
193
191
|
/**
|
|
194
192
|
* 启动自动清理任务
|
|
195
193
|
*/
|
|
196
|
-
private
|
|
194
|
+
private autoClear(): void {
|
|
197
195
|
FW.Entry.timeMgr.schedule(() => {
|
|
198
196
|
this.clearPerformanceData();
|
|
199
197
|
}, 300);
|