* Change the implementation of `notify` so that it does not have a return value any more. * Get rid of the only remaning use of the return value of `notify` in the `every` function. * Have a "lock" on each round to ensure that no library or runtime calls `notify` synchronously, causing an update to happen half way through another update, ultimately leading to a dropped frame.
This commit is contained in:
parent
a49d381c09
commit
704da021b0
3 changed files with 29 additions and 14 deletions
|
@ -34,12 +34,10 @@ Elm.Native.Time.make = function(elm) {
|
|||
return A3( Signal.lift2, F2(f), isOn, ticker );
|
||||
}
|
||||
|
||||
function everyWhen(t, isOn) {
|
||||
function every(t) {
|
||||
var clock = Signal.constant(Date.now());
|
||||
var id = setInterval(function tellTime() {
|
||||
if (!elm.notify(clock.id, Date.now())) {
|
||||
clearInterval(id);
|
||||
}
|
||||
setInterval(function() {
|
||||
elm.notify(clock.id, Date.now());
|
||||
}, t);
|
||||
return clock;
|
||||
}
|
||||
|
@ -56,7 +54,7 @@ Elm.Native.Time.make = function(elm) {
|
|||
return elm.Native.Time.values = {
|
||||
fpsWhen : F2(fpsWhen),
|
||||
fps : function(t) { return fpsWhen(t, Signal.constant(true)); },
|
||||
every : function(t) { return everyWhen(t, Signal.constant(true)) },
|
||||
every : every,
|
||||
delay : NS.delay,
|
||||
timestamp : NS.timestamp,
|
||||
since : F2(since),
|
||||
|
|
|
@ -28,10 +28,21 @@ Elm.Native.Window.make = function(elm) {
|
|||
height.defaultNumberOfKids = 0;
|
||||
|
||||
function resizeIfNeeded() {
|
||||
// Do not trigger event if the dimensions have not changed.
|
||||
// This should be most of the time.
|
||||
var w = getWidth();
|
||||
var h = getHeight();
|
||||
if (dimensions.value._0 === w && dimensions.value._1 === h) return;
|
||||
|
||||
setTimeout(function () {
|
||||
// Check again to see if the dimensions have changed.
|
||||
// It is conceivable that the dimensions have changed
|
||||
// again while some other event was being processed.
|
||||
var w = getWidth();
|
||||
var h = getHeight();
|
||||
if (dimensions.value._0 === w && dimensions.value._1 === h) return;
|
||||
elm.notify(dimensions.id, Tuple2(w,h));
|
||||
}, 0);
|
||||
}
|
||||
elm.addListener([dimensions.id], window, 'resize', resizeIfNeeded);
|
||||
|
||||
|
|
|
@ -31,14 +31,20 @@ function init(display, container, module, moduleToReplace) {
|
|||
// defining state needed for an instance of the Elm RTS
|
||||
var inputs = [];
|
||||
|
||||
var updateInProgress = false;
|
||||
function notify(id, v) {
|
||||
var timestep = Date.now();
|
||||
var changed = false;
|
||||
for (var i = inputs.length; i--; ) {
|
||||
// order is important here to avoid short-circuiting
|
||||
changed = inputs[i].recv(timestep, id, v) || changed;
|
||||
if (updateInProgress) {
|
||||
throw new Error(
|
||||
'The notify function has been called synchronously!\n' +
|
||||
'This can lead to frames being dropped.\n' +
|
||||
'Definitely report this to <https://github.com/evancz/Elm/issues>\n');
|
||||
}
|
||||
return changed;
|
||||
updateInProgress = true;
|
||||
var timestep = Date.now();
|
||||
for (var i = inputs.length; i--; ) {
|
||||
inputs[i].recv(timestep, id, v);
|
||||
}
|
||||
updateInProgress = false;
|
||||
}
|
||||
|
||||
var listeners = [];
|
||||
|
|
Loading…
Reference in a new issue