diff --git a/examples/smoketest-webworker/index.html b/examples/smoketest-webworker/index.html new file mode 100644 index 0000000..39bfc07 --- /dev/null +++ b/examples/smoketest-webworker/index.html @@ -0,0 +1,20 @@ + + + + JS Marketplace: Smoketest with Web Workers + + + + + + + +

Smoketest with Web Workers

+
+ + diff --git a/examples/smoketest-webworker/index.js b/examples/smoketest-webworker/index.js new file mode 100644 index 0000000..5ec3112 --- /dev/null +++ b/examples/smoketest-webworker/index.js @@ -0,0 +1,46 @@ +var G; +$(document).ready(function () { + var World = Minimart.World; + var Actor = Minimart.Actor; + var sub = Minimart.sub; + var pub = Minimart.pub; + var __ = Minimart.__; + var _$ = Minimart._$; + + G = new Minimart.Ground(function () { + console.log('starting ground boot'); + + World.spawn({ + name: 'GestaltDisplay', + handleEvent: function (e) { + if (e.type === "routes") { + var gd = document.getElementById('gestalt-display'); + var t = document.createTextNode(G.world.textProcessTree() + '\n' + + e.gestalt.pretty()); + gd.innerHTML = ''; + gd.appendChild(t); + } + } + }, [sub(__, 0, 10), pub(__, 0, 10)]); + + World.spawn(new Actor(function () { + this.counter = 0; + this.step = function () { + if (this.listenerExists && this.counter < 10) { + World.send(["beep", this.counter++]); + return true; + } else { + return false; + } + }; + + Actor.advertise(function () { return ["beep", __]; }); + Actor.observeSubscribers( + function () { return ["beep", __]; }, + { presence: "listenerExists" }); + })); + + World.spawn(new Minimart.Worker("worker.js")); + }); + G.startStepping(); +}); diff --git a/examples/smoketest-webworker/worker.js b/examples/smoketest-webworker/worker.js new file mode 100644 index 0000000..2460a18 --- /dev/null +++ b/examples/smoketest-webworker/worker.js @@ -0,0 +1,19 @@ +importScripts("../../dist/minimart.js"); +var World = Minimart.World; +var Actor = Minimart.Actor; +var sub = Minimart.sub; +var pub = Minimart.pub; +var __ = Minimart.__; +var _$ = Minimart._$; + +new Minimart.WorkerGround(function () { + console.log('starting worker boot'); + World.spawn(new Actor(function () { + Actor.subscribe( + function () { return ["beep", _$("counter")]; }, + { metaLevel: 1 }, + function (counter) { + console.log("beep!", counter); + }); + })); +}).startStepping(); diff --git a/src/main.js b/src/main.js index f957905..7156a0f 100644 --- a/src/main.js +++ b/src/main.js @@ -10,3 +10,7 @@ module.exports.Ground = require("./ground.js").Ground; module.exports.Actor = require("./actor.js").Actor; module.exports.Spy = require("./spy.js").Spy; module.exports.WakeDetector = require("./wake-detector.js").WakeDetector; + +var Worker = require("./worker.js"); +module.exports.Worker = Worker.Worker; +module.exports.WorkerGround = Worker.WorkerGround; diff --git a/src/worker.js b/src/worker.js new file mode 100644 index 0000000..407571c --- /dev/null +++ b/src/worker.js @@ -0,0 +1,56 @@ +/* Web Worker interface */ +var Ground = require("./ground.js").Ground; +var Util = require("./util.js"); +var Codec = require("./codec.js"); + +var Minimart = require("./minimart.js"); +var World = Minimart.World; +var sub = Minimart.sub; +var pub = Minimart.pub; +var __ = Minimart.__; + +var BuiltinWorker = typeof window !== 'undefined' && window.Worker; + +/////////////////////////////////////////////////////////////////////////// + +function Worker(scriptUrl) { + this.scriptUrl = scriptUrl; + this.w = new BuiltinWorker(scriptUrl); +} + +Worker.prototype.boot = function () { + this.w.onmessage = World.wrap(function (e) { + console.log("Received from worker", JSON.stringify(e.data)); + World.current().enqueueAction(World.activePid(), Codec.decodeAction(e.data)); + }); +}; + +Worker.prototype.handleEvent = function (e) { + console.log("Sending to worker", JSON.stringify(Codec.encodeEvent(e))); + this.w.postMessage(Codec.encodeEvent(e)); +}; + +/////////////////////////////////////////////////////////////////////////// + +function WorkerGround(bootFn) { + var self = this; + Ground.call(this, bootFn); + onmessage = function (e) { + console.log("Received from main page", JSON.stringify(e.data)); + self.world.handleEvent(Codec.decodeEvent(e.data)); + self.startStepping(); + }; +} + +WorkerGround.prototype = Util.extend({}, Ground.prototype); + +WorkerGround.prototype.enqueueAction = function (pid, action) { + console.log("Sending to main page", JSON.stringify(Codec.encodeAction(action))); + postMessage(Codec.encodeAction(action)); + console.log("Sent to main page"); +}; + +/////////////////////////////////////////////////////////////////////////// + +module.exports.Worker = Worker; +module.exports.WorkerGround = WorkerGround;