mirror of
https://github.com/Gongxh0901/kunpolibrary
synced 2025-10-09 16:45:45 +00:00
first commit
This commit is contained in:
25
src/condition/ConditionDecorator.ts
Normal file
25
src/condition/ConditionDecorator.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-17
|
||||
* @Description: 条件装饰器
|
||||
*/
|
||||
export namespace _conditionDecorator {
|
||||
/** 用来存储条件注册信息 */
|
||||
const cdClassMap: Map<number, any> = new Map();
|
||||
|
||||
/** 获取组件注册信息 */
|
||||
export function getConditionMaps(): Map<number, any> {
|
||||
return cdClassMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 条件装饰器
|
||||
* @param {number} conditionType 条件类型
|
||||
*/
|
||||
export function conditionClass(conditionType: number): Function {
|
||||
/** target 类的构造函数 */
|
||||
return function (ctor: any): void {
|
||||
cdClassMap.set(conditionType, ctor);
|
||||
};
|
||||
}
|
||||
}
|
210
src/condition/ConditionManager.ts
Normal file
210
src/condition/ConditionManager.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description:
|
||||
*/
|
||||
import { warn } from "../tool/log";
|
||||
import { _conditionDecorator } from "./ConditionDecorator";
|
||||
import { ConditionMode } from "./ConditionMode";
|
||||
import { ConditionBase } from "./node/ConditionBase";
|
||||
import { ConditionNode } from "./node/ConditionNode";
|
||||
export class ConditionManager {
|
||||
/** 注册的 条件类型对应条件的信息 */
|
||||
private static readonly _typeToCondition: Map<number, ConditionBase> = new Map<number, ConditionBase>();
|
||||
|
||||
/** 条件类型 对应 条件节点 */
|
||||
private static readonly _typeToNotifyNodes: Map<number, Set<ConditionNode>> = new Map<number, Set<ConditionNode>>();
|
||||
/** 条件节点 对应 条件类型 */
|
||||
private static readonly _nodeToConditionTypes: Map<ConditionNode, Set<number>> = new Map<ConditionNode, Set<number>>();
|
||||
|
||||
/** 需要更新的条件 */
|
||||
private static readonly _needUpdateConditions: Set<ConditionBase> = new Set<ConditionBase>();
|
||||
/** 需要更新的节点 */
|
||||
private static readonly _needUpdateNodes: Set<ConditionNode> = new Set<ConditionNode>();
|
||||
|
||||
/** 是否正在更新 */
|
||||
private static _updating: boolean = false;
|
||||
|
||||
/** 初始化所有条件,并全部更新一次 */
|
||||
public static initCondition(): void {
|
||||
const conditionMaps = _conditionDecorator.getConditionMaps();
|
||||
conditionMaps.forEach((ctor, conditionType) => {
|
||||
if (!this._typeToCondition.has(conditionType)) {
|
||||
const condition = new ctor();
|
||||
condition.type = conditionType;
|
||||
condition._init();
|
||||
this._addCondition(condition);
|
||||
} else {
|
||||
warn(`条件(${conditionType})已经被注册, 跳过`);
|
||||
}
|
||||
});
|
||||
this._refreshAllConditions();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加条件
|
||||
* @param {IConditionBase} condition 条件
|
||||
*/
|
||||
private static _addCondition(condition: ConditionBase): void {
|
||||
if (this._updating) {
|
||||
throw new Error("请不要在ConditionManager更新过程中添加要更新的条件");
|
||||
}
|
||||
this._typeToNotifyNodes.set(condition.type, new Set<ConditionNode>());
|
||||
this._typeToCondition.set(condition.type, condition);
|
||||
this._needUpdateConditions.add(condition);
|
||||
}
|
||||
|
||||
|
||||
private static _refreshAllConditions(): void {
|
||||
let allCondition = this._typeToCondition;
|
||||
for (const condition of allCondition.values()) {
|
||||
condition._updateCondition();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加到更新列表中
|
||||
* @param conditionType 条件类型
|
||||
*/
|
||||
public static _addUpdateCondition(conditionType: number): void {
|
||||
if (this._updating) {
|
||||
throw new Error("请不要在ConditionManager更新过程中添加要更新的条件");
|
||||
}
|
||||
// 添加待更新的条件;
|
||||
const condition = this._typeToCondition.get(conditionType);
|
||||
if (condition) {
|
||||
this._needUpdateConditions.add(condition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加条件节点
|
||||
* @param notifyNode 条件节点
|
||||
* @param conditionType 条件类型
|
||||
*/
|
||||
public static _addConditionNode(conditionNode: ConditionNode, conditionType: number): void {
|
||||
const condition = this._typeToCondition.get(conditionType);
|
||||
if (!condition) {
|
||||
warn(`不存在条件类型(${conditionType}),请通过装饰器()注册条件类型`);
|
||||
return;
|
||||
}
|
||||
// 添加通知类型对应节点
|
||||
let nodes = this._typeToNotifyNodes.get(condition.type);
|
||||
if (!nodes.has(conditionNode)) {
|
||||
nodes.add(conditionNode);
|
||||
}
|
||||
// 添加节点对应通知类型
|
||||
let conditionTypes = this._nodeToConditionTypes.get(conditionNode);
|
||||
if (!conditionTypes) {
|
||||
conditionTypes = new Set<number>();
|
||||
this._nodeToConditionTypes.set(conditionNode, conditionTypes);
|
||||
}
|
||||
if (!conditionTypes.has(condition.type)) {
|
||||
conditionTypes.add(condition.type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除条件节点
|
||||
* @param conditionNode 条件节点
|
||||
* @param conditionType 条件类型
|
||||
*/
|
||||
public static _removeConditionNode(conditionNode: ConditionNode): void {
|
||||
let types = this._nodeToConditionTypes.get(conditionNode);
|
||||
for (const conditionType of types.values()) {
|
||||
let nodes = this._typeToNotifyNodes.get(conditionType);
|
||||
nodes.delete(conditionNode);
|
||||
}
|
||||
this._nodeToConditionTypes.delete(conditionNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即更新条件节点(内部使用)
|
||||
* @param conditionNode 条件节点
|
||||
*/
|
||||
public static _nowUpdateConditionNode(conditionNode: ConditionNode): void {
|
||||
this._tryUpdateConditionNode(conditionNode);
|
||||
}
|
||||
|
||||
/** 更新函数(内部使用)*/
|
||||
public static _update(): void {
|
||||
this._updating = true;
|
||||
// 更新条件
|
||||
let needUpdateConditions = this._needUpdateConditions;
|
||||
if (needUpdateConditions.size > 0) {
|
||||
for (const condition of needUpdateConditions.values()) {
|
||||
this._tryUpdateCondition(condition);
|
||||
}
|
||||
needUpdateConditions.clear();
|
||||
}
|
||||
// 更新条件节点
|
||||
let needUpdateConditionNodes = this._needUpdateNodes;
|
||||
if (needUpdateConditionNodes.size > 0) {
|
||||
for (const conditionNode of needUpdateConditionNodes.values()) {
|
||||
this._tryUpdateConditionNode(conditionNode);
|
||||
}
|
||||
needUpdateConditionNodes.clear();
|
||||
}
|
||||
this._updating = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新条件节点,如果状态改变,收集需要更新的通知节点(内部使用)
|
||||
* @param {ConditionNode} conditionNode 条件节点
|
||||
*/
|
||||
private static _tryUpdateCondition(condition: ConditionBase): void {
|
||||
// 更新条件
|
||||
if (!condition._updateCondition()) {
|
||||
return;
|
||||
}
|
||||
// 条件改变,收集需要更新的通知节点
|
||||
if (this._typeToNotifyNodes.has(condition.type)) {
|
||||
let nodes = this._typeToNotifyNodes.get(condition.type);
|
||||
let needUpdateConditionNodes = this._needUpdateNodes;
|
||||
for (const conditionNode of nodes) {
|
||||
if (!needUpdateConditionNodes.has(conditionNode)) {
|
||||
needUpdateConditionNodes.add(conditionNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新条件节点(内部使用)
|
||||
* @param {ConditionNode} conditionNode 条件节点
|
||||
*/
|
||||
private static _tryUpdateConditionNode(conditionNode: ConditionNode): void {
|
||||
if (!this._nodeToConditionTypes.has(conditionNode)) {
|
||||
return;
|
||||
}
|
||||
// 获取节点对应的所有通知条件
|
||||
const conditionTypes = this._nodeToConditionTypes.get(conditionNode);
|
||||
const conditions = this._typeToCondition;
|
||||
let canNotify = false;
|
||||
let modeType = conditionNode._modeType;
|
||||
switch (modeType) {
|
||||
case ConditionMode.Any:
|
||||
for (const conditionType of conditionTypes.values()) {
|
||||
// 有一个满足就退出
|
||||
if (conditions.get(conditionType).canNotify()) {
|
||||
canNotify = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ConditionMode.All:
|
||||
canNotify = true;
|
||||
for (const conditionType of conditionTypes.values()) {
|
||||
// 有任意一个不满足就退出
|
||||
if (!conditions.get(conditionType).canNotify()) {
|
||||
canNotify = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
conditionNode.notify(canNotify);
|
||||
}
|
||||
}
|
12
src/condition/ConditionMode.ts
Normal file
12
src/condition/ConditionMode.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 条件模式
|
||||
*/
|
||||
|
||||
export enum ConditionMode {
|
||||
/** 满足任意条件显示 */
|
||||
Any,
|
||||
/** 满足所有条件显示 */
|
||||
All,
|
||||
}
|
44
src/condition/ConditionModule.ts
Normal file
44
src/condition/ConditionModule.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 条件显示模块
|
||||
*/
|
||||
import { _decorator } from "cc";
|
||||
import { InnerTimer } from "../global/InnerTimer";
|
||||
import { ModuleBase } from "../module/ModuleBase";
|
||||
import { info } from "../tool/log";
|
||||
import { ConditionManager } from "./ConditionManager";
|
||||
|
||||
const { ccclass, menu, property } = _decorator;
|
||||
|
||||
@ccclass("ConditionModule")
|
||||
@menu("kunpo/condition/ConditionModule")
|
||||
export class ConditionModule extends ModuleBase {
|
||||
@property({
|
||||
displayName: "更新间隔(秒)",
|
||||
min: 0.1,
|
||||
step: 0.1,
|
||||
})
|
||||
updateDeltaTime: number = 0.3;
|
||||
|
||||
/** 模块名称 */
|
||||
public moduleName: string = "条件显示模块";
|
||||
|
||||
private _timer: number = 0;
|
||||
public init(): void {
|
||||
this.onInit();
|
||||
|
||||
this._timer = InnerTimer.startTimer(() => {
|
||||
ConditionManager._update();
|
||||
}, this.updateDeltaTime, -1);
|
||||
}
|
||||
|
||||
/** 模块初始化完成后调用的函数 */
|
||||
protected onInit(): void {
|
||||
info("ConditionModule init complete");
|
||||
}
|
||||
|
||||
public onDestroy(): void {
|
||||
InnerTimer.stopTimer(this._timer);
|
||||
}
|
||||
}
|
18
src/condition/node/ConditionAllNode.ts
Normal file
18
src/condition/node/ConditionAllNode.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 满足所有条件显示
|
||||
*/
|
||||
import { GObject } from "fairygui-cc";
|
||||
import { ConditionMode } from "../ConditionMode";
|
||||
import { ConditionFGUINode } from "./ConditionFGUINode";
|
||||
export class ConditionAllNode extends ConditionFGUINode {
|
||||
/**
|
||||
* 构建红点节点
|
||||
* @param {GObject} node 关联节点
|
||||
* @param {...number[]} conditionTypes 条件类型
|
||||
*/
|
||||
public constructor(node: GObject, ...conditionTypes: number[]) {
|
||||
super(node, ConditionMode.All, ...conditionTypes);
|
||||
}
|
||||
}
|
18
src/condition/node/ConditionAnyNode.ts
Normal file
18
src/condition/node/ConditionAnyNode.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 满足任意条件显示
|
||||
*/
|
||||
import { GObject } from "fairygui-cc";
|
||||
import { ConditionMode } from "../ConditionMode";
|
||||
import { ConditionFGUINode } from "./ConditionFGUINode";
|
||||
export class ConditionAnyNode extends ConditionFGUINode {
|
||||
/**
|
||||
* 构建红点节点
|
||||
* @param {GObject} node 关联节点
|
||||
* @param {...number[]} conditionTypes 条件类型
|
||||
*/
|
||||
public constructor(node: GObject, ...conditionTypes: number[]) {
|
||||
super(node, ConditionMode.Any, ...conditionTypes);
|
||||
}
|
||||
}
|
54
src/condition/node/ConditionBase.ts
Normal file
54
src/condition/node/ConditionBase.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 条件基类
|
||||
*/
|
||||
|
||||
import { ConditionManager } from "../ConditionManager";
|
||||
|
||||
export abstract class ConditionBase {
|
||||
/** 初始化 */
|
||||
public _init(): void {
|
||||
this.onInit();
|
||||
}
|
||||
|
||||
/** 条件类型 */
|
||||
public type: number;
|
||||
|
||||
private _canNotify: boolean;
|
||||
/**
|
||||
* 是否可以通知
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public canNotify(): boolean {
|
||||
return this._canNotify;
|
||||
}
|
||||
|
||||
public tryUpdate(): void {
|
||||
ConditionManager._addUpdateCondition(this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新条件
|
||||
* @returns {boolean} 是否发生变化
|
||||
*/
|
||||
public _updateCondition(): boolean {
|
||||
let canNotify = this.evaluate();
|
||||
if (canNotify == this._canNotify) {
|
||||
return;
|
||||
}
|
||||
this._canNotify = canNotify;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
protected abstract onInit(): void;
|
||||
|
||||
/**
|
||||
* 返回条件结果 子类实现
|
||||
* @returns {boolean}
|
||||
*/
|
||||
protected abstract evaluate(): boolean;
|
||||
}
|
52
src/condition/node/ConditionFGUINode.ts
Normal file
52
src/condition/node/ConditionFGUINode.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-17
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
import { GObject } from "fairygui-cc";
|
||||
import { ConditionManager } from "../ConditionManager";
|
||||
import { ConditionMode } from "../ConditionMode";
|
||||
import { ConditionNode } from "./ConditionNode";
|
||||
export class ConditionFGUINode extends ConditionNode {
|
||||
/**
|
||||
* 红点节点
|
||||
* @protected
|
||||
* @type {GObject | Node} fgui节点 或 node节点
|
||||
* @memberof NotityFGUINode
|
||||
*/
|
||||
protected node: GObject;
|
||||
|
||||
private _oldRemoveFromParent: () => void;
|
||||
|
||||
/**
|
||||
* 构建红点节点
|
||||
* @param {GObject} node 关联节点
|
||||
* @param {...number[]} conditionTypes 条件类型
|
||||
*/
|
||||
public constructor(node: GObject, modeType: ConditionMode, ...conditionTypes: number[]) {
|
||||
super(modeType, ...conditionTypes);
|
||||
this.node = node;
|
||||
const oldRemoveFromParent = (this._oldRemoveFromParent = node.removeFromParent);
|
||||
node.removeFromParent = (): void => {
|
||||
super.destroy();
|
||||
oldRemoveFromParent.call(node);
|
||||
this.node.removeFromParent = this._oldRemoveFromParent;
|
||||
this.node = null;
|
||||
};
|
||||
// 立即更新一次
|
||||
ConditionManager._nowUpdateConditionNode(this);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
if (this.node) {
|
||||
this.node.removeFromParent = this._oldRemoveFromParent;
|
||||
this.node = null;
|
||||
}
|
||||
}
|
||||
|
||||
public notify(visible: boolean): void {
|
||||
this.node.visible = visible;
|
||||
}
|
||||
}
|
36
src/condition/node/ConditionNode.ts
Normal file
36
src/condition/node/ConditionNode.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @Author: Gongxh
|
||||
* @Date: 2025-02-14
|
||||
* @Description: 条件节点
|
||||
*/
|
||||
|
||||
import { ConditionManager } from "../ConditionManager";
|
||||
import { ConditionMode } from "../ConditionMode";
|
||||
|
||||
export abstract class ConditionNode {
|
||||
/** 条件类型 */
|
||||
public _modeType: ConditionMode;
|
||||
|
||||
/**
|
||||
* 构建红点节点
|
||||
* @param {GObject} node 关联节点
|
||||
* @param {...number[]} conditionTypes 条件类型
|
||||
*/
|
||||
public constructor(modeType: ConditionMode, ...conditionTypes: number[]) {
|
||||
this._modeType = modeType;
|
||||
for (const conditionType of conditionTypes) {
|
||||
ConditionManager._addConditionNode(this, conditionType);
|
||||
}
|
||||
}
|
||||
|
||||
/** 移除节点 */
|
||||
public destroy(): void {
|
||||
ConditionManager._removeConditionNode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知节点更新
|
||||
* @param {boolean} visible 节点显示状态
|
||||
*/
|
||||
public abstract notify(visible: boolean): void;
|
||||
}
|
Reference in New Issue
Block a user