import { _decorator, director } from 'cc'; import { Auto_MainUI } from './Auto_MainUI'; import { UIPanelHomeOld } from '../PanelHome/UIPanelHomeOld'; import { UIConfigs, UIID, GAudioPath } from '../../game/ConfigRes'; import { GEvent } from 'db://assets/mx/module/event/GEvent'; import { PreloadPredictor } from 'db://assets/mx/module/res/PreloadPredictor'; import { BundleLifecycle } from 'db://assets/mx/module/res/BundleLifecycle'; import { MemoryProfile } from '../../game/MemoryProfile'; import { DailyShopDataManager } from '../../manager/DailyShopDataManager'; import { HeadIconManager } from '../../manager/HeadIconManager'; const { ccclass } = _decorator; @ccclass('UIMainUI') export class UIMainUI extends Auto_MainUI { private static readonly MAIN_TAB_IDS: number[] = [ UIID.Shop, UIID.Role, UIID.Home, UIID.Weapon, ]; onEnable(): void { GEvent.Ins.on(GEvent.UpdateMainUI, this.updateUI, this); GEvent.Ins.on(GEvent.TiaoZhuanShop, this._onTiaoZhuanShop, this); GEvent.Ins.on(GEvent.UpdateHeadIcon, this._refreshHeadIcon, this); this.schedule(this._tickRedDot, 1); super.onEnable(); this._refreshHeadIcon(); } onDisable(): void { GEvent.Ins.off(GEvent.UpdateMainUI, this.updateUI, this); GEvent.Ins.off(GEvent.TiaoZhuanShop, this._onTiaoZhuanShop, this); GEvent.Ins.off(GEvent.UpdateHeadIcon, this._refreshHeadIcon, this); this.unschedule(this._tickRedDot); super.onDisable(); } /** 刷新顶栏头像 */ private _refreshHeadIcon(): void { void HeadIconManager.refreshUiHeadAsync(this.ui_head); } private _tickRedDot(): void { gg.dot.updateRedDot(); } onInit(): void { gg.audio.playMusic({ name: '首页背景音', path: GAudioPath.Bgm }); this.updateUI(); let pageID = UIID.Home; if (this.prema != null && this.prema != undefined) { pageID = this.prema; } this.showPage(pageID).then(() => { this._onMainUiFirstPageReady(); }).catch((e) => console.error('[UIMainUI] onInit', String(e))); } private _onMainUiFirstPageReady(): void { gg.game.hideLoading(); gg.game.onMainUiReady(); gg.sdk.notifyFeedGameInteractive(); gg.sdk.storeFeedData(); gg.sdk.PlatformFeedSubscribe(); this._tryPopDailyShopBuy(); } /** 战斗胜利/失败领取奖励回大厅后,自动弹出每日商店翻牌窗 */ private _tryPopDailyShopBuy(): void { DailyShopDataManager.popSettleShopPanelIfNeeded(); } private _curentID: UIID = null; /** 切 Tab 世代,过期的 showPage 不得再开 */ private _pageEpoch = 0; isHomeTabSelected(): boolean { return this._curentID === UIID.Home || this._curentID === null; } private _showPageChain: Promise = Promise.resolve(); showPage(pageID: UIID, notCheck = false): Promise { if (pageID == this._curentID && gg.ui.panelIsShow(pageID)) { return Promise.resolve(); } const epoch = ++this._pageEpoch; this._curentID = pageID; this._setTabSelected(pageID); PreloadPredictor.getInstance().onTabIntent(pageID); this._showPageChain = this._showPageChain .then(() => { if (epoch !== this._pageEpoch) return; return this._showPageImpl(pageID); }) .catch((e) => console.error('[UIMainUI] showPage', String(e))); return this._showPageChain; } /** 先打开目标 Tab,成功后再隐藏/关闭其它 Tab */ private _showPageImpl(pageID: UIID): Promise { if (this._curentID !== pageID) return Promise.resolve(); return gg.ui.openPanel(pageID).then((ok) => { if (this._curentID !== pageID) return; if (!ok) { this._restoreTabAfterOpenFail(pageID); gg.ui.showToast('页面加载失败', false); return; } this.hideOtherMainTabPagesExcept(pageID); return this._closeInactiveMainTabs(pageID).then(() => { if (this._curentID !== pageID) return; this._releaseInactiveTabBundles(pageID); }); }); } /** 刷新底栏 Tab 选中态 */ private _setTabSelected(pageID: UIID | null): void { this.ui_btns.children.map(c => c.find('select').active = false); if (pageID == null) return; const btn = this.ui_btns.find('btn' + pageID); if (!btn) return; btn.find('select').active = true; } /** 目标 Tab 打开失败时,把选中态恢复到仍在显示的 Tab */ private _restoreTabAfterOpenFail(failedId: UIID): void { if (this._curentID !== failedId) return; let restore: UIID = null; for (const id of UIMainUI.MAIN_TAB_IDS) { if (id === failedId) continue; if (gg.ui.panelIsShow(id)) { restore = id; break; } } this._curentID = restore; this._setTabSelected(restore); } private getMainUiContentLayer() { const scene = director.getScene(); if (!scene?.isValid) return null; const canvas = scene.getChildByName('Canvas'); const root = canvas?.getChildByName('root'); return root?.getChildByName('MainUI') ?? null; } private hideOtherMainTabPagesExcept(showId: UIID) { const layer = this.getMainUiContentLayer(); if (!layer?.isValid) return; for (const id of UIMainUI.MAIN_TAB_IDS) { const conf = UIConfigs[id]; if (!conf) continue; const page = layer.getChildByName(conf.name); if (page?.isValid) { page.active = id === showId; } } } private _closeInactiveMainTabs(showId: UIID): Promise { let chain = Promise.resolve(); for (const id of UIMainUI.MAIN_TAB_IDS) { if (id === showId || id === UIID.Home) continue; if (!gg.ui.hasPanel(id)) continue; const panelId = id; chain = chain.then(() => gg.ui.closePanel(panelId)); } return chain; } private _releaseInactiveTabBundles(showId: UIID): void { if (!MemoryProfile.current.enableTabBundleUnloadOnSwitch) return; const keep = PreloadPredictor.getTabBundlesForPage(showId); BundleLifecycle.getInstance().releaseTabBundlesExcept(keep); const unloaded: string[] = []; for (const id of UIMainUI.MAIN_TAB_IDS) { if (id === showId || id === UIID.Home) continue; for (const bundle of PreloadPredictor.getTabBundlesForPage(id)) { unloaded.push(bundle); } } PreloadPredictor.getInstance().clearTabPreloadForBundles(unloaded); } private _onTiaoZhuanShop = (tabIndex: number): void => { const tabPages: UIID[] = [UIID.Shop, UIID.Role, UIID.Home, UIID.Weapon]; const pageID = tabPages[tabIndex]; if (pageID == null) return; void this.showPage(pageID); }; updateUI() { this.btn204.active = false; this.btn200.find('lock').active = false; this.btn201.find('lock').active = true; this.btn203.find('lock').active = false; this.btn204.find('lock').active = true; this.btn101.find('lock').active = false; } click_btn200(): void { this.showPage(UIID.Shop); } click_btn201(): void { this.showPage(UIID.Role); } click_btn101(): void { this.showPage(UIID.Home); } click_btn203(): void { this.showPage(UIID.Weapon); } click_btn204(): void { } }