ecs refactor

This commit is contained in:
Matthieu Jolimaitre 2024-04-09 04:25:34 +02:00
parent 28b026a614
commit f2e5d13000
8 changed files with 410 additions and 170 deletions

View file

@ -195,9 +195,9 @@ export class Vec2 {
return this.add(other.neg());
}
public inside(corner_tl: Vec2, corner_br: Vec2) {
if (!range(corner_tl.x(), corner_br.x()).includes(this.x())) return false;
if (!range(corner_tl.y(), corner_br.y()).includes(this.y())) return false;
public inside(min: Vec2, max: Vec2) {
if (!range(min.x(), max.x()).includes(this.x())) return false;
if (!range(min.y(), max.y()).includes(this.y())) return false;
return true;
}
@ -220,6 +220,10 @@ export class Vec2 {
public overlaps(other: Vec2) {
return this.distance(other) < 1;
}
public clone() {
return new Vec2(this.x(), this.y());
}
}
export function v2(x: number, y: number) {
@ -260,7 +264,8 @@ export async function run(cmd: string, ...args: string[]) {
}
export type Prototyped<P = unknown> = { constructor: { prototype: P } };
export type Constructible<I = unknown> = new (...args: unknown[]) => I;
// deno-lint-ignore no-explicit-any
export type Constructible<I = unknown> = new (...args: any[]) => I;
export class ClassMap<B = unknown> {
private inner;
@ -280,6 +285,10 @@ export class ClassMap<B = unknown> {
assertInstanceOf(value, class_);
return value;
}
has<I extends B, C extends Constructible<I>>(class_: C) {
return this.inner.has(class_.prototype);
}
}
Deno.test("test_classmap", () => {
@ -320,3 +329,83 @@ Deno.test("test_classmap", () => {
export function maybe<T>(item: T) {
return item as T | undefined;
}
export type Awaitable<T = unknown> = T | Promise<T>;
export function first<T>(iter: Iterable<T>) {
for (const item of iter) return item;
return null;
}
export function take_n<T>(iter: Iterable<T>, n: number) {
const result = [] as T[];
for (const item of iter) {
if (result.length >= n) break;
result.push(item);
}
return result;
}
export function* line(from: Vec2, to: Vec2) {
let current = from.clone();
while (current.neq(to)) {
yield current;
if (current.x() - to.x() > 0.5) current = current.sub(v2(1, 0));
if (current.x() - to.x() < -0.5) current = current.add(v2(1, 0));
if (current.y() - to.y() > 0.5) current = current.sub(v2(0, 1));
if (current.y() - to.y() < -0.5) current = current.add(v2(0, 1));
}
}
export function* spiral(origin: Vec2) {
yield origin;
for (const i of range(0, 999)) {
const size = i * 2 + 1;
const corner_A = origin.add(v2(-size / 2, -size / 2));
const corner_B = origin.add(v2(size / 2, -size / 2));
const corner_C = origin.add(v2(size / 2, size / 2));
const corner_D = origin.add(v2(-size / 2, size / 2));
yield* line(corner_A, corner_B);
yield* line(corner_B, corner_C);
yield* line(corner_C, corner_D);
yield* line(corner_D, corner_A);
}
}
// Deno.test("test_spiral", () => {
// // 2 | 10 11 12 13 14
// // 1 | 25 2 3 4 15
// // 0 | 24 9 1 5 16
// // -1 | 23 8 7 6 17
// // -2 | 22 21 20 19 18
// // ---+---------------
// // -2 -1 0 1 2
// const result = [...take_n(spiral(v2(0, 0)), 25)];
// const expects = [
// v2(0, 0),
// v2(1, 1),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// v2(),
// ]
// });