first commit

This commit is contained in:
宫欣海
2025-02-20 11:27:28 +08:00
commit 68090ca38d
91 changed files with 9915 additions and 0 deletions

View 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);
};
}
}

View 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);
}
}

View File

@@ -0,0 +1,12 @@
/**
* @Author: Gongxh
* @Date: 2025-02-14
* @Description: 条件模式
*/
export enum ConditionMode {
/** 满足任意条件显示 */
Any,
/** 满足所有条件显示 */
All,
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}

View 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;
}
}

View 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;
}