UNPKG

olympus-r

Version:

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

293 lines (292 loc) 11.8 kB
import { listenApply } from '../../utils/ConstructUtil'; import Dictionary from "../../utils/Dictionary"; import { bindManager } from "../bind/BindManager"; var onOpenDict = new Dictionary(); export function listenOnOpen(prototype, before, after) { listenApply(prototype.constructor, "onOpen", function (mediator) { // 记录onOpen篡改次数 var count = onOpenDict.get(mediator) || 0; onOpenDict.set(mediator, count + 1); // 调用回调 before && before(mediator); }, function (mediator) { // 调用回调 after && after(mediator); // 递减篡改次数 var count = onOpenDict.get(mediator) - 1; onOpenDict.set(mediator, count); // 判断是否所有onOpen都调用完毕,如果完毕了,则启动编译过程 if (count <= 0) { // 移除数据 onOpenDict.delete(mediator); // 全调用完毕了,按层级顺序由浅入深编译 var bindTargets = mediator.bindTargets; for (var depth in bindTargets) { var dict = bindTargets[depth]; dict.forEach(function (currentTarget) { return compile(mediator, currentTarget); }); } } }); } /** * 获取显示对象在mediator.skin中的嵌套层级 * * @param {IMediator} mediator 中介者 * @param {*} target 目标显示对象 * @returns {number} */ function getDepth(mediator, target) { var skin = mediator.skin; var bridge = mediator.bridge; var depth = 0; if (bridge.isMySkin(target)) { while (target && target !== skin) { depth++; target = bridge.getParent(target); } // 如果显示对象是没有根的,或者不在skin的显示树中,则返回0 if (!target) depth = 0; } return depth; } export function searchUIDepth(values, mediator, target, callback, addressing) { if (addressing === void 0) { addressing = false; } // 获取显示层级 var depth = getDepth(mediator, target); // 如果有中断编译则将遍历的工作推迟到中断重启后,否则直接开始遍历 var stopLeftHandlers = target.__stop_left_handlers__; if (stopLeftHandlers) stopLeftHandlers.push(handler); else handler(target, mediator.bindTargets, stopLeftHandlers); function handler(target, bindTargets, leftHandlers) { var index = -1; if (leftHandlers) index = leftHandlers.indexOf(handler); // 遍历绑定的目标,将编译指令绑定到目标身上,而不是指令所在的显示对象身上 searchUI(values, target, function (currentTarget, name, exp, depth) { if (addressing) currentTarget = currentTarget[name]; // 记录当前编译目标和命令本体目标到bindTargets中 var dict = bindTargets[depth]; if (!dict) bindTargets[depth] = dict = new Dictionary(); dict.set(currentTarget, target); // 调用回调 callback(currentTarget, target, name, exp, leftHandlers, index); }, depth); } } function getBindParams(currentTarget) { var bindParams = currentTarget.__bind_commands__; if (!bindParams) { bindParams = []; Object.defineProperty(currentTarget, "__bind_commands__", { configurable: true, enumerable: false, writable: true, value: bindParams }); } return bindParams; } /** * 添加编译命令到显示对象上(正向) * * @export * @param {ICompileTarget} currentTarget 显示对象 * @param {*} target 编译命令本来所在的对象 * @param {IBindCommand} cmd 命令函数 * @param {...any[]} args 命令参数列表 */ export function pushCompileCommand(currentTarget, target, cmd) { var args = []; for (var _i = 3; _i < arguments.length; _i++) { args[_i - 3] = arguments[_i]; } // 添加编译指令 getBindParams(currentTarget).push({ cmd: cmd, target: target, args: args }); } /** * 添加编译命令到显示对象上(反向) * * @export * @param {ICompileTarget} currentTarget 显示对象 * @param {*} target 编译命令本来所在的对象 * @param {IBindCommand} cmd 命令函数 * @param {...any[]} args 命令参数列表 */ export function unshiftCompileCommand(currentTarget, target, cmd) { var args = []; for (var _i = 3; _i < arguments.length; _i++) { args[_i - 3] = arguments[_i]; } getBindParams(currentTarget).unshift({ cmd: cmd, target: target, args: args }); } /** * 编译显示对象,会先编译自身,然后再递归编译子对象 * * @export * @param {IMediator} mediator 显示对象所属的中介者 * @param {ICompileTarget} currentTarget 显示对象 * @param {any[]} [envModels] 环境变量数组 */ export function compile(mediator, currentTarget, envModels) { // 取到编译参数列表 var bindParams = currentTarget.__bind_commands__; // 编译currentTarget自身 if (bindParams) { // 这里没有提前读取出length属性,因为需要动态判断数组长度 for (var i = 0; i < bindParams.length;) { // 使用shift按顺序取出编译命令 var params = bindParams.shift(); // 调用编译命令,并且更新中止状态 params.cmd.apply(params, [mediator, currentTarget, params.target, envModels || []].concat(params.args)); } } } /** * 编译bindValue命令,不会中止编译 */ export function compileValue(mediator, currentTarget, target, envModels, name, exp) { bindManager.bindValue(mediator, currentTarget, target, envModels, name, exp); } /** * 编译bindExp命令,不会中止编译 */ export function compileExp(mediator, currentTarget, target, envModels, exp) { bindManager.bindExp(mediator, currentTarget, target, envModels, exp); } /** * 编译bindFunc命令,不会中止编译 */ export function compileFunc(mediator, currentTarget, target, envModels, name) { var argExps = []; for (var _i = 5; _i < arguments.length; _i++) { argExps[_i - 5] = arguments[_i]; } bindManager.bindFunc.apply(bindManager, [mediator, currentTarget, target, envModels, name].concat(argExps)); } /** * 编译bindOn命令,不会中止编译 */ export function compileOn(mediator, currentTarget, target, envModels, type, exp) { bindManager.bindOn(mediator, currentTarget, target, envModels, type, exp); } function isPosterity(mediator, target, parent) { var tempParent = mediator.bridge.getParent(target); if (!tempParent) return false; else if (tempParent === parent) return true; else return isPosterity(mediator, tempParent, parent); } function getAllSubTargets(mediator, target) { var bindTargets = mediator.bindTargets; var subTargets = []; for (var _i = 0, bindTargets_1 = bindTargets; _i < bindTargets_1.length; _i++) { var bindTarget = bindTargets_1[_i]; bindTarget && bindTarget.forEach(function (tempTarget) { if (isPosterity(mediator, tempTarget, target)) subTargets.push(tempTarget); }); } return subTargets; } /** * 编译bindIf命令,会中止编译,直到判断条件为true时才会启动以继续编译 */ export function compileIf(mediator, currentTarget, target, envModels, exp) { // 将后面的编译命令缓存起来 var bindParams = currentTarget.__bind_commands__; var caches = [{ target: currentTarget, params: bindParams.splice(0, bindParams.length) }]; // 后代节点的也要缓存住 var subTargets = getAllSubTargets(mediator, currentTarget); for (var _i = 0, subTargets_1 = subTargets; _i < subTargets_1.length; _i++) { var subTarget = subTargets_1[_i]; var subBindParams = subTarget.__bind_commands__; caches.push({ target: subTarget, params: subBindParams.splice(0, subBindParams.length) }); } // 绑定if命令 var terminated = false; bindManager.bindIf(mediator, currentTarget, target, envModels, exp, function (value) { // 如果条件为true,则启动继续编译,但只编译一次,编译过就不需要再编译了 if (!terminated && value) { // 恢复后面的命令 for (var _i = 0, caches_1 = caches; _i < caches_1.length; _i++) { var cache = caches_1[_i]; cache.target.__bind_commands__ = cache.params; // 继续编译 compile(mediator, cache.target, envModels); } // 设置已终结标识 terminated = true; } }); } /** * 编译bindFor命令,会中止编译,直到生成新的renderer实例时才会继续编译新实例 */ export function compileFor(mediator, currentTarget, target, envModels, name, exp, mediatorCls, declaredMediatorCls, dataExp) { // 将后面的编译命令缓存起来 var leftHandlers = target.__stop_left_handlers__; // 绑定for命令 bindManager.bindFor(mediator, currentTarget, target, envModels, name, exp, mediatorCls, declaredMediatorCls, dataExp, function (data, renderer, subEnvModels) { var subLeftHandlers = leftHandlers.concat(); var bindTargets = []; // 针对每一个renderer赋值后续编译指令 for (var _i = 0, subLeftHandlers_1 = subLeftHandlers; _i < subLeftHandlers_1.length; _i++) { var leftHandler = subLeftHandlers_1[_i]; leftHandler(renderer, bindTargets, subLeftHandlers); } // 编译renderer实例 for (var depth in bindTargets) { var dict = bindTargets[depth]; dict.forEach(function (currentTarget) { return compile(mediator, currentTarget, subEnvModels); }); } }); } /** * 编译bindMessage命令,不会中止编译 */ export function compileMessage(mediator, currentTarget, target, envModels, type, name, exp, observable) { bindManager.bindMessage(mediator, currentTarget, target, envModels, type, name, exp, observable); } /** * 编译bindResponse命令,不会中止编译 */ export function compileResponse(mediator, currentTarget, target, envModels, type, name, exp, observable) { bindManager.bindResponse(mediator, currentTarget, target, envModels, type, name, exp, observable); } /** * 搜索UI,取到目标节点,执行回调 * * @export * @param {*} values 值结构字典 * @param {*} ui ui实体 * @param {(ui:any, key:string, value:any, depth?:number)=>void} callback 回调 * @param {number} [depth=0] 遍历深度,方法会继续增加这个深度 */ export function searchUI(values, ui, callback, depth) { if (depth === void 0) { depth = 0; } for (var key in values) { var value = values[key]; var index = key.indexOf("."); if (index >= 0) { // 是表达式寻址,递归寻址 var newValue = {}; newValue[key.substr(index + 1)] = value; searchUI(newValue, ui[key.substring(0, index)], callback, depth + 1); } else if (typeof value == "object" && !(value instanceof Array)) { // 是子对象寻址,递归寻址 searchUI(value, ui[key], callback, depth + 1); } else { // 是表达式,调用回调,将调用层级也传递回去 callback(ui, key, value, depth); } } }