Last active
December 30, 2016 18:38
-
-
Save mmzeeman/5267eae52b87800911a04c9dd10a2d22 to your computer and use it in GitHub Desktop.
Web Worker with SAM experiment
This file contains hidden or 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
<html> | |
<head> | |
<title>Web Worker Test</title> | |
</head> | |
<body> | |
<script id="rocket-launcher" type="javascript/worker"> | |
var COUNTER_MAX = 10; | |
var model = { | |
counter: COUNTER_MAX, | |
started: false, | |
launched: false, | |
aborted: false | |
}; | |
var ready = function() { | |
return (model.counter === COUNTER_MAX) && !model.started && !model.launched && !model.aborted ; | |
} | |
var counting = function() { | |
return (model.counter <= COUNTER_MAX) && (model.counter >= 0) && model.started && !model.launched && !model.aborted; | |
} | |
self.addEventListener("message", function(event) { | |
var proposal = event.data; | |
if (counting(model)) { | |
if (model.counter === 0) { | |
model.launched = proposal.launched || false; | |
} else { | |
model.aborted = proposal.aborted || false; | |
if (proposal.counter !== undefined) { | |
model.counter = proposal.counter; | |
} | |
} | |
} else if (ready(model)) { | |
model.started = proposal.started || false; | |
} | |
postMessage(model); | |
}, false); | |
</script> | |
<div id="representation"></div> | |
<script> | |
/* Main */ | |
var blob = new Blob([document.querySelector('#rocket-launcher').textContent]); | |
var worker_url = window.URL.createObjectURL(blob); | |
// View | |
var view = {} ; | |
// Initial State | |
view.init = function (model) { | |
return view.ready(model) ; | |
} | |
// State representation of the ready state | |
view.ready = function(model) { | |
return ( | |
"<p>Counter:" + model.counter + "</p>\n\ | |
<form onSubmit=\"JavaScript:return actions.start();\">\n\ | |
<input type=\"submit\" value=\"Start\">\n\ | |
</form>" | |
) ; | |
} | |
// State representation of the counting state | |
view.counting = function(model) { | |
return ( | |
"<p>Count down:" + model.counter + "</p>\n\ | |
<form onSubmit=\"JavaScript:return actions.abort();\">\n\ | |
<input type=\"submit\" value=\"Abort\">\n\ | |
</form>" | |
) ; | |
} | |
// State representation of the aborted state | |
view.aborted = function(model) { | |
return ("<p>Aborted at Counter:" + model.counter +"</p>\n") ; | |
} | |
// State representation of the launched state | |
view.launched = function(model) { | |
return ("<p>Launched</p>") ; | |
} | |
//display the state representation | |
view.display = function(html) { | |
var stateRepresentation = document.getElementById("representation"); | |
stateRepresentation.innerHTML = html; | |
} | |
var worker = new Worker(worker_url); | |
var state = { | |
ready: function(model) { | |
return ((model.counter === 10) && !model.started && !model.launched && !model.aborted); | |
}, | |
counting: function(model) { | |
return ((model.counter <= 10) && (model.counter >= 0) && model.started && !model.launched && !model.aborted); | |
}, | |
launched: function(model) { | |
return ((model.counter == 0) && model.started && model.launched && !model.aborted); | |
}, | |
aborted: function(model) { | |
return (model.counter <= 10) && (model.counter >= 0) && model.started && !model.launched && model.aborted; | |
} | |
}; | |
// Derive the state representation as a function of the systen | |
// control state | |
function representation(model) { | |
if (state.ready(model)) { | |
return view.ready(model) ; | |
} | |
if (state.counting(model)) { | |
return view.counting(model) ; | |
} | |
if (state.launched(model)) { | |
return view.launched(model) ; | |
} | |
if (state.aborted(model)) { | |
return view.aborted(model) ; | |
} | |
return "Oops"; | |
}; | |
var actions = {}; | |
actions.init = function () { | |
worker.postMessage({ init: true }); | |
return false; | |
}; | |
actions.decrement = function(data) { | |
data.counter = data.counter || 10 ; | |
var d = data ; | |
setTimeout(function() { | |
d.counter = d.counter - 1 ; | |
worker.postMessage(d); | |
}, 1000) ; | |
} | |
actions.start = function () { | |
worker.postMessage({ started: true }); | |
return false; | |
}; | |
actions.launch = function () { | |
worker.postMessage({ launched: true }) ; | |
return false; | |
}; | |
worker.addEventListener("message", function (event) { | |
var model = event.data; | |
view.display(representation(model)); | |
if (state.counting(model)) { | |
if (model.counter>0) { | |
actions.decrement({counter: model.counter}) ; | |
} | |
if (model.counter === 0) { | |
actions.launch() ; | |
} | |
} | |
}, false); | |
actions.init(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment