UNPKG

vue-kityminder-ggg

Version:

百度脑图

124 lines (107 loc) 3.82 kB
/** * @fileOverview * * 编辑器状态机 * * @author: techird * @copyright: Baidu FEX, 2014 */ define(function(require, exports, module) { var Debug = require('../tool/debug'); var debug = new Debug('fsm'); function handlerConditionMatch(condition, when, exit, enter) { if (condition.when != when) return false; if (condition.enter != '*' && condition.enter != enter) return false; if (condition.exit != '*' && condition.exit != exit) return; return true; } function FSM(defaultState) { var currentState = defaultState; var BEFORE_ARROW = ' - '; var AFTER_ARROW = ' -> '; var handlers = []; /** * 状态跳转 * * 会通知所有的状态跳转监视器 * * @param {string} newState 新状态名称 * @param {any} reason 跳转的原因,可以作为参数传递给跳转监视器 */ this.jump = function(newState, reason) { // debugger if (!reason) throw new Error('Please tell fsm the reason to jump'); var oldState = currentState; var notify = [oldState, newState].concat([].slice.call(arguments, 1)); // console.log(notify) var i, handler; // 跳转前 for (i = 0; i < handlers.length; i++) { handler = handlers[i]; if (handlerConditionMatch(handler.condition, 'before', oldState, newState)) { if (handler.apply(null, notify)) return; } } currentState = newState; debug.log('[{0}] {1} -> {2}', reason, oldState, newState); // 跳转后 for (i = 0; i < handlers.length; i++) { handler = handlers[i]; if (handlerConditionMatch(handler.condition, 'after', oldState, newState)) { handler.apply(null, notify); } } // console.log(currentState) return currentState; }; /** * 返回当前状态 * @return {string} */ this.state = function() { return currentState; }; /** * 添加状态跳转监视器 * * @param {string} condition * 监视的时机 * "* => *" (默认) * * @param {Function} handler * 监视函数,当状态跳转的时候,会接收三个参数 * * from - 跳转前的状态 * * to - 跳转后的状态 * * reason - 跳转的原因 */ this.when = function(condition, handler) { if (arguments.length == 1) { handler = condition; condition = '* -> *'; } var when, resolved, exit, enter; resolved = condition.split(BEFORE_ARROW); if (resolved.length == 2) { when = 'before'; } else { resolved = condition.split(AFTER_ARROW); if (resolved.length == 2) { when = 'after'; } } if (!when) throw new Error('Illegal fsm condition: ' + condition); exit = resolved[0]; enter = resolved[1]; handler.condition = { when: when, exit: exit, enter: enter }; handlers.push(handler); }; } function FSMRumtime() { this.fsm = new FSM('normal'); } return module.exports = FSMRumtime; });