playcanvas
Version:
PlayCanvas WebGL game engine
239 lines (236 loc) • 7.77 kB
JavaScript
import { guid } from '../core/guid.js';
import { GraphNode } from '../scene/graph-node.js';
import { getApplication } from './globals.js';
var cmpStaticOrder = (a, b)=>a.constructor.order - b.constructor.order;
var sortStaticOrder = (arr)=>arr.sort(cmpStaticOrder);
var _enableList = [];
var tmpPool = [];
var getTempArray = ()=>{
var _tmpPool_pop;
return (_tmpPool_pop = tmpPool.pop()) != null ? _tmpPool_pop : [];
};
var releaseTempArray = (a)=>{
a.length = 0;
tmpPool.push(a);
};
class Entity extends GraphNode {
addComponent(type, data) {
var system = this._app.systems[type];
if (!system) {
return null;
}
if (this.c[type]) {
return null;
}
return system.addComponent(this, data);
}
removeComponent(type) {
var system = this._app.systems[type];
if (!system) {
return;
}
if (!this.c[type]) {
return;
}
system.removeComponent(this);
}
findComponent(type) {
var entity = this.findOne((entity)=>{
var _entity_c;
return (_entity_c = entity.c) == null ? undefined : _entity_c[type];
});
return entity && entity.c[type];
}
findComponents(type) {
return this.find((entity)=>{
var _entity_c;
return (_entity_c = entity.c) == null ? undefined : _entity_c[type];
}).map((entity)=>entity.c[type]);
}
findScript(nameOrType) {
var entity = this.findOne((node)=>{
var _node_c_script, _node_c;
return (_node_c = node.c) == null ? undefined : (_node_c_script = _node_c.script) == null ? undefined : _node_c_script.has(nameOrType);
});
return entity == null ? undefined : entity.c.script.get(nameOrType);
}
findScripts(nameOrType) {
var entities = this.find((node)=>{
var _node_c_script, _node_c;
return (_node_c = node.c) == null ? undefined : (_node_c_script = _node_c.script) == null ? undefined : _node_c_script.has(nameOrType);
});
return entities.map((entity)=>entity.c.script.get(nameOrType));
}
getGuid() {
if (!this._guid) {
this.setGuid(guid.create());
}
return this._guid;
}
setGuid(guid) {
var index = this._app._entityIndex;
if (this._guid) {
delete index[this._guid];
}
this._guid = guid;
index[this._guid] = this;
}
_notifyHierarchyStateChanged(node, enabled) {
var enableFirst = false;
if (node === this && _enableList.length === 0) {
enableFirst = true;
}
node._beingEnabled = true;
node._onHierarchyStateChanged(enabled);
if (node._onHierarchyStatePostChanged) {
_enableList.push(node);
}
var c = node._children;
for(var i = 0, len = c.length; i < len; i++){
if (c[i]._enabled) {
this._notifyHierarchyStateChanged(c[i], enabled);
}
}
node._beingEnabled = false;
if (enableFirst) {
for(var i1 = 0; i1 < _enableList.length; i1++){
_enableList[i1]._onHierarchyStatePostChanged();
}
_enableList.length = 0;
}
}
_onHierarchyStateChanged(enabled) {
super._onHierarchyStateChanged(enabled);
var components = this._getSortedComponents();
for(var i = 0; i < components.length; i++){
var component = components[i];
if (component.enabled) {
if (enabled) {
component.onEnable();
} else {
component.onDisable();
}
}
}
releaseTempArray(components);
}
_onHierarchyStatePostChanged() {
var components = this._getSortedComponents();
for(var i = 0; i < components.length; i++){
components[i].onPostStateChange();
}
releaseTempArray(components);
}
findByGuid(guid) {
if (this._guid === guid) return this;
var e = this._app._entityIndex[guid];
if (e && (e === this || e.isDescendantOf(this))) {
return e;
}
return null;
}
destroy() {
this._destroying = true;
for(var name in this.c){
this.c[name].enabled = false;
}
for(var name1 in this.c){
this.c[name1].system.removeComponent(this);
}
super.destroy();
if (this._guid) {
delete this._app._entityIndex[this._guid];
}
this._destroying = false;
}
clone() {
var duplicatedIdsMap = {};
var clone = this._cloneRecursively(duplicatedIdsMap);
duplicatedIdsMap[this.getGuid()] = clone;
resolveDuplicatedEntityReferenceProperties(this, this, clone, duplicatedIdsMap);
return clone;
}
_getSortedComponents() {
var components = this.c;
var sortedArray = getTempArray();
var needSort = 0;
for(var type in components){
if (components.hasOwnProperty(type)) {
var component = components[type];
needSort |= component.constructor.order !== 0;
sortedArray.push(component);
}
}
if (needSort && sortedArray.length > 1) {
sortStaticOrder(sortedArray);
}
return sortedArray;
}
_cloneRecursively(duplicatedIdsMap) {
var clone = new this.constructor(undefined, this._app);
super._cloneInternal(clone);
for(var type in this.c){
var component = this.c[type];
component.system.cloneComponent(this, clone);
}
for(var i = 0; i < this._children.length; i++){
var oldChild = this._children[i];
if (oldChild instanceof Entity) {
var newChild = oldChild._cloneRecursively(duplicatedIdsMap);
clone.addChild(newChild);
duplicatedIdsMap[oldChild.getGuid()] = newChild;
}
}
return clone;
}
constructor(name, app = getApplication()){
super(name), this.c = {}, this._destroying = false, this._guid = null, this._template = false;
this._app = app;
}
}
Entity.EVENT_DESTROY = 'destroy';
function resolveDuplicatedEntityReferenceProperties(oldSubtreeRoot, oldEntity, newEntity, duplicatedIdsMap) {
if (oldEntity instanceof Entity) {
var components = oldEntity.c;
for(var componentName in components){
var component = components[componentName];
var entityProperties = component.system.getPropertiesOfType('entity');
for(var i = 0, len = entityProperties.length; i < len; i++){
var propertyDescriptor = entityProperties[i];
var propertyName = propertyDescriptor.name;
var oldEntityReferenceId = component[propertyName];
var entityIsWithinOldSubtree = !!oldSubtreeRoot.findByGuid(oldEntityReferenceId);
if (entityIsWithinOldSubtree) {
var newEntityReferenceId = duplicatedIdsMap[oldEntityReferenceId].getGuid();
if (newEntityReferenceId) {
newEntity.c[componentName][propertyName] = newEntityReferenceId;
}
}
}
}
if (components.script) {
newEntity.script.resolveDuplicatedEntityReferenceProperties(components.script, duplicatedIdsMap);
}
if (components.render) {
newEntity.render.resolveDuplicatedEntityReferenceProperties(components.render, duplicatedIdsMap);
}
if (components.button) {
newEntity.button.resolveDuplicatedEntityReferenceProperties(components.button, duplicatedIdsMap);
}
if (components.scrollview) {
newEntity.scrollview.resolveDuplicatedEntityReferenceProperties(components.scrollview, duplicatedIdsMap);
}
if (components.scrollbar) {
newEntity.scrollbar.resolveDuplicatedEntityReferenceProperties(components.scrollbar, duplicatedIdsMap);
}
if (components.anim) {
newEntity.anim.resolveDuplicatedEntityReferenceProperties(components.anim, duplicatedIdsMap);
}
var _old = oldEntity.children.filter((e)=>e instanceof Entity);
var _new = newEntity.children.filter((e)=>e instanceof Entity);
for(var i1 = 0, len1 = _old.length; i1 < len1; i1++){
resolveDuplicatedEntityReferenceProperties(oldSubtreeRoot, _old[i1], _new[i1], duplicatedIdsMap);
}
}
}
export { Entity };