UNPKG

olympus-r

Version:

一个力求简单易用的前端开发框架 #### 开发语言 TypeScript #### 核心架构 MVC #### 模块间通讯和解耦 采用事件机制,利用一个全局唯一的事件派发器进行模块间通讯,解耦模块间依赖 #### 表现层结构 使用桥接模式拆分接口与实现,达到一套核心驱动多套表现层的目的(目前支持DOM、Egret、PixiJS三种表现层),同时支持表现层的未来可扩展性 #### TypeScript装饰器注入 框架提供TypeScript装饰器注入功能,便捷获取托管对象。例如:

371 lines (370 loc) 17.4 kB
import * as tslib_1 from "tslib"; import { core } from "../../core/Core"; import { Injectable } from "../../core/injector/Injector"; import { getConstructor } from "../../utils/ConstructUtil"; import { ModuleOpenStatus } from "../mediator/IMediatorModulePart"; import { getModule } from "../mediator/Mediator"; import ModuleMessage from "./ModuleMessage"; /** * @author Raykid * @email initial_r@qq.com * @create date 2017-09-14 * @modify date 2017-09-15 * * 模块管理器,管理模块相关的所有操作。模块具有唯一性,同一时间不可以打开两个相同模块,如果打开则会退回到先前的模块处 */ var ModuleManager = /** @class */ (function () { function ModuleManager() { this._moduleStack = []; this._openCache = []; this._opening = null; this._busy = false; } Object.defineProperty(ModuleManager.prototype, "currentModule", { /** * 获取当前模块 * * @readonly * @type {IMediatorConstructor|undefined} * @memberof ModuleManager */ get: function () { var curData = this.getCurrent(); return (curData && curData[0]); }, enumerable: true, configurable: true }); Object.defineProperty(ModuleManager.prototype, "currentModuleInstance", { /** * 获取当前模块的实例 * * @readonly * @type {(IMediator|undefined)} * @memberof ModuleManager */ get: function () { var curData = this.getCurrent(); return (curData && curData[1]); }, enumerable: true, configurable: true }); Object.defineProperty(ModuleManager.prototype, "activeCount", { /** * 获取活动模块数量 * * @readonly * @type {number} * @memberof ModuleManager */ get: function () { return this._moduleStack.length; }, enumerable: true, configurable: true }); /** * 获取模块在栈中的索引 * * @param {IMediatorConstructor} cls 模块类型 * @returns {number} 索引值 * @memberof ModuleManager */ ModuleManager.prototype.getIndex = function (cls) { for (var i = 0, len = this._moduleStack.length; i < len; i++) { if (this._moduleStack[i][0] == cls) return i; } return -1; }; /** * 获取索引处模块类型 * * @param {number} index 模块索引值 * @returns {IMediatorConstructor} 模块类型 * @memberof ModuleManager */ ModuleManager.prototype.getModule = function (index) { var data = this._moduleStack[index]; return data && data[0]; }; ModuleManager.prototype.getAfter = function (cls) { var result = []; for (var _i = 0, _a = this._moduleStack; _i < _a.length; _i++) { var module = _a[_i]; if (module[0] == cls) return result; result.push(module); } return null; }; ModuleManager.prototype.getCurrent = function () { // 按顺序遍历模块,取出最新的没有在开启中的模块 var target; for (var _i = 0, _a = this._moduleStack; _i < _a.length; _i++) { var temp = _a[_i]; if (temp[0] !== this._opening) { target = temp; break; } } return target; }; /** * 获取模块是否开启中 * * @param {IMediatorConstructor} cls 要判断的模块类型 * @returns {boolean} 是否开启 * @memberof ModuleManager */ ModuleManager.prototype.isOpened = function (cls) { return (this._moduleStack.filter(function (temp) { return temp[0] == cls; }).length > 0); }; ModuleManager.prototype.activateModule = function (module, from, data) { if (module) { // 调用activate接口 module.activate(from, data); } }; ModuleManager.prototype.deactivateModule = function (module, to, data) { if (module) { // 调用deactivate接口 module.deactivate(to, data); } }; /** * 打开模块 * * @param {ModuleType|string} clsOrName 模块类型或名称 * @param {*} [data] 参数 * @param {boolean} [replace=false] 是否替换当前模块 * @returns {Promise<IMediator>} 开启成功后返回被开启模块引用 * @memberof ModuleManager */ ModuleManager.prototype.open = function (module, data, replace) { var _this = this; if (replace === void 0) { replace = false; } return new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var type, cls, after, target, from, fromModule, moduleData, i, len; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: type = (typeof module == "string" ? getModule(module) : module); // 非空判断 if (!type) return [2 /*return*/]; // 判断是否正在打开模块 if (this._busy) { this._openCache.push([type, data, replace, resolve]); return [2 /*return*/]; } this._busy = true; cls = getConstructor(type instanceof Function ? type : type.constructor); after = this.getAfter(cls); if (!!after) return [3 /*break*/, 2]; // 记录正在打开的模块类型 this._opening = type; target = type instanceof Function ? new cls() : type; // 赋值打开参数 target.data = data; from = this.getCurrent(); fromModule = from && from[1]; moduleData = [cls, target, null]; this._moduleStack.unshift(moduleData); // 设置回调 target.moduleOpenHandler = function (status, err) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a, tempData; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: _a = status; switch (_a) { case ModuleOpenStatus.Stop: return [3 /*break*/, 1]; case ModuleOpenStatus.BeforeOpen: return [3 /*break*/, 3]; case ModuleOpenStatus.AfterOpen: return [3 /*break*/, 4]; } return [3 /*break*/, 6]; case 1: // 需要判断是否是最后一个模块,最后一个模块不允许被销毁 if (this._moduleStack.length > 1) { tempData = this._moduleStack.shift(); // 销毁模块 tempData[1].dispose(); } // 派发失败消息 core.dispatch(ModuleMessage.MODULE_CHANGE_FAILED, cls, from && from[0], err); // 结束一次模块开启 return [4 /*yield*/, this.onFinishOpen()]; case 2: // 结束一次模块开启 _b.sent(); return [3 /*break*/, 6]; case 3: // 这里要优先关闭标识符,否则在开启的模块的onOpen方法里如果有操作Mask的动作就会被这个标识阻塞住 this._opening = null; // 篡改target的close方法,使其改为触发ModuleManager的close moduleData[2] = target.hasOwnProperty("close") ? target.close : null; target.close = function (data) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, moduleManager.close(target, data)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; return [3 /*break*/, 6]; case 4: // 调用onDeactivate接口 this.deactivateModule(fromModule, target, data); // 调用onActivate接口 this.activateModule(target, fromModule, data); // 如果replace是true,则关掉上一个模块 if (replace) this.close(from && from[0], data); // 派发消息 core.dispatch(ModuleMessage.MODULE_CHANGE, cls, fromModule); // 结束一次模块开启 return [4 /*yield*/, this.onFinishOpen()]; case 5: // 结束一次模块开启 _b.sent(); return [3 /*break*/, 6]; case 6: return [2 /*return*/]; } }); }); }; // 调用open接口 return [4 /*yield*/, target.open(data)]; case 1: // 调用open接口 _a.sent(); // 调用resolve resolve(target); return [3 /*break*/, 6]; case 2: if (!(after.length > 0)) return [3 /*break*/, 4]; // 已经打开且不是当前模块,先关闭当前模块到目标模块之间的所有模块 for (i = 1, len = after.length; i < len; i++) { this.close(after[i][0], data); } // 最后关闭当前模块,以实现从当前模块直接跳回到目标模块 return [4 /*yield*/, this.close(after[0][0], data)]; case 3: // 最后关闭当前模块,以实现从当前模块直接跳回到目标模块 _a.sent(); _a.label = 4; case 4: // 结束一次模块开启 return [4 /*yield*/, this.onFinishOpen()]; case 5: // 结束一次模块开启 _a.sent(); // 调用resolve,返回当前模块 resolve(this._moduleStack[0][1]); _a.label = 6; case 6: return [2 /*return*/]; } }); }); }); }; ModuleManager.prototype.onFinishOpen = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var openCache, openData; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: // 关闭标识符 this._opening = null; this._busy = false; if (!(this._openCache.length > 0)) return [3 /*break*/, 2]; openCache = this._openCache.shift(); return [4 /*yield*/, this.open.apply(this, openCache.slice(0, 3))]; case 1: openData = _a.sent(); openCache[3](openData); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; /** * 关闭模块,只有关闭的是当前模块时才会触发onDeactivate和onActivate,否则只会触发close * * @param {ModuleType|string} clsOrName 模块类型或名称 * @param {*} [data] 参数 * @returns {Promise<IMediator>} 关闭成功后返回被关闭的模块引用 * @memberof ModuleManager */ ModuleManager.prototype.close = function (module, data) { var _this = this; return new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var type, cls, index, moduleData, target, oriClose, to, toModule; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: type = (typeof module == "string" ? getModule(module) : module); // 非空判断 if (!type) return [2 /*return*/]; // 数量判断,不足一个模块时不关闭 if (this.activeCount <= 1) return [2 /*return*/]; cls = getConstructor(type instanceof Function ? type : type.constructor); index = this.getIndex(cls); if (index < 0) return [2 /*return*/]; moduleData = this._moduleStack[index]; target = moduleData[1]; oriClose = moduleData[2]; if (oriClose) target.close = oriClose; else delete target.close; if (!(index == 0)) return [3 /*break*/, 2]; // 数据先行 this._moduleStack.shift(); to = this._moduleStack[0]; toModule = to && to[1]; // 调用onDeactivate接口 this.deactivateModule(target, toModule, data); // 调用close接口 return [4 /*yield*/, target.close(data)]; case 1: // 调用close接口 _a.sent(); // 调用onActivate接口 this.activateModule(toModule, target, data); // 调用onWakeUp接口 toModule.wakeUp(target, data); // 派发消息 core.dispatch(ModuleMessage.MODULE_CHANGE, to && to[0], cls); return [3 /*break*/, 4]; case 2: // 数据先行 this._moduleStack.splice(index, 1); // 调用close接口 return [4 /*yield*/, target.close(data)]; case 3: // 调用close接口 _a.sent(); _a.label = 4; case 4: resolve(target); return [2 /*return*/]; } }); }); }); }; ModuleManager = tslib_1.__decorate([ Injectable ], ModuleManager); return ModuleManager; }()); export default ModuleManager; /** 再额外导出一个单例 */ export var moduleManager = core.getInject(ModuleManager);