UNPKG

@blockv/sdk

Version:

Allows web apps to display and interact with vatoms.

208 lines (147 loc) 6.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BLOCKvRegion = _interopRequireDefault(require("./BLOCKvRegion")); var _DataObject = _interopRequireDefault(require("../DataObject")); var _EventEmitter = _interopRequireDefault(require("../EventEmitter")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* gloabl Events */ /** * This region plugin provides access to a collection of vatoms that has been dropped within the specified region on the map. * * To get an instance, call `DataPool.region('geopos', { top_right: { lat: ..., lon: ... }, bottom_left: { lat: ..., lon: ... } })` */ class GeoPosRegion extends _BLOCKvRegion.default { /** Plugin ID */ static get id() { return 'geopos'; } /** Constructor */ constructor(dataPool, coordinates) { super(dataPool); // Don't cache this content this.noCache = true; // Fail if coordinates are invalid if (!coordinates || !coordinates.top_right || !coordinates.top_right.lat || !coordinates.top_right.lon || !coordinates.bottom_left || !coordinates.bottom_left.lat || !coordinates.bottom_left.lon) { throw new Error('Please specify the top_right and bottom_left coordinates in the region descriptor.'); } // Store coordinates this.coordinates = coordinates; // Send region command to the WebSocket this.sendRegionCommand(); // Listen for events this.onWebSocketOpen = this.onWebSocketOpen.bind(this); this.socket.addEventListener('connected', this.onWebSocketOpen); } /** Called when this region is going to be shut down */ close() { super.close(); // Remove listeners this.socket.removeEventListener('connected', this.onWebSocketOpen); } /** Called when the WebSocket connection re-opens */ onWebSocketOpen() { this.sendRegionCommand(); } /** Sends the region command up the websocket to enable region monitoring */ sendRegionCommand() { // Convert our coordinates into the ones needed by the command let topLeft = { lat: Math.max(this.coordinates.top_right.lat, this.coordinates.bottom_left.lat), lon: Math.min(this.coordinates.top_right.lon, this.coordinates.bottom_left.lon) }; let bottomRight = { lat: Math.min(this.coordinates.top_right.lat, this.coordinates.bottom_left.lat), lon: Math.max(this.coordinates.top_right.lon, this.coordinates.bottom_left.lon) // Create command payload }; let cmd = { id: '1', version: '1', type: 'command', cmd: 'monitor', payload: { top_left: topLeft, bottom_right: bottomRight } // Send it up }; console.log('Sending WS command: ' + JSON.stringify(cmd)); // this.dataPool.Blockv.WebSockets.sendMessage(cmd) } /** Our state key is the region */ get stateKey() { return 'geopos:' + this.coordinates.top_right.lat + ',' + this.coordinates.top_right.lon + ' ' + this.coordinates.bottom_left.lat + ',' + this.coordinates.bottom_left.lon; } /** Check if a region request matches our region */ matches(id, descriptor) { // Check all filters match if (id !== 'geopos') return false; if (!descriptor || !descriptor.top_right || !descriptor.bottom_left) return false; if (descriptor.top_right.lat !== this.coordinates.top_right.lat) return false; if (descriptor.top_right.lon !== this.coordinates.top_right.lon) return false; if (descriptor.bottom_left.lat !== this.coordinates.bottom_left.lat) return false; if (descriptor.bottom_left.lon !== this.coordinates.bottom_left.lon) return false; // Yes they do return true; } /** Load current state from the server */ async load() { // Pause websocket events this.pauseMessages(); // Fetch data let response = await this.dataPool.Blockv.client.request('POST', '/v1/vatom/geodiscover', { top_right: this.coordinates.top_right, bottom_left: this.coordinates.bottom_left, filter: 'all', limit: 10000 }, true); // Add vatom to new objects list let objects = []; response.vatoms.map(v => new _DataObject.default('vatom', v.id, v)).forEach(f => objects.push(f)); // Add faces to new objects list response.faces.map(f => new _DataObject.default('face', f.id, f)).forEach(f => objects.push(f)); // Add actions to new objects list response.actions.map(a => new _DataObject.default('action', a.name, a)).forEach(a => objects.push(a)); // Add new objects this.addObjects(objects); // Resume websocket messages this.resumeMessages(); // Return array of IDs return objects.map(o => o.id); } /** This region type should not be cached */ save() {} /** Don't return vatoms which are not dropped */ map(object) { // Check if dropped if (object.data && object.data['vAtom::vAtomType'] && object.data['vAtom::vAtomType'].dropped) { return super.map(object); } // Vatom is not dropped! return null; } /** * Processes a WebSocket message. * * @private Called by BVWebSocketRegion. * @abstract Subclasses can override to process other WebSocket messages. Always call super.processMessage(msg) though. * @param {Object} msg The raw JSON from the websocket event message */ processMessage(msg) { super.processMessage(msg); // Get vatom ID let vatomID = msg.payload && msg.payload.id; if (!vatomID) { return console.warn(`[DataPool > BVWebSocketRegion] Got websocket message with no vatom ID in it: `, msg); } // Check if this is a newly dropped vatom let dropped = msg.payload.new_object && msg.payload.new_object['vAtom::vAtomType'] && msg.payload.new_object['vAtom::vAtomType'].dropped; if (msg.msg_type !== 'state_update' || !dropped) { return; } // Check if we already have this vatom if (this.objects.get(vatomID)) { return; } // A new vatom was dropped! Pause WebSocket message processing this.pauseMessages(); // Fetch vatom payload this.dataPool.Blockv.client.request('POST', '/v1/user/vatom/get', { ids: [vatomID] }).then(response => { // Add vatom to new objects list let objects = []; objects.push(new _DataObject.default('vatom', response.vatoms[0].id, response.vatoms[0])); // Add faces to new objects list response.faces.map(f => new _DataObject.default('face', f.id, f)).forEach(f => objects.push(f)); // Add actions to new objects list response.actions.map(a => new _DataObject.default('action', a.name, a)).forEach(a => objects.push(a)); // Add new objects this.addObjects(objects); }).catch(err => { // Log it console.warn(`[DataPool > GeoPosRegion] A vatom was dropped, bbut we could not fetch it's payload! ` + err.message); }).then(e => { // Resume message processing this.resumeMessages(); }); } } exports.default = GeoPosRegion;