@openhps/core
Version:
Open Hybrid Positioning System - Core component
289 lines • 9.59 kB
JavaScript
var DataObject_1;
import { __decorate, __metadata } from "tslib";
import { AbsolutePosition } from '../position/AbsolutePosition';
import { RelativePosition } from '../position/RelativePosition';
import { SerializableObject, SerializableMember, SerializableArrayMember, NumberType } from '../decorators';
import { v4 as uuidv4 } from 'uuid';
import { DataSerializer } from '../DataSerializer';
import { TimeService } from '../../service/TimeService';
import { EventEmitter } from 'events';
let DataObject = DataObject_1 = class DataObject {
/**
* Create a new data object
* @param {string} uid Optional unique identifier
* @param {string} displayName Optional display name
*/
constructor(uid = uuidv4(), displayName) {
this._relativePositions = new Map();
this.uid = uid;
this.createdTimestamp = TimeService.now();
this.displayName = displayName;
}
/**
* Get the current absolute position of the object
* relative to the global reference space
* @returns {AbsolutePosition} Absolute position of data object
*/
get position() {
return this.getPosition();
}
/**
* Set the current absolute position of the object
* relative to the global reference space
*/
set position(position) {
this.setPosition(position);
}
/**
* Get the orientation of the object
* relative to the global reference space
*/
get orientation() {
return this._position ? this.getPosition().orientation : undefined;
}
/**
* Set the orientation of the object
* relative to the global reference space
*/
set orientation(orientation) {
if (this._position) {
this.getPosition().orientation = orientation;
}
}
get velocity() {
return this._position ? this.getPosition().velocity : undefined;
}
set velocity(velocity) {
if (this._position) {
this.getPosition().velocity = velocity;
}
}
get linearVelocity() {
return this._position ? this.getPosition().linearVelocity : undefined;
}
set linearVelocity(velocity) {
if (this._position) {
this.getPosition().linearVelocity = velocity;
}
}
get angularVelocity() {
return this._position ? this.getPosition().angularVelocity : undefined;
}
set angularVelocity(velocity) {
if (this._position) {
this.getPosition().angularVelocity = velocity;
}
}
/**
* Get the current absolute position of the object
* @param {TransformationSpace} [referenceSpace] Reference space to transform it to
* @returns {AbsolutePosition} Position of the data object
*/
getPosition(referenceSpace) {
if (referenceSpace !== undefined && this._position !== undefined) {
return referenceSpace.transform(this._position, {
inverse: true
});
} else {
return this._position;
}
}
/**
* Set the current absolute position of the object
* @param {AbsolutePosition} position Position to set
* @param {TransformationSpace} [referenceSpace] Reference space
* @returns {DataObject} Data object instance
*/
setPosition(position, referenceSpace) {
this._position = referenceSpace ? referenceSpace.transform(position, {
inverse: false
}) : position;
return this;
}
/**
* Set the unique identifier of this object
* @param {string} uid Unique Identifier
* @returns {DataObject} Data object instance
*/
setUID(uid) {
this.uid = uid;
return this;
}
/**
* Get relative positions
* @returns {RelativePosition[]} Array of relative positions
*/
get relativePositions() {
const relativePostions = [];
if (this._relativePositions !== undefined) {
this._relativePositions.forEach(values => {
values.forEach(value => {
relativePostions.push(value);
});
});
}
return relativePostions;
}
set relativePositions(relativePostions) {
this._relativePositions = new Map();
relativePostions.forEach(relativePostion => {
this.addRelativePosition(relativePostion);
});
}
/**
* Set a parent object to the data object
* @param {DataObject | string | undefined} object Data object or UID to add as parent
* @returns {DataObject} instance
*/
setParent(object) {
this.parentUID = object instanceof DataObject_1 ? object.uid : object;
return this;
}
removeRelativePositions(referenceObjectUID) {
this._relativePositions.delete(referenceObjectUID);
}
/**
* Add a relative position to this data object
* @param {RelativePosition} relativePosition Relative position to add
* @returns {DataObject} Data object instance
*/
addRelativePosition(relativePosition) {
if (!relativePosition || relativePosition.referenceObjectUID === undefined) {
return this;
}
if (!this._relativePositions.has(relativePosition.referenceObjectUID)) {
this._relativePositions.set(relativePosition.referenceObjectUID, new Map());
}
this._relativePositions.get(relativePosition.referenceObjectUID).set(relativePosition.constructor.name, relativePosition);
return this;
}
/**
* Get relative positions for a different target
* @param {string} [referenceObjectUID] Reference object identifier
* @returns {RelativePosition[]} Array of relative positions for the reference object
*/
getRelativePositions(referenceObjectUID) {
if (referenceObjectUID === undefined) {
return this.relativePositions;
} else if (this._relativePositions.has(referenceObjectUID)) {
return Array.from(this._relativePositions.get(referenceObjectUID).values());
} else {
return [];
}
}
/**
* Get relative position of a specified object
* @param {string} referenceObjectUID Reference object identifier
* @param {string} type Constructor type of the relative position
* @returns {RelativePosition} Relative position to reference object
*/
getRelativePosition(referenceObjectUID, type) {
if (this._relativePositions.has(referenceObjectUID)) {
const positions = this._relativePositions.get(referenceObjectUID);
if (type) {
return positions.get(type);
} else {
return Array.from(positions.values())[0];
}
} else {
return undefined;
}
}
hasRelativePosition(referenceObjectUID) {
return this._relativePositions.has(referenceObjectUID);
}
/**
* Bind the data object to a service
* @param {DataService<string, DataObject>} service Service to bind it to
* @returns {DataObjectBinding<DataObject>} Data object binding with a service
*/
bind(service) {
return new DataObjectBinding(this, service);
}
/**
* Clone the data object
* @param {Constructor<DataObject>} [dataType] Data type to clone to
* @returns {DataObject} Cloned data object
*/
clone(dataType) {
return DataSerializer.clone(this, dataType);
}
};
__decorate([SerializableMember(), __metadata("design:type", String)], DataObject.prototype, "displayName", void 0);
__decorate([SerializableMember({
index: true,
numberType: NumberType.LONG
}), __metadata("design:type", Number)], DataObject.prototype, "createdTimestamp", void 0);
__decorate([SerializableMember({
primaryKey: true
}), __metadata("design:type", String)], DataObject.prototype, "uid", void 0);
__decorate([SerializableMember(), __metadata("design:type", String)], DataObject.prototype, "parentUID", void 0);
__decorate([SerializableMember(), __metadata("design:type", AbsolutePosition), __metadata("design:paramtypes", [AbsolutePosition])], DataObject.prototype, "position", null);
__decorate([SerializableArrayMember(RelativePosition), __metadata("design:type", Array), __metadata("design:paramtypes", [Array])], DataObject.prototype, "relativePositions", null);
DataObject = DataObject_1 = __decorate([SerializableObject()
/**
* A data object is an instance that can be anything ranging from a person or asset to
* a more abstract object such as a Wi-Fi access point or {@link ReferenceSpace}.
* @example
* ```typescript
* const dataObject = new DataObject();
* dataObject.displayName = "Sample Object";
* dataObject.position = new AbsolutePosition(1, 2, 3);
* dataObject.setParent("parentUID");
* ```
*
* ## Usage
*
* ### Creation
* Objects can be created with an optional uid and display name.
* ```typescript
* const myObject = new DataObject("mvdewync", "Maxim");
* ```
*
* ### Service binding
* Data objects can be bounded to a service. Persistence is handled in {@link DataObjectService}s
* that store and load data objects.
* ```typescript
* myObject.bind(myModel).save();
* ```
* @public
* @category data
*/, __metadata("design:paramtypes", [String, String])], DataObject);
export { DataObject };
class DataObjectBinding extends EventEmitter {
constructor(target, service) {
super();
this.target = target;
this.service = service;
this.service.on('insert', this._onInsert.bind(this));
}
_onInsert(uid, object) {
if (this.target.uid === uid) {
this.emit('update', this.target, object);
this.target = object;
}
}
on(name, listener) {
return super.on(name, listener);
}
/**
* Save the data object
* @returns {Promise<DataObject>} Promise of stored data object
*/
save() {
return this.service.insert(this.target.uid, this.target);
}
/**
* Destroy the data object
* @returns {Promise<void>} Destroy promise
*/
delete() {
return this.service.delete(this.target.uid);
}
/**
* Dispose of the binding
*/
dispose() {
this.service.removeListener('update', this._onInsert.bind(this));
}
}