123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- import { Animation, Canvas, find, instantiate, Node, Prefab, Sprite, Widget } from 'cc';
- import { PREVIEW } from 'cc/env';
- import { FrameworkConf } from '../config/FrameworkConf';
- import { EventMgr } from '../event/EventManager';
- import { resLoader } from '../res/ResLoader';
- import { StringUtil } from '../util/StringUtil';
- import { TimeUtil } from '../util/TimeUtil';
- import { BaseView, UIShowType } from './BaseView';
- import { LayerConf, LayerInfo } from './LayerManager';
- import { UserData } from '../../game/data/UserData';
- import { Layer_Conf, ViewID } from '../config/LayerConf';
- export class BaseLayer extends Node {
- private _layer_queue: LayerInfo[] = []; //UI队列
- private _layer_conf: { [key: number]: LayerConf } = {}; //UI配置
- private _layer_opening: boolean = false; //是否正在打开UI
- private _layer_cache: LayerInfo[] = []; //UI缓存
- private _layer_manage = false; //是否启用层级管理
- private _bottom_layer = 0; //底层UI数量(通常位于UI栈底部,不受UI切换影响)
- constructor(name: string, conf: any, manage: boolean = false) {
- super(name);
- this._layer_conf = conf;
- let widget = this.addComponent(Widget);
- widget.isAlignLeft = widget.isAlignRight = widget.isAlignTop = widget.isAlignBottom = true;
- widget.left = widget.right = widget.top = widget.bottom = 0;
- widget.alignMode = 2;
- widget.enabled = true;
- this._layer_queue = [];
- this._layer_cache = [];
- this._layer_opening = false;
- this._layer_manage = manage;
- }
- /**
- * 打开UI
- * @param id UIID
- * @param args 打开UI的可传参数
- * @param callback UI打开成功过后的回调
- */
- open(id: number, callback: Function = null, args: any[]) {
- let conf = this._layer_conf[id];
- if (conf) {
- let info: LayerInfo = {
- id: id,
- args: args,
- view: null,
- res: null,
- callback: callback,
- active: true,
- bLoading: true
- };
- if (this._layer_opening) {
- //队列里不能有相同的UI
- for (let ui of this._layer_queue) {
- if (ui.id === id) {
- return false;
- }
- }
- //插入待打开队列
- this._layer_queue.push(info);
- return false;
- }
- //开同一UI 则刷新
- let curView = this.getUIView(id);
- if (curView) {
- //let conf = this._layer_conf[id];
- if (conf.reset) {
- console.log("页面存在,直接刷新")
- //传递自定义参数
- curView.onOpen(...info.args);
- //回调
- info.callback && info.callback();
- return true
- }
- else {
- console.log("页面存在,不刷新")
- return false;
- }
- }
- this._layer_opening = true;
- this._layer_cache.push(info);
- let __time = TimeUtil.getTime();
- let self = this
- /**
- * 加载失败
- * @param bRes 资源已加载
- */
- let funError = function (bRes) {
- if (bRes) {
- resLoader.release(conf.url, conf.bundle);
- }
- for (let i = self._layer_cache.length - 1; i >= 0; --i) {
- if (self._layer_cache[i] == info) {
- self._layer_cache.splice(i, 1);
- break;
- }
- }
- //处理待打开队列中的UI
- self._layer_opening = false;
- self._open_next();
- }
- //加载资源
- resLoader.load(conf.bundle, conf.url, Prefab, (error: Error, prefab: Prefab) => {
- if (error) {
- console.error("载入资源失败:" + conf.url);
- funError(false)
- return false
- } else {
- if (!info.bLoading) {
- console.error("资源已不需要了:" + conf.url);
- funError(true)
- return false
- }
- info.bLoading = false;
- (!conf.cache) && (info.res = prefab);
- let node = instantiate(prefab);
- node.active = true;
- console.log(`复制预制体:${conf.url}`)
- if (!node) {
- console.error("初始化Node失败");
- funError(true)
- return false;
- }
- let view = node.getComponent(BaseView);
- if (!view) {
- console.error("UI未找到UIView组件");
- funError(true)
- return false;
- }
- prefab.addRef();
- view.enabled = true;
- info.view = view;
- view.view_id = id;
- this.addChild(node);
- //统计底层UI数量
- (conf.bottom) && ++this._bottom_layer;
- this._play_anim(id, node, "open", () => {
- //刷新UI
- this._updateUI();
- //传递自定义参数
- view.onOpen(...info.args);
- //发送打开事件
- EventMgr.fireEvent(FrameworkConf.Event.OPEND_UI, info.id);
- //回调
- info.callback && info.callback();
- //处理待打开队列中的UI
- this._layer_opening = false;
- this._open_next();
- });
- (PREVIEW) && console.log(StringUtil.format("UI[{0}]加载耗时:{1}毫秒", ViewID[info.id], TimeUtil.getTime() - __time));
- }
- });
- return true;
- }
- return false;
- }
- private _open_next() {
- let info = this._layer_queue.shift();
- info && this.open(info.id, info.callback, info.args);
- }
- private _play_anim(id: number, node: Node, name: string, callback: Function,) {
- //是否播放动画
- let conf = this._layer_conf[id];
- if (conf.anim) {
- let anim = node.getComponent(Animation);
- if (anim) {
- anim.on(Animation.EventType.FINISHED, () => {
- callback && callback();
- callback = null;
- }, this);
- let animName = "";
- if (conf.anim == 1) {
- animName = "ui_" + name;
- } else if (conf.anim == 2) {
- animName = "tips_" + name;
- }
- anim.play(animName);
- return;
- }
- else{
- console.error("ui:" + id + "缺少Animation组件");
- callback && callback();
- }
- } else {
- callback && callback();
- callback = null;
- }
- }
- private _updateUI() {
- if (this._layer_manage) {
- let show_idx = this._layer_cache.length - 1, hide_idx = 0;;
- for (; show_idx >= 0; --show_idx) {
- if (this._layer_cache[show_idx].active) {
- this._layer_cache[show_idx].view?.onShow();
- let mode = this._layer_cache[show_idx].view?.show_type;
- if (mode == UIShowType.Single) {
- for (let i = 0; i < this._bottom_layer; ++i) {
- this._layer_cache[i] && this._layer_cache[i].view?.onShow();
- }
- hide_idx = this._bottom_layer;
- break;
- } else if (mode == UIShowType.FullScreen) {
- break;
- }
- }
- }
- for (let i = hide_idx; i < show_idx; ++i) {
- this._layer_cache[i].view?.onHide();
- }
- let find = false;
- for (let cache of this._layer_cache) {
- if (cache.active) {
- if (cache.view?.show_type == UIShowType.FullScreen) {
- find = true;
- //如果有全屏隐藏底层UI
- for (let i = 0; i < this._bottom_layer; ++i) {
- this._layer_cache[i] && this._layer_cache[i].view?.onHide();
- }
- break;
- }
- }
- }
- EventMgr.fireEvent("_Framewrok_Show_GameLayer", !find);
- }
- }
- /**
- * 关闭UI
- * @param ui 该值可为UIID也可为this
- */
- close(ui: number | BaseView) {
- let view = (typeof ui === "number") ? this.getUIView(ui) : ui;
- if (view) {
- let info: LayerInfo = null;
- for (let i = 0; i < this._layer_cache.length; ++i) {
- info = this._layer_cache[i];
- if (info.view == view) {
- this._layer_cache.splice(i, 1);
- //刷新UI
- let pre_info = (this._layer_cache.length >= 1) ? this._layer_cache[this._layer_cache.length - 1] : null;
- if (pre_info) {
- if (!pre_info.active) {
- pre_info = (this._layer_cache.length >= 2) ? this._layer_cache[this._layer_cache.length - 2] : null;
- }
- }
- this._updateUI();
- this._play_anim(info.view.view_id, info.view.node, "close", () => {
- //显示最后一个UI
- if (pre_info && pre_info.view) {
- pre_info.view.onShow();
- }
- this._clearUI(info);
- });
- break;
- }
- }
- }
- else {
- let info: LayerInfo = null;
- for (let i = 0; i < this._layer_cache.length; ++i) {
- info = this._layer_cache[i];
- if (info.id == ui) {
- info.bLoading = false;
- console.log("closeUI with out view:", info.id);
- }
- }
- }
- }
- ShowUI(UI, state, callback: Function = null, args: any[]) {
- let nohave = true;
- let exist = []
- for (let i in this._layer_cache) {
- if (this._layer_cache[i].id === UI) {
- nohave = false
- if (this._layer_cache[i] && this._layer_cache[i].view) {
- if (state) {
- for (let existUI of exist) {
- existUI.view.onHide();
- }
- this._layer_cache[i].view.onShow();
- this._layer_cache[i].active = true;
- } else {
- for (let existUI of exist) {
- existUI.view.onShow();
- }
- this._layer_cache[i].view.onHide();
- this._layer_cache[i].active = false;
- }
- callback && callback();
- }
- return;
- }
- exist.push(this._layer_cache[i])
- }
- if (nohave) {
- this.open(UI, callback, args);
- }
- }
- /**
- * 获取UI对应的UIView
- * @param id UIID
- */
- getUIView(id: number) {
- for (let ui of this._layer_cache) {
- if (ui.id === id) {
- if (ui.active) {
- return ui.view;
- }
- }
- }
- return null;
- }
- /**
- * 关闭当前层的所有UI
- */
- closeAll(withoutID: number = -1) {
- for (let index = this._layer_cache.length - 1; index >= 0; index--) {
- let info = this._layer_cache[index];
- if (info.id !== withoutID) {
- this.close(info.id);
- let conf = this._layer_conf[info.id];
- (!conf.special) && this._clearUI(info);
- }
- }
- this._layer_queue = [];
- }
- private _clearUI(info: LayerInfo) {
- if (info && info.view) {
- let conf = this._layer_conf[info.id];
- (conf && conf.bottom) && --this._bottom_layer;
- info.view.onClose();
- //发送打开事件
- EventMgr.fireEvent(FrameworkConf.Event.CLOSE_UI, info.id);
- info.view.unscheduleAllCallbacks();
- info.view.node.removeFromParent();
- info.view.release();
- EventMgr.removeEvent(info.view);
- info.view.node.destroyAllChildren();
- info.view.node.destroy();
- info.res && (info.res.decRef());
- info.res = null;
- info.view = null;
- info = null;
- }
- }
- showLayerUI(show: boolean) {
- for (let cache of this._layer_cache) {
- if (show) {
- cache.active && cache.view?.onShow();
- } else {
- cache.view?.onHide();
- }
- }
- }
- }
|