123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- import { StringMap } from "../../Collections/StringMap";
- import Config from "../../Config";
- import { gameMethod } from "../../common/gameMethod";
- import GameDataCenter from "../../data/GameDataCenter";
- import { GUIEvent } from "../../data/const/EventConst";
- import { PlatFormDevType } from "../../data/const/TypeConst";
- import { ViewZOrder } from "../../data/const/ViewZOrder";
- import EventMng from "../../manager/EventMng";
- import { Singleton } from "../../manager/Singleton";
- import { PromiseDefault } from "../Promise/SpecialPromise";
- import { ResCollector } from "../compment/ResCollector";
- import { ResKeeper } from "../compment/ResKeeper";
- import FguiLoadMgr from "./FguiLoadMgr";
- import { IDisposable } from "./Interface/IDisposable";
- import { ILateUpdate } from "./Interface/ILateUpdate";
- import { IUpdate } from "./Interface/IUpdate";
- import { FguiClass, FguiView, ViewType } from "./mvc/FguiView";
- export default class FguiMgr extends Singleton<FguiMgr>() implements IUpdate, ILateUpdate, IDisposable {
- /** 记录图层节点的Map */
- private _layerNodeMap: Map<ViewZOrder, fgui.GComponent> = new Map();
- /** 已开启过的ui */
- private _opened: StringMap<FguiView> = new StringMap<FguiView>();
- /** 缓存被关闭的ui */
- private _closed: StringMap<FguiView> = new StringMap<FguiView>();
- /** 记录所加载的包 */
- private _addPkged: StringMap<number> = new StringMap<number>();
- Init(): void {
- fgui.GRoot.create();
- fgui.GRoot.inst.width = Config.safeAreaRect.width
- fgui.GRoot.inst.height = Config.realHeight
- fgui.GRoot.inst.node.y = Config.realHeight + Config.safeAreaRect.y / 2
- this._layerNodeMap = new Map();
- // 创建所有UI层级
- Object.values(ViewZOrder).forEach((layer) => {
- if (typeof layer === 'number') {
- const layerName = ViewZOrder[layer];
- this.createLayer(layerName + 'Layer', layer);
- }
- });
- }
- private createLayer(name: string, zOrder: number): fgui.GComponent {
- const layer = new fgui.GComponent();
- layer.name = name;
- layer.node.name = name;
- layer.sortingOrder = zOrder;
- fgui.GRoot.inst.addChild(layer);
- layer.makeFullScreen();
- this._layerNodeMap.set(zOrder, layer);
- return layer;
- }
- /**
- * @param callback 打开完毕回调函数
- * @param intent 传入到UI的参数
- */
- public openUI<T extends FguiView>(uiClass: FguiClass<T>, zOrder: number = ViewZOrder.UI, callback?: Function, intent?: any): Promise<void> {
- if (CC_PREVIEW) console.log(`打开页面${uiClass.getViewName()}`);
- const viewKey = uiClass.getViewName();
- if (this._opened.ContainsKey(viewKey)) {
- console.log(`FguiMgr::Open ${viewKey} has already opened.`);
- return;
- }
- if (this.getCacheView(uiClass, zOrder, callback)) {
- return;
- }
- let pkgName = uiClass.getPkgName();
- EventMng.emit(GUIEvent.SHOW_MASK, pkgName, true);
- if (fgui.UIPackage.getByName(pkgName) == null) {
- // 加载uipackage
- FguiLoadMgr.loadPackage(pkgName, pkgName, async (error, pkg) => {
- if (error) {
- EventMng.emit(GUIEvent.SHOW_MASK, pkgName, false)
- console.error(`FguiMgr LoadPackage[${pkgName}] error: ${error}`);
- return;
- }
- this.CreateView(uiClass, zOrder, intent, callback);
- });
- }
- else {
- this.CreateView(uiClass, zOrder, intent, callback);
- }
- }
- /** 从缓存中加载页面 */
- private getCacheView<T extends FguiView>(uiClass: FguiClass<T>, zOrder: number = ViewZOrder.UI, callback?: Function, intent?: any): boolean {
- const viewKey = uiClass.getViewName();
- if (this._closed.ContainsKey(viewKey)) {
- const uiview = this._closed.Value(viewKey);
- if (uiview.viewType == ViewType.Full) {
- this._opened.Foreach((key: string, value: FguiView) => {
- if (value.viewType != ViewType.Part && value.zOrder <= uiview.zOrder) {
- value.addFullHideCount(1);
- }
- })
- }
- this._closed.Remove(viewKey);
- this._opened.Add(viewKey, uiview);
- this.AddPanel(uiview.Panel, zOrder);
- uiview.show(intent);
- uiview.zOrder = zOrder;
- uiview.uiPkgName = uiClass.getPkgName();
- //回调
- callback && callback(uiview);
- return true;
- }
- return false;
- }
- private CreateView<T extends FguiView>(uiClass: FguiClass<T>, zOrder: number = ViewZOrder.UI, intent?: any, complete?: Function) {
- let handler = new fgui.AsyncOperation();
- handler.callback = async (gObject) => {
- if (this._opened.ContainsKey(uiClass.getViewName())) {
- EventMng.emit(GUIEvent.SHOW_MASK, uiClass.getPkgName(), false)
- console.error(`FguiMgr::Open ${uiClass.getViewName()} has already opened.`);
- return;
- }
- let panel = gObject as fgui.GComponent;
- if (panel == null) {
- EventMng.emit(GUIEvent.SHOW_MASK, uiClass.getPkgName(), false)
- console.error(`FguiMgr createObject[${uiClass.getViewName}] error: GObject为空.`);
- return;
- }
- panel.node.name = uiClass.getPrefabName();
- let uiview = new uiClass();
- uiview.zOrder = zOrder;
- uiview.uiPkgName = uiClass.getPkgName();
- uiview.initForward(panel, null);
- const resKeeper = ResKeeper.Get(panel.node, true);
- let resCollector = new ResCollector();
- uiview.Controller.onCollectRes(resCollector, intent);
- if (resCollector.GetResList().length > 0) {
- await resKeeper.LoadResCollector(resCollector, PromiseDefault);
- }
- if (uiview.viewType == ViewType.Full) {
- this._opened.Foreach((key: string, value: FguiView) => {
- if (value.viewType != ViewType.Part && value.zOrder <= uiview.zOrder) {
- value.addFullHideCount(1);
- }
- })
- }
- this._opened.Add(uiClass.getViewName(), uiview);
- uiview.init();
- this.AddPanel(panel, zOrder);
- uiview.show(intent);
- this.AddPkgCount(uiClass.getPkgName(), uiClass.getViewName());
- EventMng.emit(GUIEvent.SHOW_MASK, uiClass.getPkgName(), false)
- complete && complete(uiview);
- };
- handler.createObject(uiClass.getPkgName(), uiClass.getPrefabName());
- }
- /**
- * @param isDispose 是否销毁
- */
- public closeUI<T extends FguiView>(uiClass: FguiClass<T>, isDispose: boolean = false) {
- const viewKey = uiClass.getViewName();
- if (this._opened.ContainsKey(viewKey)) {
- const view = this._opened.Value(viewKey);
- this._opened.Remove(viewKey);
- view.hide(isDispose);
- this.RemovePanel(view.Panel);
- if (isDispose) {
- this.DestroyView(view, uiClass);
- }
- else {
- this._closed.Add(viewKey, view);
- }
- if (view.viewType == ViewType.Full) {
- this._opened.Foreach((key: string, value: FguiView) => {
- if (value.viewType != ViewType.Part && value.zOrder <= view.zOrder) {
- value.addFullHideCount(-1);
- }
- })
- }
- }
- else if (isDispose && this._closed.ContainsKey(viewKey)) {
- const view = this._closed.Value(viewKey);
- this._closed.Remove(viewKey);
- this.DestroyView(view, uiClass);
- }
- }
- // 判断界面是否打开
- public isShowing<T extends FguiView>(uiClass: FguiClass<T>) {
- const viewKey = uiClass?.getViewName();
- if (this._opened.ContainsKey(viewKey)) {
- return true
- }
- return false
- }
- // 获取打开的界面
- public getShowingView<T extends FguiView>(uiClass: FguiClass<T>) {
- const viewKey = uiClass?.getViewName();
- if (this._opened.ContainsKey(viewKey)) {
- const view = this._opened.Value(viewKey);
- return view
- }
- return null
- }
- /**
- * 当前是否有除了指定页面以外的其他页面被打开
- */
- public checkOtherUIOpen(uilist: FguiClass<any>[]) {
- let list = []
- for (let i of uilist) {
- list.push(i.getViewName())
- }
- let haveother: boolean = false
- this._opened.Foreach((key: string, value: FguiView) => {
- if (list.indexOf(key) < 0) {
- haveother = true
- }
- })
- return haveother
- }
- public isShowingByName(uiViewName: string) {
- return this._opened.ContainsKey(uiViewName);
- }
- // 获取打开的界面
- public getShowingViewByName(uiViewName: string) {
- if (this._opened.ContainsKey(uiViewName)) {
- const view = this._opened.Value(uiViewName);
- return view
- }
- return null
- }
- public findNodeByName(uiViewName: string, goName: string): cc.Node {
- if (this._opened.ContainsKey(uiViewName)) {
- let view = this._opened.Value(uiViewName);
- let goNames = goName.split("/")
- let go = null
- let goTemp = view["_viewModel"][goNames[0]];
- if (gameMethod.isEmpty(goTemp)) {
- goTemp = view.Panel.getChild(goNames[0]);
- }
- for (let i = 1; i < goNames.length; i++) {
- if (goTemp?.Panel) {
- goTemp = goTemp.Panel?.getChild(goNames[i])
- } else {
- goTemp = goTemp?.getChild(goNames[i]);
- }
- }
- go = goTemp
- if (!gameMethod.isEmpty(go)) {
- go.visible = true
- } else {
- console.error(`界面:${uiViewName} 找不到目标节点: ${goNames}`)
- }
- return go?.node ?? null;
- }
- return null;
- }
- public removePkg<T extends FguiView>(uiClass: FguiClass<T>) {
- if (!this._addPkged.ContainsKey(uiClass.getPkgName()) || this._addPkged.Value(uiClass.getPkgName()) == 0) {
- fgui.UIPackage.removePackage(uiClass.getPkgName())
- } else {
- console.warn("removePkg fail")
- }
- }
- public clearOpenUI() {
- this._opened.Foreach((viewKey: string, value: FguiView) => {
- value.hide();
- this.RemovePanel(value.Panel);
- this._closed.Add(viewKey, value);
- })
- this._opened.Clear()
- }
- public clearAllUI() {
- this._opened.Foreach((viewKey: string, value: FguiView) => {
- value.hide();
- this.RemovePanel(value.Panel);
- })
- this.clearCacheMap()
- // this._addPkged.Foreach((pkgName: string, value: number) => {
- // fgui.UIPackage.removePackage(pkgName)
- // })
- this._addPkged.Clear();
- }
- public clearCacheMap() {
- this._opened.Clear()
- this._closed.Clear()
- }
- OnUpdate(elapseTime: number): void {
- this._opened.Foreach((k, v) => {
- v.OnUpdate(elapseTime);
- }, this);
- }
- OnLateUpdate(elapseTime: number): void {
- this._opened.Foreach((k, v) => {
- v.OnLateUpdate(elapseTime);
- }, this);
- }
- Dispose(): void {
- //TODO 有需要再补充
- }
- /** 增加fgui pkg计数 */
- public AddPkgCount(pkgName: string, from?: string) {
- if (this._addPkged.ContainsKey(pkgName)) {
- //已存在++
- let pkgCount = this._addPkged.Value(pkgName);
- pkgCount++;
- this._addPkged.Replace(pkgName, pkgCount)
- } else {
- this._addPkged.Add(pkgName, 1)
- }
- if (!gameMethod.isEmpty(GameDataCenter?.login.playerInfo?.switch?.clientLog)) {
- console.log(`${from} ${pkgName} count: ${this._addPkged.Value(pkgName)}`)
- }
- }
- /** 减少fgui pkg计数 */
- public DelPkgCount(pkgName: string, from?: string) {
- if (this._addPkged.ContainsKey(pkgName)) {
- //已存在++
- let pkgCount = this._addPkged.Value(pkgName);
- pkgCount--;
- if (!gameMethod.isEmpty(GameDataCenter?.login.playerInfo?.switch?.clientLog)) {
- console.log(`${pkgName} count: ${pkgCount}`, from)
- }
- this._addPkged.Replace(pkgName, pkgCount);
- if (pkgCount <= 0 && pkgName != "Common") {
- if (!gameMethod.isEmpty(GameDataCenter?.login.playerInfo?.switch?.clientLog)) {
- console.log(`removePackage:${pkgName}`, from)
- }
- fgui.UIPackage.removePackage(pkgName)
- }
- }
- }
- AddPkgByPkgName(pkgName: string, cb?: Function) {
- if (fgui.UIPackage.getByName(pkgName) == null) {
- // 加载uipackage
- FguiLoadMgr.loadPackage(pkgName, pkgName, (error, pkg) => {
- if (error) {
- EventMng.emit(GUIEvent.SHOW_MASK, pkgName, false)
- console.error(`FguiMgr LoadPackage[${pkgName}] error: ${error}`);
- return;
- }
- this.AddPkgCount(pkgName);
- if (!gameMethod.isEmpty(GameDataCenter?.login.playerInfo?.switch?.clientLog)) {
- console.log(`${pkgName} count: ${this._addPkged.Value(pkgName)}`)
- }
- cb && cb();
- });
- } else {
- this.AddPkgCount(pkgName);
- if (!gameMethod.isEmpty(GameDataCenter?.login.playerInfo?.switch?.clientLog)) {
- console.log(`${pkgName} count: ${this._addPkged.Value(pkgName)}`)
- }
- cb && cb();
- }
- }
- RemovePkgByPkgName(pkgName: string) {
- //ios平台才释放,安卓平台不释放
- if (GameDataCenter.plat.instance.deviceOS != PlatFormDevType.iosH5 && GameDataCenter.plat.instance.deviceOS != PlatFormDevType.ios && GameDataCenter.plat.instance.deviceOS != PlatFormDevType.local) {
- return;
- }
- this.DelPkgCount(pkgName);
- }
- private AddPanel(panel: fgui.GComponent, zOrder: ViewZOrder) {
- const layerNode = this._layerNodeMap.get(zOrder);
- if (layerNode) {
- layerNode.addChild(panel);
- } else {
- fgui.GRoot.inst.addChild(panel);
- }
- // UI全屏自适应
- panel.makeFullScreen();
- }
- private RemovePanel(panel: fgui.GComponent) {
- fgui.GRoot.inst.removeChild(panel);
- }
- private DestroyView<T extends FguiView>(uiview: FguiView, uiClass: FguiClass<T>) {
- //ios平台才释放,安卓平台不释放
- if (GameDataCenter.plat.instance.deviceOS != PlatFormDevType.iosH5 && GameDataCenter.plat.instance.deviceOS != PlatFormDevType.ios && GameDataCenter.plat.instance.deviceOS != PlatFormDevType.local) {
- return;
- }
- var panel = uiview.Panel;
- panel.dispose();
- this.DelPkgCount(uiClass.getPkgName());
- }
- public CloseUIByLayer(zOrder: ViewZOrder) {
- this._opened.Foreach((viewKey: string, value: FguiView) => {
- if (value.zOrder == zOrder) {
- const view = this._opened.Value(viewKey);
- this._opened.Remove(viewKey);
- view.hide();
- this.RemovePanel(view.Panel);
- this._closed.Add(viewKey, view);
- if (view.viewType == ViewType.Full) {
- this._opened.Foreach((key: string, value: FguiView) => {
- if (value.viewType != ViewType.Part && value.zOrder <= view.zOrder) {
- value.addFullHideCount(-1);
- }
- })
- }
- }
- })
- }
- /** 关闭所有的UI elseView 排除无需关闭的界面 */
- public CloseAllUI(elseView: string[] = []): void {
- this._opened.Foreach((viewKey: string, value: FguiView) => {
- if (elseView.indexOf(viewKey) < 0) {
- const view = this._opened.Value(viewKey);
- this._opened.Remove(viewKey);
- view.hide();
- this.RemovePanel(view.Panel);
- this._closed.Add(viewKey, view);
- if (view.viewType == ViewType.Full) {
- this._opened.Foreach((key: string, value: FguiView) => {
- if (value.viewType != ViewType.Part && value.zOrder <= view.zOrder) {
- value.addFullHideCount(-1);
- }
- })
- }
- }
- })
- }
- //#endregion
- }
|