mirror of
https://github.com/Gongxh0901/kunpolibrary
synced 2025-07-04 15:24:20 +00:00
223 lines
8.0 KiB
TypeScript
223 lines
8.0 KiB
TypeScript
/**
|
|
* @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 {
|
|
/** 注册的 条件类型对应条件的信息 @internal */
|
|
private static readonly _typeToCondition: Map<number, ConditionBase> = new Map<number, ConditionBase>();
|
|
|
|
/** 条件类型 对应 条件节点 @internal */
|
|
private static readonly _typeToNotifyNodes: Map<number, Set<ConditionNode>> = new Map<number, Set<ConditionNode>>();
|
|
/** 条件节点 对应 条件类型 @internal */
|
|
private static readonly _nodeToConditionTypes: Map<ConditionNode, Set<number>> = new Map<ConditionNode, Set<number>>();
|
|
|
|
/** 需要更新的条件 @internal */
|
|
private static readonly _needUpdateConditions: Set<ConditionBase> = new Set<ConditionBase>();
|
|
/** 需要更新的节点 @internal */
|
|
private static readonly _needUpdateNodes: Set<ConditionNode> = new Set<ConditionNode>();
|
|
|
|
/** 是否正在更新 @internal */
|
|
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 条件
|
|
* @internal
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* 刷新所有条件
|
|
* @internal
|
|
*/
|
|
private static _refreshAllConditions(): void {
|
|
let allCondition = this._typeToCondition;
|
|
for (const condition of allCondition.values()) {
|
|
condition._updateCondition();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加到更新列表中
|
|
* @param conditionType 条件类型
|
|
* @internal
|
|
*/
|
|
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 条件类型
|
|
* @internal
|
|
*/
|
|
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 条件类型
|
|
* @internal
|
|
*/
|
|
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 条件节点
|
|
* @internal
|
|
*/
|
|
public static _nowUpdateConditionNode(conditionNode: ConditionNode): void {
|
|
this._tryUpdateConditionNode(conditionNode);
|
|
}
|
|
|
|
/**
|
|
* 更新函数(内部使用)
|
|
* @internal
|
|
*/
|
|
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 {ConditionBase} condition 条件
|
|
* @internal
|
|
*/
|
|
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 条件节点
|
|
* @internal
|
|
*/
|
|
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);
|
|
}
|
|
} |