2017-12-07 02:02:22 +01:00
|
|
|
<canvas id="canvas" width="640" height="480"></canvas>
|
2017-12-07 04:37:14 +01:00
|
|
|
<script src="../../node_modules/binaryen/index.js"></script><script>
|
|
|
|
|
|
|
|
// Fetch the .wast (just because we dont's store the .wasm in git)
|
|
|
|
fetch("game-of-life.optimized.wast").then(response => response.text()).then(text => {
|
|
|
|
|
|
|
|
// Convert it to binary format
|
2017-12-09 01:35:18 +01:00
|
|
|
var binary = Binaryen.parseText(text).emitBinary();
|
2017-12-07 04:37:14 +01:00
|
|
|
|
|
|
|
// Instantiate the module
|
2017-12-09 01:35:18 +01:00
|
|
|
var module = new WebAssembly.Module(binary);
|
|
|
|
var instance = new WebAssembly.Instance(module, { /* no imports */ });
|
2017-12-07 04:37:14 +01:00
|
|
|
|
|
|
|
// Set up the canvas with a 2D rendering context
|
|
|
|
var cnv = document.getElementById("canvas");
|
|
|
|
var ctx = cnv.getContext("2d");
|
|
|
|
var w = cnv.width,
|
|
|
|
h = cnv.height,
|
|
|
|
s = w * h, // memory required to store either input or output
|
|
|
|
S = s + s; // total memory required to store input and output
|
|
|
|
|
2017-12-10 21:59:45 +01:00
|
|
|
// Grow the (exported) memory if its size isn't sufficient
|
2017-12-09 01:35:18 +01:00
|
|
|
var memory = instance.exports.memory;
|
2017-12-07 04:37:14 +01:00
|
|
|
if (memory.buffer.byteLength < S)
|
|
|
|
memory.grow(Math.ceil((S - memory.buffer.byteLength) / 65536));
|
|
|
|
|
2017-12-09 01:35:18 +01:00
|
|
|
// Initialize with width and height
|
|
|
|
instance.exports.init(w, h);
|
|
|
|
|
2017-12-10 21:59:45 +01:00
|
|
|
// Fill input at [0, s-1] with random live cells
|
2017-12-07 04:37:14 +01:00
|
|
|
var mem = new Uint8Array(memory.buffer);
|
|
|
|
for (var y = 0; y < h; ++y)
|
|
|
|
for (var x = 0; x < w; ++x)
|
2017-12-07 02:02:22 +01:00
|
|
|
mem[y * w + x] = Math.random() > 0.1 ? 0 : 1;
|
2017-12-07 04:37:14 +01:00
|
|
|
|
|
|
|
// Update about 30 times a second
|
2017-12-09 01:35:18 +01:00
|
|
|
(function update() {
|
2017-12-07 04:37:14 +01:00
|
|
|
setTimeout(update, 33);
|
2017-12-09 01:35:18 +01:00
|
|
|
instance.exports.step();
|
2017-12-07 04:37:14 +01:00
|
|
|
mem.set(mem.subarray(s, S), 0); // copy output -> input
|
2017-12-09 01:35:18 +01:00
|
|
|
})();
|
2017-12-07 04:37:14 +01:00
|
|
|
|
|
|
|
// Keep rendering the output at [s, 2*s-1]
|
2017-12-09 01:35:18 +01:00
|
|
|
(function render() {
|
2017-12-07 02:02:22 +01:00
|
|
|
requestAnimationFrame(render);
|
|
|
|
ctx.clearRect(0, 0, w, h);
|
|
|
|
ctx.fillStyle = "#333";
|
2017-12-07 04:37:14 +01:00
|
|
|
for (var y = 0; y < h; ++y)
|
|
|
|
for (var x = 0; x < w; ++x)
|
2017-12-07 02:02:22 +01:00
|
|
|
if (mem[s + y * w + x])
|
|
|
|
ctx.fillRect(x, y, 1, 1);
|
2017-12-09 01:35:18 +01:00
|
|
|
})();
|
2017-12-07 04:37:14 +01:00
|
|
|
|
2017-12-07 02:02:22 +01:00
|
|
|
}).catch(err => {
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
</script>
|