Created
June 12, 2022 19:39
-
-
Save bcolloran/a58866b3633aadb0aff76d9feb781e11 to your computer and use it in GitHub Desktop.
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 * as bit from "bitecs"; | |
type ComponentBundle = { [componentName: string]: bit.ComponentType<any> }; | |
type NumProxy<T> = { [key in keyof T]: number }; | |
export function makeCmpProxyForEnt<T>(cmp: T, eid: number) { | |
const getterSetterProps = Object.fromEntries( | |
Object.entries(cmp).map(([k, v]) => [ | |
k, | |
{ | |
get() { | |
return v[eid]; | |
}, | |
set(value: number) { | |
v[eid] = value; | |
}, | |
}, | |
]) | |
); | |
const prox = <NumProxy<T>>Object.defineProperties({}, getterSetterProps); | |
return prox; | |
} | |
export function makeCmpProxy<T>(cmp: T) { | |
let eid = 0; | |
const setProxEid = (newEid: number) => { | |
eid = newEid; | |
}; | |
const getterSetterProps = Object.fromEntries( | |
Object.entries(cmp).map(([k, v]) => [ | |
k, | |
{ | |
get() { | |
return v[eid]; | |
}, | |
set(value: number) { | |
v[eid] = value; | |
}, | |
}, | |
]) | |
); | |
const prox = <NumProxy<T>>Object.defineProperties({}, getterSetterProps); | |
return [prox, setProxEid] as const; | |
} | |
type BundleProxy<T> = { [key in keyof T]: NumProxy<T[key]> }; | |
export function makeBundleProxy<T extends ComponentBundle>(cmpBundle: T) { | |
const bundleProx: any = {}; | |
const eidSetters: ((eid: number) => void)[] = []; | |
Object.entries(cmpBundle).forEach(([k, cmp]) => { | |
const [prox, eidSetter] = makeCmpProxy(cmp); | |
bundleProx[k] = prox; | |
eidSetters.push(eidSetter); | |
}); | |
const setProxEid = (newEid: number) => { | |
eidSetters.forEach((eidSetter) => eidSetter(newEid)); | |
}; | |
return [<BundleProxy<T>>bundleProx, setProxEid] as const; | |
} | |
type BundleMutatorFn<T> = (bundle: { | |
[key in keyof T]: NumProxy<T[key]>; | |
}) => void; | |
export function createComponentBundleForEachSystem<T extends ComponentBundle>( | |
cmpBundle: T, | |
bundleMutator: BundleMutatorFn<T> | |
): bit.System { | |
const query = bit.defineQuery(Object.values(cmpBundle)); | |
const [prox, eidSetter] = makeBundleProxy(cmpBundle); | |
return function (world) { | |
const eids = query(world); | |
for (let eid of eids) { | |
eidSetter(eid); | |
bundleMutator(prox); | |
} | |
return world; | |
}; | |
} | |
const vec2_f32 = { x: bit.Types.f32, y: bit.Types.f32 }; | |
const size2_i16 = { width: bit.Types.i16, height: bit.Types.i16 }; | |
const index2_i16 = { i: bit.Types.i16, j: bit.Types.i16 }; | |
const Position = bit.defineComponent(vec2_f32); | |
const Velocity = bit.defineComponent(vec2_f32); | |
const GridIndex = bit.defineComponent(index2_i16); | |
const Size = bit.defineComponent(size2_i16); | |
createComponentBundleForEachSystem( | |
{ pos: Position, vel: Velocity, GridIndex, Size}, | |
(ent) => { | |
ent.pos.x += ent.vel.y | |
ent.GridIndex.j | |
ent.Size.height | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment