278 lines
7.1 KiB
TypeScript
Raw Normal View History

2025-02-20 11:27:28 +08:00
import { Component } from "./Component";
import { EntityId } from "./ECType";
import { EntityManager } from "./EntityManager";
export class Entity {
/**
*
* @type {String}
*/
public name: string;
/**
* ID
* @type {EntityId}
*/
public id: EntityId;
/**
*
* @type {Set<number>}
* @memberof Entity
*/
public tags: Set<number>;
/**
*
* @type {Map<number, number>}
* @memberof Entity
*/
public states: Map<number, number>;
/**
*
* @type {boolean}
*/
public active: boolean = false;
/**
*
* @private
* @type {EntityManager}
*/
public entityManager: EntityManager;
/**
*
* @type {Map<number, Component>}
* @type {number}
* @type {Component}
*/
public readonly components: Map<number, Component> = new Map();
/**
* EntityManager
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public _add(): void {
this.active = true;
for (const component of this.components.values()) {
component._enter();
}
}
/**
*
* @memberof Entity
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public _destroy(): void {
this.removeAllComponents();
this.tags && this.tags.clear();
this.states && this.states.clear();
this.active = false;
this.entityManager = null;
}
/**
*
* @param {number[]} ...tags EntityEntityManager获取指定标签的Entity
*/
public addTag(...tag: number[]): void {
let tags = this.tags;
if (!tags) {
tags = this.tags = new Set<number>();
}
for (let i = 0; i < tag.length; i++) {
tags.add(tag[i]);
this.active && this.entityManager && this.entityManager._addEntityTag(this.id, tag[i]);
}
}
/**
*
* @param {number} tag
*/
public removeTag(tag: number): void {
if (this.tags) {
this.tags.delete(tag);
this.active && this.entityManager && this.entityManager._removeEntityTagById(this.id, tag);
}
}
/**
*
* @param {number} tag
* @returns {boolean}
*/
public hasTag(...tag: number[]): boolean {
let tags = this.tags;
if (!tags) {
return false;
}
for (let i = 0; i < tag.length; i++) {
if (tags.has(tag[i])) {
return true;
}
}
return false;
}
/**
*
* @param {number} componentType
* @returns {T}
*/
public getComponent<T extends Component>(componentType: number): T {
return this.components.get(componentType) as T;
}
/**
*
* @param {Component} component
*/
public addComponent(component: Component): void {
if (this.hasComponent(component.type)) {
throw new Error(`组件{${component.constructor.name}类型:${component.type})已经存在,不允许添加同一类型组件`);
}
this.components.set(component.type, component);
component.entity = this;
component._add();
if (this.active) {
component._enter();
}
}
/**
*
* @param {number} componentType
*/
public removeComponent(componentType: number): void {
const component = this.components.get(componentType);
if (component) {
this.components.delete(componentType);
component._remove();
}
}
/**
*
*/
public removeAllComponents(): void {
for (const component of this.components.values()) {
component._remove();
}
this.components.clear();
}
/**
*
* @param {number} componentType
* @returns {boolean}
*/
public hasComponent(componentType: number): boolean {
return this.components.has(componentType);
}
/**
*
*/
public destroy(): void {
this.entityManager.destroyEntityById(this.id);
}
/**
*
* @param eventName
* @param callback
* @param entityId ID
* @param once
*/
public addEvent(eventName: string, callback: (...args: any[]) => void, once: boolean = false): void {
this.entityManager && this.entityManager._addEvent(eventName, callback, this, once);
}
/**
*
* @param eventName
* @param entityId ID
* @param args
*/
public sendListener(eventName: string, ...args: any[]): void {
this.entityManager && this.entityManager._sendEvent(eventName, this, ...args);
}
public removeListener(eventName: string, callback?: (...args: any[]) => void): void {
this.entityManager && this.entityManager._removeEvent(eventName, this, callback);
}
/**
*
* addState和removeState成对存在
* @param {number} state
* @memberof Entity
*/
public addState(state: number): void {
let states = this.states;
if (!states) {
states = this.states = new Map<number, number>();
}
states.set(state, (states.get(state) || 0) + 1);
}
/**
*
*
* @param {number} state
* @returns {boolean} 0true
* @memberof Entity
*/
public removeState(state: number): boolean {
const states = this.states;
if (!states) {
return false;
}
let stateCount = states.get(state);
if (stateCount) {
// 处理状态计数为0则删除状态
--stateCount;
if (stateCount == 0) {
states.delete(state);
return true;
}
states.set(state, stateCount);
return false;
}
return true;
}
/**
*
* @param {number} state
* @returns {boolean}
* @memberof Entity
*/
public hasState(state: number): boolean {
return this.states && this.states.has(state);
}
/**
*
* @param {number} state
* @memberof Entity
*/
public clearState(state: number): void {
this.states && this.states.delete(state);
}
/**
*
* @memberof Entity
*/
public clearAllStates(): void {
this.states && this.states.clear();
}
}