use zero timeout instead of a loop
This commit is contained in:
parent
0bc817cde1
commit
d9c3c8db30
2 changed files with 69 additions and 81 deletions
|
|
@ -5,57 +5,52 @@
|
||||||
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
|
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
|
||||||
* @author Fabian Jakobs <fabian AT ajax DOT org>
|
* @author Fabian Jakobs <fabian AT ajax DOT org>
|
||||||
*/
|
*/
|
||||||
require.def("ace/RenderLoop",
|
require.def("ace/RenderLoop", function() {
|
||||||
["ace/lib/oop",
|
|
||||||
"ace/MEventEmitter"],
|
|
||||||
function(oop, MEventEmitter) {
|
|
||||||
|
|
||||||
var RenderLoop = function(fps) {
|
var RenderLoop = function(onRender) {
|
||||||
this.interval = 1000 / fps;
|
this.onRender = onRender;
|
||||||
|
this.pending = false;
|
||||||
|
this.changes = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
oop.implement(this, MEventEmitter);
|
this.schedule = function(change) {
|
||||||
|
this.changes = this.changes | change;
|
||||||
if (window.mozRequestAnimationFrame) {
|
if (!this.pending) {
|
||||||
|
this.pending = true;
|
||||||
this.start = function() {
|
|
||||||
var _self = this;
|
var _self = this;
|
||||||
this.stop();
|
this.setTimeoutZero(function() {
|
||||||
|
_self.pending = false;
|
||||||
this.$onTimeout = function() {
|
_self.onRender(_self.changes);
|
||||||
_self.$dispatchEvent("tick");
|
_self.changes = 0;
|
||||||
window.mozRequestAnimationFrame();
|
})
|
||||||
}
|
}
|
||||||
window.addEventListener("MozBeforePaint", this.$onTimeout, false);
|
|
||||||
window.mozRequestAnimationFrame();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.stop = function() {
|
if (window.postMessage) {
|
||||||
window.removeEventListener("MozBeforePaint", this.$onTimeout, false);
|
|
||||||
|
this.messageName = "zero-timeout-message";
|
||||||
|
|
||||||
|
this.setTimeoutZero = function(callback) {
|
||||||
|
if (!this.attached) {
|
||||||
|
var _self = this;
|
||||||
|
window.addEventListener("message", function(e) {
|
||||||
|
if (e.source == window && _self.callback && e.data == _self.messageName) {
|
||||||
|
e.stopPropagation();
|
||||||
|
_self.callback();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
this.attached = true;
|
||||||
|
}
|
||||||
|
this.callback = callback;
|
||||||
|
window.postMessage(this.messageName, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
this.start = function() {
|
this.setTimeoutZero = function(callback) {
|
||||||
var _self = this;
|
setTimeout(callback, 0);
|
||||||
this.stop();
|
|
||||||
|
|
||||||
this.$timer = setTimeout(onTimeout, 0);
|
|
||||||
|
|
||||||
function onTimeout() {
|
|
||||||
var start = new Date();
|
|
||||||
_self.$dispatchEvent("tick");
|
|
||||||
var end = new Date();
|
|
||||||
var timeout = Math.max(10, _self.interval - (end - start));
|
|
||||||
this.$timer = setTimeout(onTimeout, timeout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.stop = function() {
|
|
||||||
if (this.$timer)
|
|
||||||
clearTimeout(this.$timer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ var VirtualRenderer = function(container) {
|
||||||
self.characterWidth = textLayer.getCharacterWidth();
|
self.characterWidth = textLayer.getCharacterWidth();
|
||||||
self.lineHeight = textLayer.getLineHeight();
|
self.lineHeight = textLayer.getLineHeight();
|
||||||
|
|
||||||
this.$changes = this.$changes | this.CHANGE_FULL;
|
self.$loop.schedule(self.CHANGE_FULL);
|
||||||
});
|
});
|
||||||
event.addListener(this.$gutter, "click", lang.bind(this.$onGutterClick, this));
|
event.addListener(this.$gutter, "click", lang.bind(this.$onGutterClick, this));
|
||||||
event.addListener(this.$gutter, "dblclick", lang.bind(this.$onGutterClick, this));
|
event.addListener(this.$gutter, "dblclick", lang.bind(this.$onGutterClick, this));
|
||||||
|
|
@ -80,11 +80,8 @@ var VirtualRenderer = function(container) {
|
||||||
|
|
||||||
this.$updatePrintMargin();
|
this.$updatePrintMargin();
|
||||||
|
|
||||||
this.loop = new RenderLoop(50);
|
this.$loop = new RenderLoop(lang.bind(this.$renderChanges, this));
|
||||||
this.loop.on("tick", lang.bind(this.$renderChanges, this));
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
this.loop.start();
|
|
||||||
|
|
||||||
this.$changes = this.CHANGE_FULL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
@ -107,7 +104,7 @@ var VirtualRenderer = function(container) {
|
||||||
this.$markerLayer.setDocument(doc);
|
this.$markerLayer.setDocument(doc);
|
||||||
this.$textLayer.setDocument(doc);
|
this.$textLayer.setDocument(doc);
|
||||||
|
|
||||||
this.$changes = this.$changes | this.CHANGE_FULL;
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -128,28 +125,28 @@ var VirtualRenderer = function(container) {
|
||||||
this.$updateLines.lastRow = lastRow;
|
this.$updateLines.lastRow = lastRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$changes = this.$changes | this.CHANGE_FULL;
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers full update of the text layer
|
* Triggers full update of the text layer
|
||||||
*/
|
*/
|
||||||
this.updateText = function() {
|
this.updateText = function() {
|
||||||
this.$changes = this.$changes | this.CHANGE_TEXT;
|
this.$loop.schedule(this.CHANGE_TEXT);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers a full update of all layers
|
* Triggers a full update of all layers
|
||||||
*/
|
*/
|
||||||
this.updateFull = function() {
|
this.updateFull = function() {
|
||||||
this.$changes = this.$changes | this.CHANGE_FULL;
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers resize of the editor
|
* Triggers resize of the editor
|
||||||
*/
|
*/
|
||||||
this.onResize = function() {
|
this.onResize = function() {
|
||||||
this.$changes = this.$changes | this.CHANGE_SIZE;
|
this.$loop.schedule(this.CHANGE_SIZE);
|
||||||
|
|
||||||
var height = dom.getInnerHeight(this.container);
|
var height = dom.getInnerHeight(this.container);
|
||||||
if (this.$size.height != height) {
|
if (this.$size.height != height) {
|
||||||
|
|
@ -160,7 +157,7 @@ var VirtualRenderer = function(container) {
|
||||||
|
|
||||||
if (this.doc) {
|
if (this.doc) {
|
||||||
this.scrollToY(this.getScrollTop());
|
this.scrollToY(this.getScrollTop());
|
||||||
this.$changes = this.$changes | this.CHANGE_FULL;
|
this.$loop.schedule(this.CHANGE_FULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +177,7 @@ var VirtualRenderer = function(container) {
|
||||||
this.setTokenizer = function(tokenizer) {
|
this.setTokenizer = function(tokenizer) {
|
||||||
this.$textLayer.setTokenizer(tokenizer);
|
this.$textLayer.setTokenizer(tokenizer);
|
||||||
|
|
||||||
this.$changes = this.$changes | this.CHANGE_TEXT;
|
this.$loop.schedule(this.CHANGE_TEXT);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$onGutterClick = function(e) {
|
this.$onGutterClick = function(e) {
|
||||||
|
|
@ -201,7 +198,7 @@ var VirtualRenderer = function(container) {
|
||||||
this.$showInvisibles = showInvisibles;
|
this.$showInvisibles = showInvisibles;
|
||||||
this.$textLayer.setShowInvisibles(showInvisibles);
|
this.$textLayer.setShowInvisibles(showInvisibles);
|
||||||
|
|
||||||
this.$changes = this.$changes | this.CHANGE_TEXT;
|
this.$loop.schedule(this.CHANGE_TEXT);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getShowInvisibles = function() {
|
this.getShowInvisibles = function() {
|
||||||
|
|
@ -268,23 +265,22 @@ var VirtualRenderer = function(container) {
|
||||||
this.scrollBar.setScrollTop(this.scrollTop);
|
this.scrollBar.setScrollTop(this.scrollTop);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$renderChanges = function() {
|
this.$renderChanges = function(changes) {
|
||||||
if (!this.$changes)
|
if (!changes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// text, scrolling and resize changes can cause the view port size to change
|
// text, scrolling and resize changes can cause the view port size to change
|
||||||
if (!this.layerConfig ||
|
if (!this.layerConfig ||
|
||||||
this.$changes & this.CHANGE_FULL ||
|
changes & this.CHANGE_FULL ||
|
||||||
this.$changes & this.CHANGE_SIZE ||
|
changes & this.CHANGE_SIZE ||
|
||||||
this.$changes & this.CHANGE_TEXT ||
|
changes & this.CHANGE_TEXT ||
|
||||||
this.$changes & this.CHANGE_LINES ||
|
changes & this.CHANGE_LINES ||
|
||||||
this.$changes & this.CHANGE_SCROLL
|
changes & this.CHANGE_SCROLL
|
||||||
)
|
)
|
||||||
this.$computeLayerConfig();
|
this.$computeLayerConfig();
|
||||||
|
|
||||||
// full
|
// full
|
||||||
if (this.$changes & this.CHANGE_FULL) {
|
if (changes & this.CHANGE_FULL) {
|
||||||
this.$changes = 0;
|
|
||||||
this.$textLayer.update(this.layerConfig);
|
this.$textLayer.update(this.layerConfig);
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
this.$markerLayer.update(this.layerConfig);
|
this.$markerLayer.update(this.layerConfig);
|
||||||
|
|
@ -294,8 +290,8 @@ var VirtualRenderer = function(container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrolling
|
// scrolling
|
||||||
if (this.$changes & this.CHANGE_SCROLL) {
|
if (changes & this.CHANGE_SCROLL) {
|
||||||
if (this.$changes & this.CHANGE_TEXT || this.$changes & this.CHANGE_LINES) {
|
if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) {
|
||||||
this.$textLayer.scrollLines(this.layerConfig);
|
this.$textLayer.scrollLines(this.layerConfig);
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
this.$markerLayer.update(this.layerConfig);
|
this.$markerLayer.update(this.layerConfig);
|
||||||
|
|
@ -308,35 +304,32 @@ var VirtualRenderer = function(container) {
|
||||||
this.$cursorLayer.update(this.layerConfig);
|
this.$cursorLayer.update(this.layerConfig);
|
||||||
}
|
}
|
||||||
this.$updateScrollBar();
|
this.$updateScrollBar();
|
||||||
this.$changes = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$changes & this.CHANGE_TEXT) {
|
if (changes & this.CHANGE_TEXT) {
|
||||||
this.$textLayer.update(this.layerConfig);
|
this.$textLayer.update(this.layerConfig);
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
}
|
}
|
||||||
else if (this.$changes & this.CHANGE_LINES) {
|
else if (changes & this.CHANGE_LINES) {
|
||||||
this.$updateLines();
|
this.$updateLines();
|
||||||
}
|
}
|
||||||
else if (this.$changes & this.CHANGE_SCROLL) {
|
else if (changes & this.CHANGE_SCROLL) {
|
||||||
this.$textLayer.scrollLines(this.layerConfig);
|
this.$textLayer.scrollLines(this.layerConfig);
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
} if (this.$changes & this.CHANGE_GUTTER) {
|
} if (changes & this.CHANGE_GUTTER) {
|
||||||
this.$gutterLayer.update(this.layerConfig);
|
this.$gutterLayer.update(this.layerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$changes & this.CHANGE_CURSOR)
|
if (changes & this.CHANGE_CURSOR)
|
||||||
this.$cursorLayer.update(this.layerConfig);
|
this.$cursorLayer.update(this.layerConfig);
|
||||||
|
|
||||||
if (this.$changes & this.CHANGE_MARKER) {
|
if (changes & this.CHANGE_MARKER) {
|
||||||
this.$markerLayer.update(this.layerConfig);
|
this.$markerLayer.update(this.layerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.$changes & this.CHANGE_SIZE)
|
if (changes & this.CHANGE_SIZE)
|
||||||
this.$updateScrollBar();
|
this.$updateScrollBar();
|
||||||
|
|
||||||
this.$changes = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$computeLayerConfig = function() {
|
this.$computeLayerConfig = function() {
|
||||||
|
|
@ -403,22 +396,22 @@ var VirtualRenderer = function(container) {
|
||||||
|
|
||||||
this.addMarker = function(range, clazz, type) {
|
this.addMarker = function(range, clazz, type) {
|
||||||
return this.$markerLayer.addMarker(range, clazz, type);
|
return this.$markerLayer.addMarker(range, clazz, type);
|
||||||
this.$changes = this.$changes | this.CHANGE_MARKER;
|
this.$loop.schedule(this.CHANGE_MARKER);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.removeMarker = function(markerId) {
|
this.removeMarker = function(markerId) {
|
||||||
this.$markerLayer.removeMarker(markerId);
|
this.$markerLayer.removeMarker(markerId);
|
||||||
this.$changes = this.$changes | this.CHANGE_MARKER;
|
this.$loop.schedule(this.CHANGE_MARKER);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setBreakpoints = function(rows) {
|
this.setBreakpoints = function(rows) {
|
||||||
this.$gutterLayer.setBreakpoints(rows);
|
this.$gutterLayer.setBreakpoints(rows);
|
||||||
this.$changes = this.$changes | this.CHANGE_GUTTER;
|
this.$loop.schedule(this.CHANGE_GUTTER);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateCursor = function(position, overwrite) {
|
this.updateCursor = function(position, overwrite) {
|
||||||
this.$cursorLayer.setCursor(position, overwrite);
|
this.$cursorLayer.setCursor(position, overwrite);
|
||||||
this.$changes = this.$changes | this.CHANGE_CURSOR;
|
this.$loop.schedule(this.CHANGE_CURSOR);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hideCursor = function() {
|
this.hideCursor = function() {
|
||||||
|
|
@ -473,7 +466,7 @@ var VirtualRenderer = function(container) {
|
||||||
|
|
||||||
if (this.scrollTop !== scrollTop) {
|
if (this.scrollTop !== scrollTop) {
|
||||||
this.scrollTop = scrollTop;
|
this.scrollTop = scrollTop;
|
||||||
this.$changes = this.$changes | this.CHANGE_SCROLL;
|
this.$loop.schedule(this.CHANGE_SCROLL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue