kunpolibrary/src/condition/ConditionManager.ts
2025-03-07 16:57:26 +08:00

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