UNPKG

11.3 kBSource Map (JSON)View Raw
1{"version":3,"sources":["../src/ComponentManager.ts"],"names":["Component","data","ComponentManager","clazz","components","entities","lookup","entity","length","component","push","componentIndex","pop","entity2","i","srcIndex","destIndex","srcComponent","srcEntity","direction","next","index","componentIdx","Object","keys","entityInNum","Number","EMPTY","callback","getCount","getComponent","result"],"mappings":"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","sourcesContent":["import { EMPTY, Entity } from './Entity';\n\ntype NonFunctionPropertyNames<T> = {\n [K in keyof T]: T[K] extends (args: unknown) => void ? never : K;\n}[keyof T];\nexport type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;\n\nexport type ComponentClassType<P> = new (\n data: Partial<NonFunctionProperties<P>>,\n) => Component<P> & P;\n\nexport abstract class Component<P> {\n constructor(data?: Partial<NonFunctionProperties<P>>) {\n //\n }\n}\n\n/**\n * 管理某一类 Component,尽可能做到 AoS 而非 SoA\n * @see https://wickedengine.net/2019/09/29/entity-component-system/\n * @see https://github.com/turanszkij/WickedEngine/blob/master/WickedEngine/wiECS.h\n */\n// tslint:disable-next-line:max-classes-per-file\nexport class ComponentManager<P> {\n private clazz: ComponentClassType<P>;\n private components: Array<Component<P> & P> = [];\n private entities: Entity[] = [];\n\n /**\n * 不在 Entity 中维护拥有的 Component 列表,反之亦然\n */\n private lookup: Record<Entity, number> = {};\n\n constructor(clazz: ComponentClassType<P>) {\n this.clazz = clazz;\n }\n\n public clear() {\n this.components = [];\n this.entities = [];\n this.lookup = {};\n }\n\n public contains(entity: Entity) {\n return this.lookup[entity] > -1;\n }\n\n public create(entity: Entity, data?: Partial<NonFunctionProperties<P>>) {\n this.lookup[entity] = this.components.length;\n const component = new this.clazz(data || {});\n this.components.push(component);\n this.entities.push(entity);\n return component;\n }\n\n public remove(entity: Entity) {\n const componentIndex = this.lookup[entity];\n if (componentIndex > -1) {\n if (componentIndex < this.components.length - 1) {\n // 将待删除元素和最后一个元素交换\n // C++ 中有 std::move 这样的操作,避免数据的拷贝\n // @see https://github.com/turanszkij/WickedEngine/blob/master/WickedEngine/wiECS.h#L169\n this.components[componentIndex] = this.components[\n this.components.length - 1\n ];\n this.entities[componentIndex] = this.entities[this.entities.length - 1];\n this.lookup[this.entities[componentIndex]] = componentIndex;\n }\n }\n\n // 待删除元素已经移动到了最后一个\n this.components.pop();\n this.entities.pop();\n delete this.lookup[entity];\n }\n\n public removeKeepSorted(entity: Entity) {\n const componentIndex = this.lookup[entity];\n if (componentIndex > -1) {\n const entity2 = this.entities[componentIndex];\n\n if (componentIndex < this.components.length - 1) {\n // Move every component left by one that is after this element:\n for (let i = componentIndex + 1; i < this.components.length; ++i) {\n this.components[i - 1] = this.components[i];\n }\n // Move every entity left by one that is after this element and update lut:\n for (let i = componentIndex + 1; i < this.entities.length; ++i) {\n this.entities[i - 1] = this.entities[i];\n this.lookup[this.entities[i - 1]] = i - 1;\n }\n }\n\n this.components.pop();\n this.entities.pop();\n delete this.lookup[entity2];\n }\n }\n\n public moveItem(srcIndex: number, destIndex: number) {\n if (srcIndex === destIndex) {\n return;\n }\n\n // Save the moved component and entity:\n const srcComponent = this.components[srcIndex];\n const srcEntity = this.entities[srcIndex];\n\n // Every other entity-component that's in the way gets moved by one and lut is kept updated:\n const direction = srcIndex < destIndex ? 1 : -1;\n for (let i = srcIndex; i !== destIndex; i += direction) {\n const next = i + direction;\n this.components[i] = this.components[next];\n this.entities[i] = this.entities[next];\n this.lookup[this.entities[i]] = i;\n }\n\n // Saved entity-component moved to the required position:\n this.components[destIndex] = srcComponent;\n this.entities[destIndex] = srcEntity;\n this.lookup[srcEntity] = destIndex;\n }\n\n public getEntity(index: number) {\n return this.entities[index];\n }\n\n /**\n * 由于缺少类似 C++ 的重载操作符,没法通过 [下标] 直接访问。因此只能增加该方法用于遍历。\n */\n public getComponent(index: number) {\n return this.components[index];\n }\n\n public getComponentByEntity(entity: Entity) {\n const componentIndex = this.lookup[entity];\n if (componentIndex > -1) {\n return this.components[componentIndex];\n }\n return null;\n }\n\n public getCount() {\n return this.components.length;\n }\n\n public getEntityByComponentIndex(componentIdx: number) {\n for (const entity of Object.keys(this.lookup)) {\n const entityInNum = Number(entity);\n if (this.lookup[entityInNum] === componentIdx) {\n return entityInNum;\n }\n }\n return EMPTY;\n }\n\n public find(callback: (component: Component<P> & P, i: number) => boolean) {\n for (let i = 0; i < this.getCount(); i++) {\n const component = this.getComponent(i);\n if (callback(component, i)) {\n return component;\n }\n }\n return null;\n }\n\n public findIndex(\n callback: (component: Component<P> & P, i: number) => boolean,\n ) {\n for (let i = 0; i < this.getCount(); i++) {\n const component = this.getComponent(i);\n if (callback(component, i)) {\n return i;\n }\n }\n return -1;\n }\n\n public forEach(\n callback: (entity: Entity, component: Component<P> & P) => void,\n ) {\n for (const entity of Object.keys(this.lookup)) {\n const entityInNum = Number(entity);\n const componentIndex = this.lookup[entityInNum];\n callback(entityInNum, this.getComponent(componentIndex));\n }\n }\n\n public map(callback: (entity: Entity, component: Component<P> & P) => void) {\n const result = [];\n for (const entity of Object.keys(this.lookup)) {\n const entityInNum = Number(entity);\n const componentIndex = this.lookup[entityInNum];\n result.push(callback(entityInNum, this.getComponent(componentIndex)));\n }\n return result;\n }\n}\n"],"file":"ComponentManager.js"}
\No newline at end of file