UNPKG

webgme-hfsm

Version:

WebGME Domain for creating Executable Heirarchical Finite State Machines (HFSMs). Contains metamodel, visualization, simulation, and code generation for Heirarchical Finite State Machines (HFSMs) following the UML State Machine specification.

222 lines (184 loc) 7.42 kB
/*globals define, WebGMEGlobal*/ /*jshint browser: true*/ /** * Generated by VisualizerGenerator 1.7.0 from webgme on Thu May 11 2017 10:42:38 GMT-0700 (PDT). */ define([ 'js/Constants', 'js/Utils/GMEConcepts', 'js/NodePropertyNames' ], function ( CONSTANTS, GMEConcepts, nodePropertyNames ) { 'use strict'; var HFSMVizControl; HFSMVizControl = function (options) { var self = this; self._logger = options.logger.fork('Control'); self._client = options.client; // Initialize core collections and variables self._widget = options.widget; self.currentNodeInfo = {id: null, children: [], parentId: null}; // Put new node's info into territory rules self._selfPatterns = {}; self._initWidgetEventHandlers(); self._logger.debug('ctor finished'); }; HFSMVizControl.prototype._initWidgetEventHandlers = function () { var self = this; self._widget.onNodeClick = function (id) { // Change the current active object WebGMEGlobal.State.registerActiveObject(id); }; }; var rootTypes = ['State Machine', 'Library']; var excludeTypes = [];//'Project', 'Component']; /* * * * * * * * Visualizer content update callbacks * * * * * * * */ // One major concept here is with managing the territory. The territory // defines the parts of the project that the visualizer is interested in // (this allows the browser to then only load those relevant parts). HFSMVizControl.prototype.selectedObjectChanged = function (nodeId) { var self = this, desc; self._logger.debug('activeObject nodeId \'' + nodeId + '\''); var widgetNode = self._widget.nodes[ nodeId ]; if (!self.currentNodeInfo.id || !widgetNode) { // Remove current territory patterns if (self._territoryId) { self._widget.clearNodes(); // Update the territory self._selfPatterns = {}; self._client.updateTerritory(self._territoryId, self._selfPatterns); self._client.removeUI(self._territoryId); } self.currentNodeInfo.id = nodeId; self.currentNodeInfo.parentId = undefined; desc = self._getObjectDescriptor(nodeId); if (desc && rootTypes.indexOf(desc.type) > -1) { self._selfPatterns[nodeId] = {children: 100}; // Territory "rule" self._territoryId = self._client.addUI(self, function (events) { self._eventCallback(events); }); // Update the territory self.currentNodeInfo.parentId = desc.parentId; } self._client.updateTerritory(self._territoryId, self._selfPatterns); } }; // This next function retrieves the relevant node information for the widget HFSMVizControl.prototype._getObjectDescriptor = function (nodeId) { var self = this; var node = self._client.getNode(nodeId), objDescriptor = null; if (node) { var metaObj = self._client.getNode(node.getMetaTypeId()), metaName = undefined; if (metaObj) { metaName = metaObj.getAttribute(nodePropertyNames.Attributes.name); } if (metaName && excludeTypes.indexOf(metaName) == -1) { objDescriptor = { id: node.getId(), type: metaName, position: node.getRegistry('position'), // { x, y } childrenIds: node.getChildrenIds(), parentId: node.getParentId(), isConnection: GMEConcepts.isConnection(nodeId) }; node.getAttributeNames().map(function(a) { objDescriptor[a] = node.getAttribute(a); }); objDescriptor.LABEL = objDescriptor.name; // add the node pointers if it's a connection if (objDescriptor.isConnection) { objDescriptor.src = node.getPointer('src').to; objDescriptor.dst = node.getPointer('dst').to; objDescriptor.LABEL = objDescriptor.Event; if (objDescriptor.Guard) { objDescriptor.LABEL += ' [' + objDescriptor.Guard + ']'; } } else if (objDescriptor.type == 'Internal Transition') { objDescriptor.LABEL = objDescriptor.Event; if (objDescriptor.Guard) { objDescriptor.LABEL += ' [' + objDescriptor.Guard + ']'; } } // make sure the root level has no parentId if (rootTypes.indexOf(objDescriptor.type) > -1) objDescriptor.parentId = null; } } return objDescriptor; }; /* * * * * * * * Node Event Handling * * * * * * * */ HFSMVizControl.prototype._eventCallback = function (events) { var self = this; var i = events ? events.length : 0, event; self._logger.debug('_eventCallback \'' + i + '\' items'); while (i--) { event = events[i]; switch (event.etype) { case CONSTANTS.TERRITORY_EVENT_LOAD: self._onLoad(event.eid); break; case CONSTANTS.TERRITORY_EVENT_UPDATE: self._onUpdate(event.eid); break; case CONSTANTS.TERRITORY_EVENT_UNLOAD: self._onUnload(event.eid); break; default: break; } } self._logger.debug('_eventCallback \'' + events.length + '\' items - DONE'); }; HFSMVizControl.prototype._onLoad = function (gmeId) { var self = this; var description = self._getObjectDescriptor(gmeId); if (description && self._widget) self._widget.addNode(description); }; HFSMVizControl.prototype._onUpdate = function (gmeId) { var self = this; var description = self._getObjectDescriptor(gmeId); if (description && self._widget) self._widget.updateNode(description); }; HFSMVizControl.prototype._onUnload = function (gmeId) { if (this._widget) this._widget.removeNode(gmeId); }; HFSMVizControl.prototype._stateActiveObjectChanged = function (model, activeObjectId) { this.selectedObjectChanged(activeObjectId); }; /* * * * * * * * Visualizer life cycle callbacks * * * * * * * */ HFSMVizControl.prototype.destroy = function () { this._client.removeUI(this._territoryId); delete this._widget; this._detachClientEventListeners(); }; HFSMVizControl.prototype._attachClientEventListeners = function () { this._detachClientEventListeners(); WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged, this); }; HFSMVizControl.prototype._detachClientEventListeners = function () { WebGMEGlobal.State.off('change:' + CONSTANTS.STATE_ACTIVE_OBJECT, this._stateActiveObjectChanged); }; HFSMVizControl.prototype.onActivate = function () { this._attachClientEventListeners(); if (this.currentNodeInfo && typeof this.currentNodeInfo.id === 'string') { WebGMEGlobal.State.registerActiveObject(this.currentNodeInfo.id, { suppressVisualizerFromNode: true }); } }; HFSMVizControl.prototype.onDeactivate = function () { this._detachClientEventListeners(); }; return HFSMVizControl; });