Skip to content

Instantly share code, notes, and snippets.

@mmzeeman
Last active December 30, 2016 18:38
Show Gist options
  • Save mmzeeman/5267eae52b87800911a04c9dd10a2d22 to your computer and use it in GitHub Desktop.
Save mmzeeman/5267eae52b87800911a04c9dd10a2d22 to your computer and use it in GitHub Desktop.
Web Worker with SAM experiment
<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