import { gameMethod } from "../../common/gameMethod"; import { RedUtilType } from "../../data/const/TypeConst"; import { ItemLabelRender } from "./ListUtil"; export class RedUtil { private static _redMap: Map = new Map(); static clear() { this._redMap.clear() } static registerBaseRed(type: RedUtilType, func: () => boolean, target: any = null) { if (this.getRedDot(type)) { if (CC_PREVIEW) console.warn("红点" + type + "已经注册过了"); return; } let red = new RedDotBase(type, func.bind(target)); if (red == null) return; this._redMap.set(type, red); } static registerUpperRed(type: RedUtilType, childs: RedUtilType[], func: () => boolean = null) { if (this.getRedDot(type)) { if (CC_PREVIEW) console.warn("红点" + type + "已经注册过了"); return; } let rednode = new RedDotNode(type); this.setChilds(rednode, childs); this._redMap.set(type, rednode); } static getRedState(type: RedUtilType): boolean { let red = this.getRedDot(type); if (red == null) { if (CC_PREVIEW) console.warn(`红点 ${type} 不存在`); return false; } return red.getRedState(); } static getRedDot(type) { return this._redMap?.get(type); } static upRedNode(type: RedUtilType, node: RedDot) { let red = this.getRedDot(type); if (red == null) { if (CC_PREVIEW) console.warn(`节点:${node.name} 的红点 ${type} 不存在 `); return; } if (red.node && red.node != node) { if (CC_PREVIEW) console.warn(`节点${red.node?.name}已经挂载了${type}红点,${node?.name}重复挂载了`); return; } red.node = node; } static offRedNode(type: RedUtilType) { let red = this.getRedDot(type); if (red == null) { if (CC_PREVIEW) console.warn(`红点 ${type} 不存在 `); return; } red.node = null; } private static setChilds(red: RedDotNode, childs: RedUtilType[]) { for (let child of childs) { if (child == red.type) { if (CC_PREVIEW) console.warn(`红点 ${red.type} 不能自己依赖自己`); continue; } this.setChild(red.type, child); } red.childs = childs; } static updateRed(type: RedUtilType) { let red = this.getRedDot(type); if (red instanceof RedDotBase) { red.updateRed(); } else { if (CC_PREVIEW) console.warn(`红点类型不是底部红点 ${type}`); } } private static setChild(parent: RedUtilType, child: RedUtilType) { let red = this._redMap.get(child); //排除重复挂载依赖 if (red == null) { if (CC_PREVIEW) console.warn(`${child} 红点不存在`); return } if (red.parent) { if (CC_PREVIEW) console.warn(`${child} 已经有父红点了`); return } red.parent = parent; } public static initRedUtil() { this._redMap?.forEach((red: RedDotClass) => { if (red instanceof RedDotBase) red.updateRed(); }); } } abstract class RedDotClass { type: RedUtilType; parent: RedUtilType; node: RedDot; constructor(type: RedUtilType) { this.type = type; } abstract getRedState(): boolean; abstract updateRed(); } class RedDotNode extends RedDotClass { childs: RedUtilType[] = []; getRedState(): boolean { let isred = false; for (let i of this.childs) { let red = RedUtil.getRedDot(i); isred = red.getRedState(); if (isred) break; } return isred; } updateRed() { this.node?.upRed(); if (this.parent) { let red = RedUtil.getRedDot(this.parent); if (red == null) { if (CC_PREVIEW) console.warn(`红点:${this.parent} 不存在`); return; } red.updateRed(); } } } class RedDotBase extends RedDotClass { redCount: boolean; func: () => boolean; constructor(type: RedUtilType, func: () => boolean) { super(type); this.func = func; } reCalRed(): boolean { try { this.redCount = this.func() ?? false; } catch (err) { if (CC_PREVIEW) console.warn(err); this.redCount = false; } return this.redCount; } getRedState(): boolean { return this.redCount; } updateRed() { this.reCalRed(); this.node?.upRed(); if (this.parent) { let red = RedUtil.getRedDot(this.parent); if (red == null) { if (CC_PREVIEW) console.warn(`红点:${this.parent} 不存在`); return; } red.updateRed(); } } } export class RedDot extends ItemLabelRender { type: RedUtilType; show: fairygui.Controller; onInit(): void { this.initControllers(); } onShow(): void { this.upNode(); } onHide(): void { this.offNode(); } upNode() { if (this.type == null) { this.show.selectedIndex = 1; return; } RedUtil.upRedNode(this.type, this); this.upRed(); } offNode() { if (this.type == null) return; RedUtil.offRedNode(this.type); } setData(data: RedUtilType, index?: number, param?: any) { this.type = data; this.upNode() } upRed() { if (gameMethod.isEmpty(this.node)) { return; } this.show.selectedIndex = RedUtil.getRedState(this.type) ? 0 : 1; } isShow() { return this.show.selectedIndex == 0; } }