@typeonce/ecs
Version:
Entity Component System (ECS) implementation in TypeScript, extensible, working with any renderer, type safe and composable
1 lines • 20.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/registry.ts","../src/ecs.ts","../src/types.ts"],"sourcesContent":["import type { AnySystem, EventMap, SystemExecute } from \"./types\";\n\nexport class SystemRegistry<Tags extends string, E extends EventMap = {}> {\n private systems: Map<Tags, AnySystem<Tags, E>> = new Map();\n private dependencies: Map<Tags, Set<Tags>> = new Map();\n\n registerSystem(system: AnySystem<Tags, E>) {\n this.systems.set(system._tag, system);\n this.dependencies.set(system._tag, new Set(system.dependencies));\n }\n\n private resolveExecutionOrder() {\n const order: Tags[] = [];\n const visited = new Set<Tags>();\n const stack = new Set<Tags>();\n\n const visit = (name: Tags) => {\n if (stack.has(name)) {\n throw new Error(`Circular dependency detected: ${name}`);\n }\n\n if (visited.has(name)) return;\n\n stack.add(name);\n\n const system = this.systems.get(name);\n if (!system) throw new Error(`System not found: ${name}`);\n\n const dependencies = this.dependencies.get(name) ?? new Set();\n for (const dep of dependencies) {\n visit(dep);\n }\n\n visited.add(name);\n stack.delete(name);\n order.push(name);\n };\n\n for (const name of this.systems.keys()) {\n visit(name);\n }\n\n return order;\n }\n\n execute(params: SystemExecute<Tags, E>) {\n const sortedSystemNames = this.resolveExecutionOrder();\n for (const name of sortedSystemNames) {\n const system = this.systems.get(name);\n if (system) {\n system.execute(params);\n }\n }\n }\n}\n","import { SystemRegistry } from \"./registry\";\nimport type {\n AnySystem,\n ComponentClass,\n ComponentClassMap,\n ComponentInstanceMap,\n ComponentType,\n EntityId,\n Equals,\n Event,\n EventMap,\n EventType,\n InitFunctions,\n Mutation,\n SystemExecute,\n World,\n} from \"./types\";\n\nexport const Component = <Tag extends string>(\n tag: Tag\n): {\n new <A extends Record<string, any> = {}>(\n args: Equals<A, {}> extends true\n ? void\n : {\n readonly [P in keyof A as P extends \"_tag\" ? never : P]: A[P];\n }\n ): { readonly _tag: Tag } & A;\n readonly _tag: Tag;\n} => {\n class Base {\n readonly _tag = tag;\n constructor(args: any) {\n if (args) {\n Object.assign(this, args);\n }\n }\n }\n (Base.prototype as any).name = tag;\n (Base as any)._tag = tag;\n return Base as any;\n};\n\nexport const System: <Tags extends string, E extends EventMap = {}>() => <\n A extends Record<string, any> = {}\n>(\n tag: Tags,\n params: {\n execute: (_: SystemExecute<Tags, E> & { input: A }) => void;\n dependencies?: Tags[];\n }\n) => {\n new (\n args: Equals<A, {}> extends true\n ? void\n : {\n readonly [P in keyof A as P extends \"_tag\" ? never : P]: A[P];\n }\n ): {\n readonly _tag: Tags;\n readonly execute: (_: SystemExecute<Tags, E> & { input: A }) => void;\n readonly dependencies: Tags[];\n } & A;\n} =\n () =>\n (tag, { execute, dependencies = [] }) => {\n class Base {\n readonly _tag = tag;\n readonly dependencies = dependencies;\n readonly execute = (_: any) =>\n execute({\n ..._,\n input:\n // @ts-ignore\n this.input as any,\n });\n constructor(args: any) {\n if (args) {\n Object.assign(this, args);\n Object.defineProperty(this, \"input\", {\n get() {\n return args;\n },\n });\n }\n }\n }\n (Base.prototype as any).name = tag;\n (Base as any)._tag = tag;\n return Base as any;\n };\n\nconst getComponentRequired =\n <Tag extends string, E extends EventMap>(world: World<Tag, E>) =>\n <M extends ComponentClassMap>(componentMap: M) =>\n (entityId: EntityId): { entityId: EntityId } & ComponentInstanceMap<M> => {\n const entityComponents = world.components.get(entityId);\n if (entityComponents) {\n const matchedComponents: Partial<ComponentInstanceMap<M>> = {};\n let allMatched = true;\n\n for (const [key, componentClass] of Object.entries(componentMap)) {\n const component = entityComponents.get(componentClass._tag);\n if (component) {\n matchedComponents[key as keyof M] = component as InstanceType<\n M[keyof M]\n >;\n } else {\n allMatched = false;\n break;\n }\n }\n\n if (allMatched) {\n return {\n entityId,\n ...(matchedComponents as ComponentInstanceMap<M>),\n };\n } else {\n throw new Error(\n `Entity ${entityId} does not have all required components.`\n );\n }\n }\n\n throw new Error(`Components for entity ${entityId} not found`);\n };\n\nconst getComponent =\n <Tag extends string, E extends EventMap>(world: World<Tag, E>) =>\n <M extends ComponentClassMap>(componentMap: M) =>\n (\n entityId: EntityId\n ): ({ entityId: EntityId } & ComponentInstanceMap<M>) | undefined => {\n try {\n return getComponentRequired(world)(componentMap)(entityId);\n } catch (error) {\n return undefined;\n }\n };\n\nconst addComponent =\n <Tag extends string, E extends EventMap>(\n world: World<Tag, E>,\n mutations: Mutation[]\n ) =>\n <T extends ComponentType>(\n entityId: EntityId,\n ...components: NoInfer<T>[]\n ): void => {\n if (!world.components.has(entityId)) {\n world.components.set(entityId, new Map());\n }\n\n for (let i = 0; i < components.length; i++) {\n const component = components[i]!;\n mutations.push({ type: \"addComponent\", entityId, component });\n }\n };\n\nconst removeComponent =\n <Tag extends string, E extends EventMap>(\n world: World<Tag, E>,\n mutations: Mutation[]\n ) =>\n <T extends ComponentType>(\n entityId: EntityId,\n componentClass: ComponentClass<T>\n ): void => {\n const entityComponents = world.components.get(entityId);\n if (entityComponents) {\n mutations.push({\n type: \"removeComponent\",\n entityId,\n component: componentClass,\n });\n }\n };\n\nconst createEntity =\n <Tag extends string, E extends EventMap>(world: World<Tag, E>) =>\n (): EntityId => {\n const entityId = world.nextEntityId++ as EntityId;\n world.entities.add(entityId);\n return entityId;\n };\n\nconst destroyEntity =\n <Tag extends string, E extends EventMap>(\n world: World<Tag, E>,\n mutations: Mutation[]\n ) =>\n (entityId: EntityId): void => {\n const wasDeleted = world.entities.delete(entityId);\n if (wasDeleted) {\n mutations.push({ type: \"destroyEntity\", entityId });\n }\n };\n\nconst emit =\n <E extends EventMap>(events: Event<E, EventType<E>>[]) =>\n <ET extends EventType<E>>(event: Event<E, ET>): void => {\n events.push(event);\n };\n\nconst poll =\n <E extends EventMap>(events: Event<E, EventType<E>>[]) =>\n <ET extends EventType<E>>(eventType: ET): Event<E, ET>[] => {\n return events.filter(\n (event): event is Event<E, ET> => event.type === eventType\n );\n };\n\nconst addSystem =\n <Tag extends string, E extends EventMap>(world: World<Tag, E>) =>\n (...systems: AnySystem<Tag, E>[]): void => {\n for (const system of systems) {\n world.registry.registerSystem(system);\n }\n };\n\nexport const query =\n <M extends ComponentClassMap, T extends ComponentType>(\n componentMap: M,\n notComponents?: ComponentClass<NoInfer<T>>[]\n ) =>\n <Tag extends string, E extends EventMap>(\n world: World<Tag, E>\n ): ({ entityId: EntityId } & ComponentInstanceMap<M>)[] => {\n const result: Map<\n EntityId,\n { entityId: EntityId } & ComponentInstanceMap<M>\n > = new Map();\n const get = getComponent(world)(componentMap);\n\n for (const entityId of world.entities) {\n const entity = get(entityId);\n if (entity) {\n result.set(entityId, entity);\n }\n }\n\n if (notComponents) {\n const not = getComponent(world)(\n Object.fromEntries(\n notComponents.map((component) => [component._tag, component])\n )\n );\n\n for (const entityId of world.entities) {\n const entity = not(entityId);\n if (entity) {\n result.delete(entityId);\n }\n }\n }\n\n return Array.from(result.values());\n };\n\nexport const queryRequired =\n <M extends ComponentClassMap>(componentMap: M) =>\n <Tag extends string, E extends EventMap>(\n world: World<Tag, E>\n ): [\n { entityId: EntityId } & ComponentInstanceMap<M>,\n ...({ entityId: EntityId } & ComponentInstanceMap<M>)[]\n ] => {\n const result = query(componentMap)(world);\n\n if (result.length === 0) {\n throw new Error(\n `Missing at least one required entity with the following components: ${Object.keys(\n componentMap\n ).join(\", \")}`\n );\n }\n\n return result as [\n { entityId: EntityId } & ComponentInstanceMap<M>,\n ...({ entityId: EntityId } & ComponentInstanceMap<M>)[]\n ];\n };\n\nexport class ECS<Tags extends string = string, E extends EventMap = {}>\n implements World<Tags, E>\n{\n static create<Tags extends string, E extends EventMap = {}>(\n init: (_: InitFunctions<Tags, E>) => void\n ): World<Tags, E> {\n const world = new ECS<Tags, E>();\n const mutations: Mutation[] = [];\n init({\n addComponent: addComponent(world, mutations),\n createEntity: createEntity(world),\n addSystem: addSystem(world),\n });\n world.applyMutations(mutations);\n return world;\n }\n\n registry: SystemRegistry<Tags, E> = new SystemRegistry();\n entities: Set<EntityId> = new Set();\n components: Map<EntityId, Map<string, ComponentType>> = new Map();\n nextEntityId: EntityId = 0 as EntityId;\n\n public update(deltaTime: number): void {\n const events: Event<E, EventType<E>>[] = [];\n const mutations: Mutation[] = [];\n this.registry.execute({\n world: this,\n deltaTime,\n getComponentRequired: getComponentRequired(this),\n getComponent: getComponent(this),\n createEntity: createEntity(this),\n\n addComponent: addComponent(this, mutations),\n removeComponent: removeComponent(this, mutations),\n destroyEntity: destroyEntity(this, mutations),\n\n addSystem: addSystem(this),\n\n poll: poll(events),\n emit: emit(events),\n });\n\n this.applyMutations(mutations);\n }\n\n private applyMutations(mutations: Mutation[]): void {\n for (let i = 0; i < mutations.length; i++) {\n const mutation = mutations[i]!;\n switch (mutation.type) {\n case \"addComponent\":\n this.components\n .get(mutation.entityId)!\n .set(mutation.component._tag, mutation.component);\n break;\n case \"removeComponent\":\n this.components\n .get(mutation.entityId)!\n .delete(mutation.component._tag);\n break;\n case \"destroyEntity\":\n this.entities.delete(mutation.entityId);\n break;\n }\n }\n }\n}\n","import type { SystemRegistry } from \"./registry\";\n\nexport type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <\n T\n>() => T extends Y ? 1 : 2\n ? true\n : false;\n\nconst EntityIdTypeId: unique symbol = Symbol.for(\"ecs/EntityId\");\n\nexport type EntityId = number & {\n readonly [EntityIdTypeId]: {\n readonly EntityId: \"EntityId\";\n };\n};\n\nexport interface ComponentType {\n readonly _tag: string;\n}\n\nexport interface ComponentClass<T extends ComponentType> {\n new (...args: any[]): Readonly<T>;\n readonly _tag: string;\n}\n\nexport type ComponentClassMap = Record<string, ComponentClass<any>>;\n\nexport type ComponentInstanceMap<T extends ComponentClassMap> = {\n [K in keyof T]: InstanceType<T[K]>;\n};\n\nexport type EventMap = {\n [K: symbol]: any;\n};\n\ntype EventData<E extends EventMap, ET extends EventType<E>> = E[ET];\nexport type EventType<E extends EventMap> = keyof E & symbol;\n\nexport interface Event<E extends EventMap, ET extends EventType<E>> {\n type: ET;\n data: EventData<E, ET>;\n}\n\ntype EventEmit<E extends EventMap> = <ET extends EventType<E>>(\n event: Event<E, ET>\n) => void;\n\ntype EventPoll<E extends EventMap> = <ET extends EventType<E>>(\n eventType: ET\n) => Event<E, ET>[];\n\ntype GetComponentRequired<Tag extends string, E extends EventMap> = (\n world: World<Tag, E>\n) => <M extends ComponentClassMap>(\n componentMap: M\n) => (entityId: EntityId) => { entityId: EntityId } & ComponentInstanceMap<M>;\n\ntype GetComponent<Tag extends string, E extends EventMap> = (\n world: World<Tag, E>\n) => <M extends ComponentClassMap>(\n componentMap: M\n) => (\n entityId: EntityId\n) => ({ entityId: EntityId } & ComponentInstanceMap<M>) | undefined;\n\ntype AddComponent<Tag extends string, E extends EventMap> = (\n world: World<Tag, E>\n) => <T extends ComponentType>(\n entityId: EntityId,\n ...components: NoInfer<T>[]\n) => void;\n\ntype RemoveComponent<Tag extends string, E extends EventMap> = (\n world: World<Tag, E>\n) => <T extends ComponentType>(\n entityId: EntityId,\n componentClass: ComponentClass<T>\n) => void;\n\ntype AddSystem<Tag extends string, E extends EventMap> = (\n world: World<Tag, E>\n) => (...systems: SystemType<Tag, E, any>[]) => void;\n\nexport type InitFunctions<Tag extends string, E extends EventMap> = {\n addComponent: ReturnType<AddComponent<Tag, E>>;\n createEntity: () => EntityId;\n addSystem: ReturnType<AddSystem<Tag, E>>;\n};\n\ntype SystemFunctions<Tag extends string, E extends EventMap> = InitFunctions<\n Tag,\n E\n> & {\n world: World<Tag, E>;\n deltaTime: number;\n getComponentRequired: ReturnType<GetComponentRequired<Tag, E>>;\n getComponent: ReturnType<GetComponent<Tag, E>>;\n removeComponent: ReturnType<RemoveComponent<Tag, E>>;\n destroyEntity: (entityId: EntityId) => void;\n};\n\nexport type SystemExecute<\n Tag extends string,\n E extends EventMap\n> = InitFunctions<Tag, E> &\n SystemFunctions<Tag, E> & { emit: EventEmit<E>; poll: EventPoll<E> };\n\nexport type SystemType<\n Tag extends string,\n E extends EventMap,\n Exe extends SystemExecute<Tag, E>\n> = {\n readonly _tag: Tag;\n readonly dependencies: Tag[];\n readonly execute: (_: Exe) => void;\n};\n\nexport type AnySystem<Tag extends string, E extends EventMap> = SystemType<\n Tag,\n E,\n any\n>;\n\nexport type Mutation =\n | { type: \"addComponent\"; entityId: EntityId; component: ComponentType }\n | { type: \"removeComponent\"; entityId: EntityId; component: ComponentType }\n | { type: \"destroyEntity\"; entityId: EntityId };\n\nexport interface World<Tag extends string, E extends EventMap> {\n entities: Set<EntityId>;\n components: Map<EntityId, Map<string, ComponentType>>;\n nextEntityId: EntityId;\n registry: SystemRegistry<Tag, E>;\n\n update(deltaTime: number): void;\n}\n"],"mappings":"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","names":["SystemRegistry","__publicField","system","order","visited","stack","visit","name","dependencies","dep","params","sortedSystemNames","Component","tag","Base","args","__publicField","System","execute","dependencies","_","getComponentRequired","world","componentMap","entityId","entityComponents","matchedComponents","allMatched","key","componentClass","component","getComponent","addComponent","mutations","components","i","removeComponent","createEntity","destroyEntity","emit","events","event","poll","eventType","addSystem","systems","system","query","notComponents","result","get","entity","not","queryRequired","ECS","_ECS","SystemRegistry","init","deltaTime","mutation","EntityIdTypeId"]}