Skip to content

Instantly share code, notes, and snippets.

@SamuelDavis
Last active February 12, 2023 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamuelDavis/bb8379c0f55cf8261830c5661286df26 to your computer and use it in GitHub Desktop.
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
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