diff options
Diffstat (limited to 'src/proxyWorker.js')
-rw-r--r-- | src/proxyWorker.js | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/proxyWorker.js b/src/proxyWorker.js new file mode 100644 index 00000000..8d641b0d --- /dev/null +++ b/src/proxyWorker.js @@ -0,0 +1,128 @@ + +function EventListener() { + this.listeners = {}; + + this.addEventListener = function(event, func) { + if (!this.listeners[event]) this.listeners[event] = []; + this.listeners[event].push(func); + }; + + this.fireEvent = function(event) { + event.preventDefault = function(){}; + + if (event.type in this.listeners) { + this.listeners[event.type].forEach(function(listener) { + listener(event); + }); + } + }; +}; + +var window = this; +var windowExtra = new EventListener(); +for (var x in windowExtra) window[x] = windowExtra[x]; + +window.close = function() { + postMessage({ target: 'window', method: 'close' }); +}; + +var document = new EventListener(); + +document.createElement = function(what) { + switch(what) { + case 'canvas': { + var canvas = new EventListener(); + canvas.ensureData = function() { + if (!canvas.data || canvas.data.width !== canvas.width || canvas.data.height !== canvas.height) { + canvas.data = { + width: canvas.width, + height: canvas.height, + data: new Uint8Array(canvas.width*canvas.height*4) + }; + postMessage({ target: 'canvas', op: 'resize', width: canvas.width, height: canvas.height }); + } + }; + canvas.getContext = function(type) { + assert(type == '2d'); + return { + getImageData: function(x, y, w, h) { + assert(x == 0 && y == 0 && w == canvas.width && h == canvas.height); + canvas.ensureData(); + return { + width: canvas.data.width, + height: canvas.data.height, + data: new Uint8Array(canvas.data.data) // TODO: can we avoid this copy? + }; + }, + putImageData: function(image, x, y) { + canvas.ensureData(); + assert(x == 0 && y == 0 && image.width == canvas.width && image.height == canvas.height); + canvas.data.data.set(image.data); // TODO: can we avoid this copy? + postMessage({ target: 'canvas', op: 'render', image: canvas.data }); + } + }; + }; + return canvas; + } + default: throw 'document.createElement ' + what; + } +}; + +var console = { + log: function(x) { + Module.printErr(x); + } +}; + +Module.canvas = document.createElement('canvas'); + +Module.setStatus = function(){}; + +Module.print = function(x) { + postMessage({ target: 'stdout', content: x }); +}; +Module.printErr = function(x) { + postMessage({ target: 'stderr', content: x }); +}; + +// buffer messages until the program starts to run + +var messageBuffer = null; + +function messageResender() { + if (calledMain) { + assert(messageBuffer && messageBuffer.length > 0); + messageBuffer.forEach(function(message) { + onmessage(message); + }); + messageBuffer = null; + } else { + setTimeout(messageResender, 100); + } +} + +onmessage = function(message) { + if (!calledMain) { + if (!messageBuffer) { + messageBuffer = []; + setTimeout(messageResender, 100); + } + messageBuffer.push(message); + } + switch (message.data.target) { + case 'document': { + document.fireEvent(message.data.event); + break; + } + case 'window': { + window.fireEvent(message.data.event); + break; + } + case 'canvas': { + Module.canvas.fireEvent(message.data.event); + break; + } + default: throw 'wha? ' + message.data.target; + } +}; + |