@chiyou/minigame-framework 1.2.68 → 1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chiyou/minigame-framework",
3
- "version": "1.2.68",
3
+ "version": "1.3.0",
4
4
  "description": "基于 Cocos Creator 3.x 的小游戏开发框架,支持多平台发布",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 事件监听者信息(调试用)
3
+ */
4
+ export interface EventListenerInfo {
5
+ callback: Function;
6
+ target: any;
7
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 定时器重复次数枚举
3
+ */
4
+ export enum TimerRepeat {
5
+ /** 只执行一次 */
6
+ Once = 1,
7
+ /** 无限循环 */
8
+ Infinite = -1,
9
+ }
@@ -1,4 +1,5 @@
1
1
  import { LogUtils } from '../Utils/LogUtils';
2
+ import { EventListenerInfo } from '../Definition/EventDefinition';
2
3
  import { BaseMgr } from './BaseMgr';
3
4
 
4
5
  /** 事件项 */
@@ -73,6 +74,20 @@ export class EventMgr extends BaseMgr {
73
74
  this.eventList.set(eventName, array);
74
75
  }
75
76
 
77
+ /**
78
+ * 监听事件(只触发一次,触发后自动移除)
79
+ * @param eventName 事件名称
80
+ * @param callback 回调函数
81
+ * @param target 回调目标对象
82
+ */
83
+ public once(eventName: string, callback: Function, target: any): void {
84
+ const wrappedCallback = (...data: any[]) => {
85
+ this.off(eventName, wrappedCallback, target);
86
+ callback.apply(target, data);
87
+ };
88
+ this.on(eventName, wrappedCallback, target);
89
+ }
90
+
76
91
  /**
77
92
  * 取消监听事件
78
93
  * @param eventName 事件名称
@@ -128,6 +143,22 @@ export class EventMgr extends BaseMgr {
128
143
  }
129
144
  }
130
145
 
146
+ /**
147
+ * 获取指定事件的所有监听者(调试用)
148
+ * @param eventName 事件名称
149
+ * @return 监听者信息数组
150
+ */
151
+ public getListeners(eventName: string): EventListenerInfo[] {
152
+ const array = this.eventList.get(eventName);
153
+ if (!array || array.length === 0) {
154
+ return [];
155
+ }
156
+ return array.map(item => ({
157
+ callback: item.callback,
158
+ target: item.target
159
+ }));
160
+ }
161
+
131
162
  /**
132
163
  * 触发事件
133
164
  * @param eventName 事件名称
@@ -3,7 +3,7 @@ import { BaseMgr } from './BaseMgr';
3
3
  import { LogUtils } from '../Utils/LogUtils';
4
4
  import { FwkErrorCode } from '../Definition/FwkErrorDefinition';
5
5
  import { ServiceLocator } from '../Utils/ServiceLocator';
6
- import type { UIMgr } from './UIMgr';
6
+ import { UIMgr, UICtrl } from './UIMgr';
7
7
 
8
8
  /** 节点池配置接口 */
9
9
  export interface IPoolConfig {
@@ -334,6 +334,15 @@ export class NodePoolMgr extends BaseMgr {
334
334
  let node: Node = poolInfo.pool.get() as Node;
335
335
  poolInfo.usingNodeSet.add(node);
336
336
 
337
+ // 重置 Transform(_resetNode 只管 Transform,不管业务组件)
338
+ this._resetNode(node);
339
+
340
+ // 调用业务层钩子 onPoolGet(顺序:_resetNode → onPoolGet → addChild → active)
341
+ let ctrl: UICtrl = node.getComponent(UICtrl);
342
+ if (ctrl && typeof ctrl.onPoolGet === 'function' && node.isValid) {
343
+ ctrl.onPoolGet(node);
344
+ }
345
+
337
346
  if (parent) {
338
347
  parent.addChild(node);
339
348
  }
@@ -480,7 +489,10 @@ export class NodePoolMgr extends BaseMgr {
480
489
  }
481
490
  }
482
491
 
483
- /** 回收节点(内部方法) */
492
+ /**
493
+ * 回收节点(内部方法)
494
+ * 调用顺序:NodePoolMgr.putNode → UICtrl.onPoolPut → NodePoolMgr._resetNode → node.active = false → 入池
495
+ */
484
496
  private _recycleNode(poolName: string, node: Node, resetNode: boolean = true): void {
485
497
  if (!node || !node.isValid) {
486
498
  return;
@@ -494,7 +506,12 @@ export class NodePoolMgr extends BaseMgr {
494
506
  node.removeFromParent();
495
507
  }
496
508
 
509
+ // 调用业务层钩子 onPoolPut(顺序:onPoolPut → _resetNode → active → 入池)
497
510
  if (resetNode) {
511
+ let ctrl: UICtrl = node.getComponent(UICtrl);
512
+ if (ctrl && typeof ctrl.onPoolPut === 'function' && node.isValid) {
513
+ ctrl.onPoolPut(node);
514
+ }
498
515
  this._resetNode(node);
499
516
  }
500
517
 
@@ -513,7 +530,11 @@ export class NodePoolMgr extends BaseMgr {
513
530
  }
514
531
  }
515
532
 
516
- /** 重置节点(内部方法) */
533
+ /**
534
+ * 重置节点 Transform(内部方法)
535
+ * 注意:只重置 position/rotation/scale,不管业务组件(如 UIOpacity 等)。
536
+ * 业务组件的清理由 onPoolPut 钩子兜底。
537
+ */
517
538
  private _resetNode(node: Node): void {
518
539
  if (!node || !node.isValid) {
519
540
  return;
@@ -575,11 +575,12 @@ export class ResMgr extends BaseMgr {
575
575
  }
576
576
 
577
577
  /**
578
- * 获取资源
578
+ * 获取资源(同步)
579
+ * @description 必须先通过 preloadResBatch 预加载或 loadRes/loadResAsync 加载目标资源后,才能使用 getAsset 获取。同一帧内不支持同步触发加载。
579
580
  * @param bundleName AssetBundle 名称
580
581
  * @param url 资源路径
581
582
  * @param assetType 资源类型
582
- * @return 资源实例
583
+ * @return 资源实例(未加载时返回 null)
583
584
  */
584
585
  public getAsset<T extends Asset>(bundleName: string, url: string, assetType?: typeof Asset): T | null {
585
586
  if (!bundleName || bundleName.trim() === "") {
@@ -739,6 +740,44 @@ export class ResMgr extends BaseMgr {
739
740
  });
740
741
  }
741
742
 
743
+ /**
744
+ * 动态加载资源(Promise 版本)
745
+ * @param bundleName AssetBundle 名称
746
+ * @param url 资源路径
747
+ * @param assetType 资源类型
748
+ * @return Promise<Asset> 资源实例
749
+ */
750
+ public loadResAsync<T extends Asset>(bundleName: string, url: string, assetType: typeof Asset): Promise<T> {
751
+ return new Promise<T>((resolve, reject) => {
752
+ this.loadRes(bundleName, url, assetType, (success: boolean) => {
753
+ if (success) {
754
+ let asset = this.getAsset<T>(bundleName, url, assetType);
755
+ if (asset) {
756
+ resolve(asset);
757
+ } else {
758
+ LogUtils.Instance.error(ResMgr.TAG, FwkErrorCode.Res.NotFound, {
759
+ operation: "loadResAsync",
760
+ reason: "loadRes 成功但 getAsset 返回 null(可能原因:图集子资源 URL 不正确,或资源类型不匹配)",
761
+ bundleName: bundleName,
762
+ url: url,
763
+ assetType: assetType?.name || "未指定"
764
+ });
765
+ reject(new Error(`loadResAsync: getAsset returned null, bundle=${bundleName}, url=${url}`));
766
+ }
767
+ } else {
768
+ LogUtils.Instance.error(ResMgr.TAG, FwkErrorCode.Res.LoadAssetFailed, {
769
+ operation: "loadResAsync",
770
+ reason: "loadRes 加载失败",
771
+ bundleName: bundleName,
772
+ url: url,
773
+ assetType: assetType?.name || "未指定"
774
+ });
775
+ reject(new Error(`loadResAsync failed: bundle=${bundleName}, url=${url}`));
776
+ }
777
+ });
778
+ });
779
+ }
780
+
742
781
  /**
743
782
  * 加载远程图片
744
783
  * @param imageUrl 图片 URL
@@ -11,7 +11,7 @@ import { PlatformAdapterVivo } from "../Adapter/PlatformAdapter/PlatformAdapterV
11
11
  import { PlatformAdapterWeiXin } from "../Adapter/PlatformAdapter/PlatformAdapterWeiXin";
12
12
  import { PlatformAdapterXiaoMi } from "../Adapter/PlatformAdapter/PlatformAdapterXiaoMi";
13
13
  import { PlatformAdapterZhiFuBao } from "../Adapter/PlatformAdapter/PlatformAdapterZhiFuBao";
14
- import { AppItem, CopyrightInfo, ICPItem, PlatformID } from "../Definition/SystemDefinition";
14
+ import { AppItem, CopyrightInfo, ICPItem, PlatformID, ScreenInfo } from "../Definition/SystemDefinition";
15
15
  import { FwkErrorCode } from "../Definition/FwkErrorDefinition";
16
16
  import { LogUtils } from "../Utils/LogUtils";
17
17
  import { BaseMgr } from "./BaseMgr";
@@ -344,4 +344,12 @@ export class SystemMgr extends BaseMgr {
344
344
 
345
345
  this.getPlatformAdapter().downloadFile(fileUrl, success, fail);
346
346
  }
347
+
348
+ public getScreenInfo(): ScreenInfo {
349
+ if (this.getPlatformAdapter() === null) {
350
+ return null;
351
+ }
352
+
353
+ return this.getPlatformAdapter().getScreenInfo();
354
+ }
347
355
  }
@@ -1,4 +1,5 @@
1
1
  import { FwkErrorCode } from "../Definition/FwkErrorDefinition";
2
+ import { TimerRepeat } from "../Definition/TimerDefinition";
2
3
  import { LogUtils } from "../Utils/LogUtils";
3
4
  import { ServiceLocator } from "../Utils/ServiceLocator";
4
5
  import { BaseMgr } from "./BaseMgr";
@@ -45,15 +46,15 @@ export class TimerMgr extends BaseMgr {
45
46
  * 添加定时器
46
47
  * @param delay 延迟时间(秒)
47
48
  * @param interval 间隔时间(秒)
48
- * @param repeat 重复次数,0表示拒绝,负数表示无限
49
+ * @param repeat 重复次数:TimerRepeat.Once(1)= 执行一次后移除,TimerRepeat.Infinite(-1)= 无限循环,0 = 不执行(立即跳过),>0 = 执行指定次数
49
50
  * @param func 回调函数
50
51
  * @param target 回调目标对象
51
52
  */
52
- public addTimer(delay: number, interval: number, repeat: number, func: Function, target: Object) {
53
+ public addTimer(delay: number, interval: number, repeat: TimerRepeat | number, func: Function, target: Object) {
53
54
  if (repeat === 0) {
54
55
  LogUtils.Instance.error(TimerMgr.TAG, FwkErrorCode.Timer.InvalidState, {
55
56
  operation: "addTimer",
56
- reason: "重复次数为0",
57
+ reason: "repeat=0 拒绝添加(不支持),应使用 TimerRepeat.Once",
57
58
  delay: delay,
58
59
  interval: interval,
59
60
  repeat: repeat
@@ -16,6 +16,20 @@ export class UICtrl extends Component {
16
16
  this.load_all_object(this.node, "");
17
17
  }
18
18
 
19
+ /**
20
+ * 节点从池中取出时调用(UICtrl 子类可 override)
21
+ * 调用顺序:NodePoolMgr.getNode → NodePoolMgr._resetNode → UICtrl.onPoolGet → parent.addChild → node.active = true
22
+ * @param node 从池中取出的节点
23
+ */
24
+ public onPoolGet?(node: Node): void;
25
+
26
+ /**
27
+ * 节点归还到池中时调用(UICtrl 子类可 override)
28
+ * 调用顺序:NodePoolMgr.putNode → UICtrl.onPoolPut → NodePoolMgr._resetNode → node.active = false → 入池
29
+ * @param node 归还到池中的节点
30
+ */
31
+ public onPoolPut?(node: Node): void;
32
+
19
33
  /** 加载所有子节点到视图映射 */
20
34
  private load_all_object(root: Node, path: string): void {
21
35
  for (let i = 0; i < root.children.length; i++) {
package/src/index.ts CHANGED
@@ -52,4 +52,6 @@ export * from './Framework/Definition/PrivacyDefinition';
52
52
  export * from './Framework/Definition/SocialDefinition';
53
53
  export * from './Framework/Definition/FwkErrorDefinition';
54
54
  export * from './Framework/Definition/UIDefinition';
55
+ export * from './Framework/Definition/EventDefinition';
56
+ export * from './Framework/Definition/TimerDefinition';
55
57
  export * from './Framework/Definition/FrameworkBase';