the-world-engine
Version:
three.js based, unity like game engine for browser
289 lines (287 loc) • 8.75 kB
JavaScript
import { GameObjectEventContainer } from "./GameObjectEventContainer";
import { Transform } from "./Transform";
export class GameObject {
L;
yt;
$t;
Mt;
Nt;
_initialized;
components;
gameObjectEventContainer;
constructor(t, e) {
this.L = t;
this.yt = t.instantiater.generateId();
this.$t = true;
this.Mt = true;
this._initialized = false;
this.components = [];
this.gameObjectEventContainer = new GameObjectEventContainer;
this.Nt = new Transform(this, t, this.Qt.bind(this));
this.Nt.unsafeGetObject3D().name = e;
}
addChildFromBuilder(t) {
this.Vt();
const e = t.build(this.transform);
t.processEvent();
return e;
}
Qt(t, e) {
if (e && this.L !== e.gameObject.L) {
throw new Error("can't change parent to another engine instance");
}
const i = this.transform.gameObject;
if (e) {
if (i.Mt) {
i.Xt(e.gameObject.$t);
}
} else {
i.Xt(i.Mt);
}
}
addComponent(t) {
this.Vt();
const e = new t(this);
e.engine_internal_constructAfterProcess();
if (e.disallowMultipleComponent) {
const e = this.getComponent(t);
if (e) {
console.warn(`Component ${t.name} already exists on GameObject ${this.name}`);
return null;
}
}
const i = e.requiredComponents;
for (let e = 0; e < i.length; ++e) {
const s = i[e];
const n = this.getComponent(s);
if (!n) {
console.warn(`Component ${s.name} is required by Component ${t.name} on GameObject ${this.name}`);
return null;
}
}
this.components.push(e);
this.gameObjectEventContainer.registerComponent(e);
if (this.$t) {
if (e.enabled) {
e._engine_internal_componentEventContainer.tryCallAwake();
e._engine_internal_componentEventContainer.tryRegisterOnEnable();
e._engine_internal_componentEventContainer.tryRegisterStart();
e._engine_internal_componentEventContainer.tryRegisterUpdate();
this.L.sceneProcessor.tryStartProcessSyncedEvent();
}
}
return e;
}
getComponent(t) {
this.Vt();
const e = this.components;
for (let i = 0; i < e.length; ++i) {
const s = e[i];
if (s instanceof t) return s;
}
return null;
}
getComponents(t) {
this.Vt();
if (!t) return this.components.slice();
const e = this.components;
const i = [];
for (let s = 0; s < e.length; ++s) {
const n = e[s];
if (n instanceof t) {
i.push(n);
}
}
return i;
}
getComponentInChildren(t) {
this.Vt();
const e = this.getComponent(t);
if (e) return e;
let i = null;
this.Nt.iterateChild((e => {
const s = e.gameObject.getComponentInChildren(t);
if (s) {
i = s;
return false;
}
return true;
}));
return i;
}
getComponentsInChildren(t) {
this.Vt();
if (!t) {
const t = this.getComponents();
this.Nt.foreachChild((e => {
t.push(...e.gameObject.getComponentsInChildren());
}));
return t;
} else {
const e = this.getComponents(t);
this.Nt.foreachChild((i => {
const s = i.gameObject.getComponentsInChildren(t);
e.push(...s);
}));
return e;
}
}
foreachComponent(t, e) {
this.Vt();
const i = this.components;
if (!e) {
for (let e = 0; e < i.length; ++e) {
t(i[e]);
}
} else {
for (let s = 0; s < i.length; ++s) {
const n = i[s];
if (n instanceof e) {
t(n);
}
}
}
}
foreachComponentInChildren(t, e) {
this.Vt();
if (!e) {
this.foreachComponent(t);
this.Nt.foreachChild((e => {
e.gameObject.foreachComponentInChildren(t);
}));
} else {
this.foreachComponent(t, e);
this.Nt.foreachChild((i => {
i.gameObject.foreachComponentInChildren(t, e);
}));
}
}
Zt=false;
destroy() {
GameObject.destroyRecursively(this);
this.L.sceneProcessor.tryStartProcessSyncedEvent();
this.L.sceneProcessor.addRemoveGameObject(this);
}
static destroyRecursively(t) {
if (t.Zt) return;
t.Zt = true;
t.te();
const e = t.Nt.children;
for (let t = 0; t < e.length; ++t) {
const i = e[t];
if (i instanceof Transform) GameObject.destroyRecursively(i.gameObject);
}
}
te() {
const t = this.components;
for (let e = 0; e < t.length; ++e) {
const i = t[e];
if (i._engine_internal_destroyed) continue;
if (i.enabled && this.$t) {
i._engine_internal_componentEventContainer.tryRegisterOnDisable();
i._engine_internal_componentEventContainer.tryUnregisterStart();
i._engine_internal_componentEventContainer.tryUnregisterUpdate();
}
i.stopAllCoroutines();
i._engine_internal_componentEventContainer.tryRegisterOnDestroy();
i._engine_internal_destroyed = true;
}
}
removeFromParent() {
this.Nt.unsafeGetObject3D().removeFromParent();
}
removeComponent(t) {
const e = this.components.indexOf(t);
if (e >= 0) {
this.components.splice(e, 1);
}
this.gameObjectEventContainer.unregisterComponent(t);
}
get engine() {
return this.L;
}
get activeInHierarchy() {
return this.$t;
}
set activeInHierarchy(t) {
if (this.$t === t) return;
this.$t = t;
if (this._initialized) {
const t = this.components;
if (this.$t) {
for (let e = 0; e < t.length; ++e) {
const i = t[e];
if (i.enabled) {
i._engine_internal_componentEventContainer.tryCallAwake();
i._engine_internal_componentEventContainer.tryRegisterOnEnable();
i._engine_internal_componentEventContainer.tryRegisterStart();
i._engine_internal_componentEventContainer.tryRegisterUpdate();
}
}
} else {
for (let e = 0; e < t.length; ++e) {
const i = t[e];
if (i.enabled) {
i._engine_internal_componentEventContainer.tryRegisterOnDisable();
i._engine_internal_componentEventContainer.tryUnregisterUpdate();
i.stopAllCoroutines();
}
}
}
}
this.Nt.foreachChild((t => {
const e = t.gameObject;
if (this.$t) {
e.activeInHierarchy = e.Mt;
} else {
e.activeInHierarchy = false;
}
}));
}
Xt(t) {
if (this.$t === t) return;
this.activeInHierarchy = t;
if (this._initialized) this.L.sceneProcessor.tryStartProcessSyncedEvent();
}
get activeSelf() {
return this.Mt;
}
set activeSelf(t) {
this.Vt();
if (this.Mt === t) return;
this.Mt = t;
if (this.Nt.parent instanceof Transform) {
if (this.Nt.parent.gameObject.$t) {
this.Xt(this.Mt);
} else {
this.Xt(false);
}
} else {
this.Xt(this.Mt);
}
}
get transform() {
return this.Nt;
}
get name() {
return this.Nt.unsafeGetObject3D().name;
}
set name(t) {
this.Vt();
this.Nt.unsafeGetObject3D().name = t;
}
get instanceId() {
return this.yt;
}
get initialized() {
return this._initialized;
}
get exists() {
return !this.Zt;
}
Vt() {
if (this.Zt) {
throw new Error("GameObject " + this.name + " is destroyed");
}
}
}