File size: 1,694 Bytes
b55e088
 
1f0a6e9
b55e088
39b38b8
1f0a6e9
 
 
a69d494
1f0a6e9
 
 
39b38b8
a3ea276
1f0a6e9
 
39b38b8
1f0a6e9
 
ab5ceb7
b55e088
1f0a6e9
c32403d
 
 
39b38b8
c32403d
1f0a6e9
c32403d
821cd82
c32403d
07a4adc
 
1f0a6e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { initGPU } from "./gpu.js";
import { World } from "./world.js";
import { record, replay } from "./plme.js";
import { Agents } from "./agents.js";

const canvas = document.getElementById("viewport");
const log = document.getElementById("log");
const input = document.getElementById("input");

function println(msg) {
  log.textContent += "\n" + msg;
  log.scrollTop = log.scrollHeight;
}

const gpu = await initGPU();
println("GPU mode: " + gpu.mode);

const world = new World(canvas, gpu);
const agents = new Agents(world);

let last = performance.now();

function loop(t) {
  const dt = (t - last) / 1000;
  last = t;

  agents.update(dt);
  world.update(dt);
  world.render();

  requestAnimationFrame(loop);
}

requestAnimationFrame(loop);

input.addEventListener("keydown", e => {
  if (e.key === "Enter") {
    const text = input.value.trim();
    input.value = "";

    const cmd = parseCommand(text);
    record(cmd);
    execute(cmd);
  }
});

function execute(cmd) {
  println("> " + cmd.raw);

  if (cmd.lane === "world") world.apply(cmd);
  if (cmd.lane === "agent") agents.apply(cmd);
  if (cmd.lane === "system" && cmd.action === "replay") {
    println("Replaying PLME stream...");
    replay(execute);
  }
}

function parseCommand(text) {
  const timestamp = performance.now();
  if (text.startsWith("power")) {
    return { lane: "world", payload: { power: parseFloat(text.split(" ")[1]) }, raw: text, timestamp };
  }
  if (text === "spawn") {
    return { lane: "agent", action: "spawn", raw: text, timestamp };
  }
  if (text === "replay") {
    return { lane: "system", action: "replay", raw: text, timestamp };
  }
  return { lane: "text", raw: text, timestamp };
}