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} * @memberof Entity */ public tags: Set; /** * 实体状态 * @type {Map} * @memberof Entity */ public states: Map; /** * 是否被激活 (添加到实体管理器时激活) * @type {boolean} */ public active: boolean = false; /** * 所属实体管理器 (实体创建后直接赋值) * @private * @type {EntityManager} */ public entityManager: EntityManager; /** * 所有组件 * @type {Map} * @type {number} 组件类型 * @type {Component} 组件 */ public readonly components: Map = 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 标签除了表示Entity,还可以通过EntityManager获取指定标签的Entity */ public addTag(...tag: number[]): void { let tags = this.tags; if (!tags) { tags = this.tags = new Set(); } 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(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(); } states.set(state, (states.get(state) || 0) + 1); } /** * 删除状态 * * @param {number} state 状态类型 * @returns {boolean} 如果计数为0或状态不存在,则返回true * @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(); } }