Last active
February 12, 2023 20:43
-
-
Save SamuelDavis/bb8379c0f55cf8261830c5661286df26 to your computer and use it in GitHub Desktop.
An example of typing a proxy object to get/set properties in bitESC's components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
addComponent, | |
addEntity, | |
createWorld, | |
defineComponent, | |
defineQuery, | |
type ComponentType, | |
type IWorld, | |
Types, | |
type ISchema, | |
} from "bitecs"; | |
// Schema | |
const Scalar = { v: Types.ui32 }; | |
const Vector2 = { x: Types.ui32, y: Types.ui32 }; | |
// Components | |
const Position = defineComponent(Vector2); | |
const Speed = defineComponent(Scalar); | |
// Queries | |
export const queryAll = defineQuery([]); | |
// Helpers | |
type SchemaProxy<S extends ISchema, V = number> = { [SK in keyof S]: V }; | |
type GetSchema<T> = T extends ComponentType<infer U> ? U : never; | |
type ComponentMapProxy<C extends ComponentType<any>> = { | |
[CK in keyof C]: SchemaProxy<GetSchema<C[CK]>>; | |
}; | |
function createEntity< | |
W extends IWorld, | |
C extends Record<string, ComponentType<any>> | |
>( | |
world: W, | |
components: C | |
): { eid: ReturnType<typeof addEntity> } & ComponentMapProxy<C> { | |
const eid = addEntity(world); | |
const entity = { eid }; | |
for (const [name, component] of Object.entries(components)) { | |
addComponent(world, component, eid); | |
entity[name] = {}; | |
for (const property in component) | |
if (!property.match(/^Symbol/)) | |
proxy[name] = { | |
get [property]() { | |
return component[property][eid]; | |
}, | |
set [property](v: number) { | |
component[property][eid] = v; | |
}, | |
}; | |
} | |
return entity as any; | |
} | |
// Main | |
export const world = createWorld(); | |
export const position = createEntity(world, { Position }); | |
export const speed = createEntity(world, { Speed }); | |
export const positionAndSpeed = createEntity(world, { Position, Speed }); | |
position.Position.x = 1; | |
position.Position.y = 1; | |
speed.Speed.v = 10; | |
positionAndSpeed.Position.x = 1; | |
positionAndSpeed.Position.y = 1; | |
positionAndSpeed.Speed.v = 2; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment