Skip to content

Instantly share code, notes, and snippets.

@mysterycommand
Last active August 27, 2019 18:29
Show Gist options
  • Save mysterycommand/c78c5dc6446dda940d49b36ee6529c45 to your computer and use it in GitHub Desktop.
Save mysterycommand/c78c5dc6446dda940d49b36ee6529c45 to your computer and use it in GitHub Desktop.
Some ideas
/**
* 0.0
*/
// const [factory, system] = createComponent();
/**
* 0.1
*/
// const [activate, update, deactivate] = createComponent(data, system, scheduler);
/**
* 0.2
*/
// createComponent(data, system, scheduler);
// /**
// * scheduler.createComponents();
// * scheduler.updateComponents();
// * scheduler.deleteComponents();
// *
// * ... or maybe just:
// */
// scheduler.step();
/**
* 0.3
*/
// const scheduler = createScheduler();
// const positionData = { x: 0, y: 0 };
// const positionSystem = (/* entity */) => (); // noop
// const position = createComponent(positionData, positionSystem, scheduler);
// const velocityData = { x: 1, y: 1 };
// const velocitySystem = (entity) => {
// // something like this maybe? not sure how this'd work
// const pos = getComponent(position, entity);
// const vel = getComponent(velocity, entity);
// pos.x += vel.x;
// pos.y += vel.y;
// };
// scheduler.step();
/**
* 0.4
*/
function createComponentFactory<T>(name: string, initialData: T): [string, T] {
return () => [name, { ...initialData }];
}
type Vec2 = { x: number, y: number };
const positionFactory = createComponentFactory<Vec2>('position', { x: 0, y: 0 });
const v = () => Math.random() * 2 - 1;
const velocityFactory = createComponentFactory<Vec2>('velocity', { x: v(), y: v() });
type System<T extends {}> = (componentMap: T) => void;
const physicsSystem<{
position: Vec2,
velocity: Vec2,
}> = ({ position, velocity }) => {
position.x += velocity.x;
position.y += velocity.y;
}
function createSumulation() {
private entities: number[] = [];
private components: Component[] = [];
private chunks: Map<string, number[]> = new Map();
private systems: Map<string, System> = new Map();
function createEntities(count: number, components: ComponentFactory[]) {
for (let i = 0; i < count; ++i) {
entities[entities.length] = entities.length;
const componentMap = components.reduce((acc, componentFactory) => {
const [name, data] = componentFactory();
acc[name] = data;
return acc;
}, {});
components[entities.length] = componentMap;
const chunkKey = componentMap.keys().sort().join('|');
chunks.has(chunkKey)
? chunks.get(chunkKey).push(entities.length)
: chunks.set(chunkKey, [entities.length]);
}
}
function registerSystem(chunkKey: string, system: System) {
// missing something about `System<T>` here, but ...
if (systems.has(chunkKey)) {
throw new Error(`System already exists for query: ${chunkKey}`);
}
systems.set(chunkKey, system);
}
function update() {
systems.forEach((system, chunkKey) => {
chunks.get(chunkKey).forEach(entity => system(components.get(entity)));
});
}
return const [ createEntities, registerSystem, update ];
}
const [ createEntities, registerSystem, update ] = createSimulation();
createEntities(10_000, [ positionFactory, velocityFactory ]);
registerSystem('position|velocity', physicsSystem);
update();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment