Add material registry with built-in materials
This commit is contained in:
parent
dd27634f0c
commit
bc2c8fa270
2 changed files with 125 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { MaterialRegistry } from "../materials/registry";
|
||||
import {
|
||||
BEHAVIOR_GAS,
|
||||
BEHAVIOR_LIQUID,
|
||||
|
|
@ -36,3 +37,38 @@ describe("material types", () => {
|
|||
expect(sand.density).toBe(1.5);
|
||||
});
|
||||
});
|
||||
|
||||
describe("MaterialRegistry", () => {
|
||||
test("has air at id 0", () => {
|
||||
const reg = new MaterialRegistry();
|
||||
const air = reg.get(0);
|
||||
expect(air.name).toBe("air");
|
||||
expect(air.density).toBe(0);
|
||||
});
|
||||
|
||||
test("has sand registered", () => {
|
||||
const reg = new MaterialRegistry();
|
||||
const sand = reg.getByName("sand");
|
||||
expect(sand).toBeDefined();
|
||||
expect(sand!.behavior).toBe(BEHAVIOR_POWDER);
|
||||
});
|
||||
|
||||
test("all material ids are unique", () => {
|
||||
const reg = new MaterialRegistry();
|
||||
const ids = reg.all().map((m) => m.id);
|
||||
expect(new Set(ids).size).toBe(ids.length);
|
||||
});
|
||||
|
||||
test("all material ids are in range 0-255", () => {
|
||||
const reg = new MaterialRegistry();
|
||||
for (const m of reg.all()) {
|
||||
expect(m.id).toBeGreaterThanOrEqual(0);
|
||||
expect(m.id).toBeLessThanOrEqual(255);
|
||||
}
|
||||
});
|
||||
|
||||
test("get throws for unknown id", () => {
|
||||
const reg = new MaterialRegistry();
|
||||
expect(() => reg.get(254)).toThrow();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
89
src/materials/registry.ts
Normal file
89
src/materials/registry.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import {
|
||||
BEHAVIOR_GAS,
|
||||
BEHAVIOR_POWDER,
|
||||
BEHAVIOR_SOLID,
|
||||
type Material,
|
||||
} from "./types";
|
||||
|
||||
const BUILTIN_MATERIALS: Material[] = [
|
||||
{
|
||||
id: 0,
|
||||
name: "air",
|
||||
behavior: BEHAVIOR_GAS,
|
||||
density: 0,
|
||||
color: [0, 0, 0, 0],
|
||||
hardness: 0,
|
||||
angleOfRepose: 0,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: "sand",
|
||||
behavior: BEHAVIOR_POWDER,
|
||||
density: 1.5,
|
||||
color: [0.76, 0.7, 0.5, 1.0],
|
||||
hardness: 0.1,
|
||||
angleOfRepose: 34,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "dirt",
|
||||
behavior: BEHAVIOR_POWDER,
|
||||
density: 1.3,
|
||||
color: [0.45, 0.32, 0.18, 1.0],
|
||||
hardness: 0.2,
|
||||
angleOfRepose: 40,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "rock",
|
||||
behavior: BEHAVIOR_SOLID,
|
||||
density: 2.5,
|
||||
color: [0.5, 0.5, 0.5, 1.0],
|
||||
hardness: 1.0,
|
||||
angleOfRepose: 90,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "food",
|
||||
behavior: BEHAVIOR_SOLID,
|
||||
density: 1.0,
|
||||
color: [0.2, 0.8, 0.2, 1.0],
|
||||
hardness: 0.0,
|
||||
angleOfRepose: 0,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "home",
|
||||
behavior: BEHAVIOR_SOLID,
|
||||
density: 0,
|
||||
color: [0.3, 0.3, 1.0, 1.0],
|
||||
hardness: 0.0,
|
||||
angleOfRepose: 0,
|
||||
},
|
||||
];
|
||||
|
||||
export class MaterialRegistry {
|
||||
private byId: Map<number, Material> = new Map();
|
||||
private byName: Map<string, Material> = new Map();
|
||||
|
||||
constructor() {
|
||||
for (const m of BUILTIN_MATERIALS) {
|
||||
this.byId.set(m.id, m);
|
||||
this.byName.set(m.name, m);
|
||||
}
|
||||
}
|
||||
|
||||
get(id: number): Material {
|
||||
const m = this.byId.get(id);
|
||||
if (!m) throw new Error(`Unknown material id: ${id}`);
|
||||
return m;
|
||||
}
|
||||
|
||||
getByName(name: string): Material | undefined {
|
||||
return this.byName.get(name);
|
||||
}
|
||||
|
||||
all(): Material[] {
|
||||
return [...this.byId.values()];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue