UNPKG

mm_os

Version:

这是超级美眉服务端框架,用于快速构建应用程序。

477 lines (458 loc) 9.58 kB
const { types } = require("util"); class Eventer { /** * 构造函数 * @param {Object} config 配置参数 */ constructor(config) { this.dict = {}; this.list_add = []; this.list_del = []; // 模式,0为执行完不重载程序,1为执行完后重载程序。 this.mode = 0; // 自增ID,用于添加事件处理程序后可控更新和卸载。 this.autoId = 1; } } /** * 事件模型 * @param {String|Number} id ID,用于标识查找事件,方便调用、更替和删除 */ Eventer.prototype.model = function(id = "") { if (!id) { id = this.autoId; this.autoId++; } return { // 事件ID id, // 消息类型 type: "发动攻击时", // 时态 tense: "main", // 总执行次数 -1为无限次 count: 0, // 执行次数 num: 0, // 状态 1启用,2暂停,0结束 state: 1, // 参数 param: {}, // 回调函数 func: function() {} } } /** * 添加事件 * @param {String} type 事件类型 * @param {Function} func 回调函数 * @param {Object} param 回调附加参数 * @param {String} tense 时态 before执行前|check确认是否执行|main执行|after执行后 * @param {Number} count 执行次数 * @param {String|Number} id ID,用于标识查找事件,方便调用、更替和删除 */ Eventer.prototype.add = function(type, func, param, tense, count = -1, id = "") { var info; if (typeof(type) === "object") { info = type; if (!info.id) { if (!id) { id = this.autoId; this.autoId++; } info.id = id; } } else { if (!id) { id = this.autoId; this.autoId++; } info = { id, type, tense: tense || "main", num: 0, state: 1, count, param, func }; } this.list_add.push(info); return id; } /** * 执行全部事件前 */ Eventer.prototype.do_before = function() { // 追加事件 var list = this.list_add; for (var i = 0; i < list.length; i++) { var o = list[i]; var dt = this.dict[o.type]; if (!dt) { this.dict[o.type] = { before: [], check: [], main: [], after: [] }; dt = this.dict[o.type]; } var lt = dt[o.tense]; if (lt) { lt.add(o); } } this.list_add.clear(); // 移除事件 var list = this.list_del; for (var i = 0; i < list.length; i++) { var o = list[i]; var dt = this.dict[o.type]; if (dt) { var lt = dt[o.tense]; if (lt) { lt.del({ id: o.id }); } if (!dt.before.length && !dt.check.length && !dt.main.length && !dt.after.length) { delete this.dict[o.type]; } } } this.list_del.clear(); } /** * 执行全部事件后 */ Eventer.prototype.do_after = function() { } /** * 执行事件 */ Eventer.prototype.doing = async function(o, ...msg) { o.num++; var ret; try { ret = o.func(...msg, o.param, o.num); if (types.isPromise(ret)) { ret = await ret; } if (this.mode > 4) { o.exec('reload', o.filename); } } catch (err) { $.log.error("事件器执行失败!", err); } if (o.num === o.count) { this.list_del.push(o.id); } return ret; } /** * 运行事件 * @param {Array} list 列表 * @param {String} type 类型 * @param {Boolean} isBreak 是否中断 * @param {Object} msg 事件消息 */ Eventer.prototype.run_sub = async function(list, isBreak, ...msg) { var ret; if (list) { for (var i = 0; i < list.length; i++) { var o = list[i]; // 判断是否启用状态 if (o.state == 1) { // 判断是否还需要执行 if (o.count < 0 || o.num < o.count) { ret = await this.doing(o, ...msg); if (ret && isBreak) { break; } } } else if (!o.state) { this.list_del.push({ id: o.id, type: o.type, tense: o.tense }); } } } return ret; } /** * 运行事件 * @param {String} type 类型 * @param {Object} msg 事件消息 */ Eventer.prototype.run = async function(type, ...msg) { this.do_before(); var ret; var dt = this.dict[type]; if (dt) { ret = await this.run_sub(dt.before, false, ...msg); ret = await this.run_sub(dt.check, true, ...msg); if (ret) { return ret } ret = await this.run_sub(dt.main, false, ...msg); if (ret) { var ret_new = await this.run_sub(dt.after, false, ...msg); ret = ret_new || ret; } } this.do_after(); return ret; } /** * 设置状态 * @param {Array} lt * @param {Object} id * @param {Object} state */ Eventer.prototype.setState_sub = function(lt, id, state) { var obj; if (lt) { if (id) { // 如果传入了ID,处理该ID事项 obj = lt.getObj({ id }); if (obj) { obj.state = state; } } else { // 否则全部处理 for (var i = 0; i < lt.length; i++) { var o = lt[i]; o.state = state; } } } return obj; } /** * 设置事件状态 * @param {Number} id 类型 * @param {String} type 类型 * @param {String} tense 时态 before执行前|check确认是否执行|main执行|after执行后 * @param {Number} state 状态 */ Eventer.prototype.setState = function(id, type, tense, state) { if (type) { // 如果传入了类型,处理该类事件 var dt = this.dict[type]; var obj; if (dt) { if (tense) { // 如果传入了时态,处理该事件下该时态的事 obj = this.setState_sub(dt[tense], id, state); } else { obj = this.setState_sub(dt.before, id, state); if (!obj) { obj = this.setState_sub(dt.check, id, state); if (!obj) { obj = this.setState_sub(dt.main, id, state); if (!obj) { obj = this.setState_sub(dt.after, id, state); } } } } } if (obj) { obj.state = state; } else { if (id) { obj = this.list_add.getObj({ id }); if (obj) { obj.state = state; } } else if (tense) { var lt = this.list_add.get({ type, tense }); for (var i = 0; i < lt.length; i++) { var o = lt[i]; o.state = state; } } else { var lt = this.list_add.get({ type }); for (var i = 0; i < lt.length; i++) { var o = lt[i]; o.state = state; } } } } else { var obj; for (var k in this.dict) { var dt = this.dict[k]; if (dt) { if (tense) { obj = this.setState_sub(dt[tense], id, state); } else { obj = this.setState_sub(dt.before, id, state); if (!obj) { obj = this.setState_sub(dt.check, id, state); if (!obj) { obj = this.setState_sub(dt.main, id, state); if (!obj) { obj = this.setState_sub(dt.after, id, state); } } } } if (obj) { break; } } } if (!obj) { if (id) { obj = this.list_add.getObj({ id }); } } if (obj) { obj.state = state; } } } /** * 开启 * @param {Number|String} id 名称或ID * @param {String} type 事件类型 * @param {String} tense 时态 before执行前|check确认是否执行|after执行后 */ Eventer.prototype.start = function(id, type, tense) { this.setState(id, type, tense, 1); } /** * 暂停 * @param {Number|String} id 名称或ID * @param {String} type 事件类型 * @param {String} tense 时态 before执行前|check确认是否执行|after执行后 */ Eventer.prototype.stop = function(id, type, tense) { this.setState(id, type, tense, 2); } /** * 结束 * @param {Number|String} id 名称或ID * @param {String} type 事件类型 * @param {String} tense 时态 before执行前|check确认是否执行|after执行后 */ Eventer.prototype.end = function(id, type, tense) { this.setState(id, type, tense, 0); } /** * 删除事件-子程序 * @param {Object} lt */ Eventer.prototype.del_sub = function(lt) { if (lt) { for (var i = 0; i < lt.length; i++) { var o = lt[i]; this.list_del.push({ id: o.id, type: o.type, tense: o.tense }) } } } /** * 删除事件 * @param {Number|String} id 名称或ID * @param {String} type 事件类型 * @param {String} tense 时态 before执行前|check确认是否执行|after执行后 */ Eventer.prototype.del = function(id, type, tense) { if (type) { if (id) { if (tense) { this.list_del.push({ id, type, tense }); } else { this.list_del.push({ id, type, tense: "before" }); this.list_del.push({ id, type, tense: "check" }); this.list_del.push({ id, type, tense: "main" }); this.list_del.push({ id, type, tense: "after" }); } } else { var dt = this.dict[type]; if (dt) { if (tense) { this.del_sub(dt[tense]); } else { this.del_sub(dt.before); this.del_sub(dt.check); this.del_sub(dt.main); this.del_sub(dt.after); } } } } else if (id) { var obj; for (var k in this.dict) { var dt = this.dict[k]; if (dt) { for (var t in dt) { var lt = dt[t]; if (lt) { obj = lt.getObj({ id }); if (obj) { break } } } } } if (!obj) { obj = this.list_add.getObj({ id }); } if (obj) { obj.state = 0; this.list_del.push({ id: obj.id, type: obj.type }); } } } module.exports = Eventer;