@openhps/core
Version:
Open Hybrid Positioning System - Core component
160 lines • 4.76 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Node } from '../Node';
import { Service } from './Service';
import { SerializableObject } from '../data/decorators';
/**
* Remote node service
*/
let RemoteService = class RemoteService extends Service {
constructor() {
super();
this.nodes = new Set();
this.localServices = new Set();
this.remoteServices = new Set();
this.promises = new Map();
this.once('build', this._registerServices.bind(this));
}
_registerServices() {
return new Promise(resolve => {
if (!this.model) {
return resolve(); // No services to add when not added to model
}
this.model.once('ready', () => {
// Only register services after the model is ready
// this is why we resolve the promise before this is completed
this.model.findAllServices().forEach(service => {
this.registerService(service);
});
});
resolve();
});
}
registerPromise(resolve, reject, id) {
const uuid = id !== null && id !== void 0 ? id : this.generateUUID();
this.promises.set(uuid, {
resolve,
reject
});
return uuid;
}
getPromise(uuid) {
const promise = this.promises.get(uuid);
if (promise) {
this.promises.delete(uuid);
}
return promise;
}
/**
* Local positioning model push
* @param {string} uid UID of the node
* @param {DataFrame | any} frame Data frame
* @param {RemotePushOptions} options Push options
*/
localPush(uid, frame, options) {
options = options || {};
if (this.nodes.has(uid)) {
// Parse frame and options
const node = this.model.findNodeByUID(uid);
node.emit('localpush', frame, options);
}
}
/**
* Local positioning model pull
* @param {string} uid UID of the node
* @param {RemotePullOptions} options Pull options
*/
localPull(uid, options) {
options = options || {};
if (this.nodes.has(uid)) {
this.model.findNodeByUID(uid).emit('localpull', options);
}
}
/**
* Local positioning model event
* @param {string} uid UID of the node
* @param {string} event Event name
* @param {any[]} [args] Argument
*/
localEvent(uid, event, ...args) {
if (this.nodes.has(uid)) {
this.model.findNodeByUID(uid).emit('localevent', event, ...args);
}
}
/**
* Local service call
* @param {string} uid Service uid
* @param {string} method Method name
* @param {any[]} [args] optional arguments
* @returns {Promise<any> | any | void} service call output
*/
localServiceCall(uid, method, ...args) {
if (this.localServices.has(uid)) {
const service = this.model.findService(uid) || this.model.findDataService(uid);
return service[method](...args);
}
}
/**
* Register a node as a remotely available node
* @param {Node<any, any> | string} node Node to register
* @returns {Promise<void>} Promise of registration
*/
registerNode(node) {
return new Promise(resolve => {
const existingNode = node instanceof Node ? node : this.model.findNodeByUID(node);
this.nodes.add(existingNode.uid);
this.logger('debug', `Registered remote server node ${existingNode.uid}`);
resolve();
});
}
/**
* Register a service to be remotely available
* @param {Service} service Service to register
* @returns {Promise<void>} Promise of registration
*/
registerService(service) {
return new Promise(resolve => {
if (!(service instanceof RemoteServiceProxy)) {
this.localServices.add(service.uid);
} else {
this.remoteServices.add(service.uid);
}
resolve();
});
}
};
RemoteService = __decorate([SerializableObject(), __metadata("design:paramtypes", [])], RemoteService);
export { RemoteService };
export class RemoteServiceProxy extends Service {
constructor(options) {
super();
this.options = options;
this.uid = options.uid;
}
get(target, p) {
const ownResult = this[p];
if (ownResult) {
return ownResult;
}
return this.createHandler(target, p);
}
set(target, p, value) {
target[p] = value;
return true;
}
/**
* Create handler function for a specific property key
* @param {Service} target Target service
* @param {string|number|symbol} p Property
* @returns {Function} Handler function
*/
createHandler(target, p) {
if (!this.service) {
this.service = target.model.findService(this.options.service);
if (this.service === undefined || this.service === null) {
return () => undefined;
}
this.service.registerService(this);
}
return (...args) => this.service.remoteServiceCall(target.uid, p, ...args);
}
}