import { BaseComponent } from './BaseComponent';
import { Selector } from '../selector/Selector';
const __ = {
private: Symbol('private'),
}
/**
* @class RelationshipComponent
* The relationship component.
* @memberof THING
* @extends THING.BaseComponent
* @public
*/
class RelationshipComponent extends BaseComponent {
static mustCopyWithInstance = true;
/**
* The relationship of object.
*/
constructor() {
super();
this[__.private] = {};
let _private = this[__.private];
_private.relationships = null;
}
/**
* object add relationship
* @param {THING.Relationship} value
* @private
*/
addRelationship(value) {
let _private = this[__.private];
_private.relationships = _private.relationships || [];
if (!_private.relationships.includes(value)) {
_private.relationships.push(value);
}
}
/**
* object remove relationship
* @param {THING.Relationship} value
* @private
*/
removeRelationship(value) {
let _private = this[__.private];
if (value) {
let relationships = _private.relationships || [];
let index = relationships.indexOf(value);
if (index !== -1) {
relationships.splice(index, 1);
}
}
}
// #endregion
// #region query
/**
* Query related objects.
* @param {Object} options
* @param {String} options.type The type of relationship.
* @param {String} options.name The name of relationship.
* @param {RelationshipDirection} options.queryDirection The query direction.
* @returns {THING.Selector}
* @example
* let source = new THING.Object3D();
* let target = new THING.Object3D();
* let rel = new THING.Relationship({
* type: 'control',
* source,
* target
* })
* let result = source.relationship.query({type: 'control'});
* // @expect(result[0] == target)
* @public
*/
query(options = {}) {
let _private = this[__.private];
let objs = [];
if (_private.relationships) {
let queryDirection = options['queryDirection'];
_private.relationships.forEach((relationship) => {
if (relationship.test(options)) {
let selector = relationship.queryObjects(this.object, queryDirection);
objs.push(...selector.objects);
}
})
}
return new Selector([...new Set(objs)]);
}
/**
* Query related objects by relationship type.
* @param {String} type The relationship type.
* @param {RelationshipDirection} queryDirection The query direction.
* @returns {THING.Selector}
* @example
* let source = new THING.Object3D();
* let target = new THING.Object3D();
* let rel = new THING.Relationship({
* type: 'control',
* source,
* target
* })
* let result = source.relationship.queryByType('control');
* // @expect(result[0] == target)
* @public
*/
queryByType(type, queryDirection) {
return this.query({ type, queryDirection });
}
/**
* Query related objects by relationship name.
* @param {String} name The relationship name.
* @param {RelationshipDirection} queryDirection The query direction.
* @returns {THING.Selector}
* @example
* let source = new THING.Object3D();
* let target = new THING.Object3D();
* let rel = new THING.Relationship({
* name: 'myControl',
* type: 'control',
* source,
* target
* })
* let result = source.relationship.queryByName('myControl');
* // @expect(result[0] == target)
* @public
*/
queryByName(name, queryDirection) {
return this.query({ name, queryDirection });
}
// #endregion
// #region remove
onRemove() {
let _private = this[__.private];
if (_private.relationships) {
let relationships = _private.relationships.slice(0);
relationships.forEach(relationship => {
this.app.relationshipManager.notifyRelationshipRemoveObject(relationship, this.object);
});
_private.relationships = null;
}
super.onRemove();
}
// #endregion
// #region Accessors
get relationships() {
let _private = this[__.private];
return _private.relationships || [];
}
// #endregion
}
export { RelationshipComponent }