UNPKG

@wiz-code/async-fsm

Version:

Finite StateMachine JavaScript Library

237 lines (179 loc) 6.46 kB
'use strict'; var _ = require('underscore'); var Elem = require('./elem'); var Region = require('./region'); var logger = require('./logger'); var ProtoState = function (name) { Elem.call(this, name); this._type = 'state'; this.container = null; this.region = null; this.children = []; this.setObserverType('container'); }; ProtoState.prototype = _.create(Elem.prototype, { constructor: ProtoState, _cname: 'ProtoState', getRegion: function (index) { var result; if (_.isNumber(index)) { result = this.children[index]; } else { result = this.region; } return result; }, getRegionByName: function (regionName) { return _.find(this.children, function (region) { return region.getName() === regionName; }); }, getRegionById: function (regionId) { return _.find(this.children, function (region) { return region.getId() === regionId; }); }, filterActiveRegion: function () { return _.filter(this.children, function (region) { return region.isActive(); }); }, completion: function () { if (!this.isActive()) { logger.error(this._cname + 'インスタンス"' + this._name + '"はすでに非アクティブ化されています。'); } this._async(function () { this._exit(); if (!_.isNull(this.container)) { this.notify('container', 'completion'); } }); }, _getParentState: function () { var result = null; if (!_.isNull(this.container) && !_.isNull(this.container.parent)) { result = this.container.parent; } return result; }, _hasSubState: function () { var result = _.some(this.children, function (region) { return region.children.states.length > 0; }); return result; }, update: function (event) { var params = _.toArray(arguments).slice(1); switch (event) { case 'entry': this._entry.apply(this, params); break; case 'exit': this._exit.apply(this, params); break; case 'refresh': this._refresh.apply(this, params); break; case 'completion': this.completion.apply(this, params); break; } }, _refresh: function (depth) { this._depth = depth; this.parent = this._getParentState(); this.notify('children', 'refresh', depth); }, _entry: function (message) { if (!this.isActive()) { this._activate(); this.notify('children', 'entry', message); } }, addState: function () { var states = _.toArray(arguments); if (_.isNull(this.region)) { this.appendRegion(); } return this.region.addState.apply(this.region, states); }, removeState: function () { var states = _.toArray(arguments); if (_.isNull(this.region)) { logger.error('デフォルトのRegionインスタンスが存在しません。'); } return this.region.removeState.apply(this.region, states); }, addTransition: function () { var transits = _.toArray(arguments); if (_.isNull(this.region)) { this.appendRegion(); } return this.region.addTransition.apply(this.region, transits); }, removeTransition: function () { var transits = _.toArray(arguments); if (_.isNull(this.region)) { logger.error('デフォルトのRegionインスタンスが存在しません。'); } return this.region.removeTransition.apply(this.region, transits); }, appendRegion: function (region) { if (this._attached) { logger.error('デプロイ後は要素の追加/削除はできません。Machineクラスのundeploy()メソッドでデプロイを取り消してください。'); } if (_.isNull(this.region)) { if (_.isUndefined(region)) { region = new Region('default-region-of-' + this._name); logger.info(this._cname + 'インスタンス"' + this._name + '"のRegionインスタンスが自動作成されました。'); } else if (!(region instanceof Region)) { logger.error('Regionインスタンスを指定してください。'); } this.region = region; } else { if (_.isUndefined(region)) { region = new Region(false); } else if (!(region instanceof Region)) { logger.error('Regionインスタンスを指定してください。'); } } region.parent = this; this.children.push(region); this.addObserver('children', region); region.addObserver('parent', this); if (!region._originalName) { region.setName('region-index-' + region.getIndex() + '-of-' + this._name, true); region._setDefaultStateName(); } region._refresh(this._depth); return region; }, removeRegion: function (region) { var index; if (this._attached) { logger.error('デプロイ後は要素の追加/削除はできません。Machineクラスのundeploy()メソッドでデプロイを取り消してください。'); } if (!(region instanceof Region)) { logger.error('Regionインスタンスを指定してください。'); } index = _.indexOf(this.children, region); if (index > -1) { this.children.splice(index, 1); } else { logger.error('削除対象のRegionインスタンスが見つかりません。'); } region.parent = null; if (this.region === region) { this.region = null; } region._refresh(); this.removeObserver('children', region); region.removeObserver('parent', this); if (!region._originalName) { region.setName(region.getId(), true); region._setDefaultStateName(); } return region; }, }); module.exports = ProtoState;