Created
April 25, 2018 17:49
-
-
Save bjfish/ff045fd6455ffa16af1030a0cde24cc5 to your computer and use it in GitHub Desktop.
GoL ASC Memory Visualzation index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Conway's Game of Life - AssemblyScript</title> | |
<link rel="icon" href="http://assemblyscript.org/favicon.ico" type="image/x-icon" /> | |
<meta name="viewport" content="user-scalable=0" /> | |
<style> | |
/* html, body { height: 100%; margin: 0; overflow: hidden; color: #111; background: #fff; font-family: sans-serif; } */ | |
/* body { border-top: 2px solid #bc18d4; } | |
h1 { padding: 18px 20px 20px; font-size: 12pt; margin: 0; } | |
a { color: #111; text-decoration: none; } | |
a:hover { color: #bc18d4; text-decoration: underline; } | |
canvas { position: absolute; top: 60px; left: 20px; width: calc(100% - 40px); height: calc(100% - 80px); background: #100707; cursor: cell; user-select: none; } | |
#edge { position: absolute; bottom: 40px; right: 40px; color: #fff; display: none; text-shadow: 0 1px 2px #000; -ms-user-select: none; user-select: none; } */ | |
</style> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/two.js/0.6.0/two.js"></script> | |
</head> | |
<body> | |
<h1> | |
<a href="https://en.wikipedia.org/wiki/Conway's_Game_of_Life">Conway's Game of Life</a> in | |
<a href="http://assemblyscript.org">AssemblyScript</a> | |
( <a href="https://github.com/AssemblyScript/assemblyscript/blob/master/examples/game-of-life/assembly/index.ts">source</a> ) | |
</h1> | |
<div><canvas></canvas></div> | |
<div id="main"></div> | |
<div id="edge">Might be blurry because MS Edge does not support 'image-rendering: crisp-edges' (yet) :-(</div> | |
<script>"use strict"; | |
// Configuration | |
const RGB_ALIVE = 0xD392E6; | |
const RGB_DEAD = 0xA61B85; | |
const BIT_ROT = 10; | |
// Set up the canvas with a 2D rendering context | |
var cnv = document.getElementsByTagName("canvas")[0]; | |
var ctx = cnv.getContext("2d"); | |
var bcr = cnv.getBoundingClientRect(); | |
// Compute the size of the universe (here: 2px per cell) | |
var width = bcr.width >>> 1; | |
var height = bcr.height >>> 1; | |
var size = width * height; | |
var byteSize = (size + size) << 2; // input & output (here: 4b per cell) | |
cnv.width = width; | |
cnv.height = height; | |
cnv.style = ` | |
image-rendering: optimizeSpeed; | |
image-rendering: -moz-crisp-edges; | |
image-rendering: -webkit-optimize-contrast; | |
image-rendering: -o-crisp-edges; | |
image-rendering: optimize-contrast; | |
image-rendering: crisp-edges; | |
image-rendering: pixelated; | |
-ms-interpolation-mode: nearest-neighbor; | |
`; | |
ctx.imageSmoothingEnabled = false; | |
// Compute the size of and instantiate the module's memory | |
var memory = new WebAssembly.Memory({ initial: ((byteSize + 0xffff) & ~0xffff) >>> 16 }); | |
// Fetch and instantiate the module | |
fetch("build/optimized.wasm") | |
.then(response => response.arrayBuffer()) | |
.then(buffer => WebAssembly.instantiate(buffer, { | |
env: { | |
RGB_ALIVE : rgb2le(RGB_ALIVE) | 1, // little endian, LSB must be set | |
RGB_DEAD : rgb2le(RGB_DEAD) & ~1, // little endian, LSB must not be set | |
BIT_ROT, | |
memory, | |
abort: function() {} | |
}, | |
JSMath: Math | |
})) | |
.then(module => { | |
var exports = module.instance.exports; | |
// Initialize the module with the universe's width and height | |
exports.init(width, height); | |
var mem = new Uint32Array(memory.buffer); | |
// Update about 30 times a second | |
(function update() { | |
setTimeout(update, 1000 / 30); | |
mem.copyWithin(0, size, size + size); // copy output to input | |
exports.step(); // perform the next step | |
})(); | |
function updateMem() { | |
console.log("ABou to updateMem"); | |
var two = new Two({ height: 10000, width: 1200 | |
}).appendTo(document.getElementById("main")); | |
var padHeight = 100; | |
var padWidth = 100; | |
var columns = 128; | |
var width = 8; | |
var height = 8; | |
var array = new Uint8Array(mem.buffer); | |
console.log("ABou to fill:" + array.length); | |
for (var i = 0; i < 10000; i++) { | |
var rect = two.makeRectangle(((i % columns) * height) + padWidth, (Math.floor(i / columns) * height) + padHeight, width ,height); | |
rect.fill = array[i] > 0 ? 'green': 'gray'; | |
rect.stroke = 'orangered'; | |
} | |
console.log("ABou to two.update"); | |
two.update(); | |
} | |
setTimeout(updateMem, 3000); | |
// Keep rendering the output at [size, 2*size] | |
var imageData = ctx.createImageData(width, height); | |
var argb = new Uint32Array(imageData.data.buffer); | |
(function render() { | |
requestAnimationFrame(render); | |
argb.set(mem.subarray(size, size + size)); // copy output to image buffer | |
ctx.putImageData(imageData, 0, 0); // apply image buffer | |
})(); | |
// When clicked or dragged, fill the current row and column with random live cells | |
var down = false; | |
[ [cnv, "mousedown"], | |
[cnv, "touchstart"] | |
].forEach(eh => eh[0].addEventListener(eh[1], e => down = true)); | |
[ [document, "mouseup"], | |
[document, "touchend"] | |
].forEach(eh => eh[0].addEventListener(eh[1], e => down = false)); | |
[ [cnv, "mousemove"], | |
[cnv, "touchmove"], | |
[cnv, "mousedown"] | |
].forEach(eh => eh[0].addEventListener(eh[1], e => { | |
if (!down) return; | |
var loc; | |
if (e.touches) { | |
if (e.touches.length > 1) return; | |
loc = e.touches[0]; | |
} else { | |
loc = e; | |
} | |
var bcr = cnv.getBoundingClientRect(); | |
exports.fill((loc.clientX - bcr.left) >>> 1, (loc.clientY - bcr.top) >>> 1, 0.5); | |
})); | |
// :-( | |
if (navigator.userAgent.indexOf(" Edge/") >= 0) document.getElementById("edge").style.display = "block"; | |
}).catch(err => { | |
alert("Failed to load WASM: " + err.message + " (ad blocker, maybe?)"); | |
console.log(err.stack); | |
}); | |
function rgb2le(rgb) { | |
return ((rgb >>> 16) & 0xff) | (rgb & 0xff00) | (rgb & 0xff) << 16; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment