aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-05-01 13:28:40 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-05-01 13:28:40 -0700
commit50d59708df29324c9c913310b49db93241ca1e48 (patch)
tree28a26b68120f0bd783b8d3d3e68835d807cb5113
parent34a0667d67e4f4679b438277212a446c3d3f3996 (diff)
use requestAnimationFrame
-rw-r--r--src/library_browser.js39
-rw-r--r--src/library_glut.js13
-rw-r--r--system/include/emscripten.h7
-rw-r--r--tests/emscripten_api_browser.cpp17
4 files changed, 54 insertions, 22 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index fa3e051b..fd175df5 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -100,6 +100,18 @@ mergeInto(LibraryManager.library, {
canvas.requestFullScreen();
},
+ requestAnimationFrame: function(func) {
+ if (!window.requestAnimationFrame) {
+ window.requestAnimationFrame = window['requestAnimationFrame'] ||
+ window['mozRequestAnimationFrame'] ||
+ window['webkitRequestAnimationFrame'] ||
+ window['msRequestAnimationFrame'] ||
+ window['oRequestAnimationFrame'] ||
+ window['setTimeout'];
+ }
+ window.requestAnimationFrame(func);
+ },
+
getMovementX: function(delta, event) {
if (!Browser.pointerLock) return delta;
return event.movementX ||
@@ -130,15 +142,24 @@ mergeInto(LibraryManager.library, {
emscripten_set_main_loop: function(func, fps) {
Module['noExitRuntime'] = true;
- fps = fps || 60; // TODO: use requestAnimationFrame
_emscripten_set_main_loop.cancel = false;
var jsFunc = FUNCTION_TABLE[func];
- function doOne() {
- if (_emscripten_set_main_loop.cancel) return;
- jsFunc();
- setTimeout(doOne, 1000/fps); // doing this each time means that on exception, we stop
+
+ if (fps && fps > 0) {
+ function doOne() {
+ if (_emscripten_set_main_loop.cancel) return;
+ jsFunc();
+ setTimeout(doOne, 1000/fps); // doing this each time means that on exception, we stop
+ }
+ setTimeout(doOne, 1000/fps);
+ } else {
+ function doOneRAF() {
+ if (_emscripten_set_main_loop.cancel) return;
+ jsFunc();
+ Browser.requestAnimationFrame(doOneRAF);
+ }
+ Browser.requestAnimationFrame(doOneRAF);
}
- setTimeout(doOne, 1000/fps);
},
emscripten_cancel_main_loop: function(func) {
@@ -153,7 +174,11 @@ mergeInto(LibraryManager.library, {
FUNCTION_TABLE[func]();
};
}
- setTimeout(Browser.asyncCalls[func], millis);
+ if (millis >= 0) {
+ setTimeout(Browser.asyncCalls[func], millis);
+ } else {
+ Browser.requestAnimationFrame(Browser.asyncCalls[func]);
+ }
}
});
diff --git a/src/library_glut.js b/src/library_glut.js
index 9ad83684..b0308acf 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -263,16 +263,7 @@ var LibraryGLUT = {
document['webkitCancelFullScreen'] ||
(function() {});
CFS.apply(document, []);
- },
-
- requestAnimationFrame: function(func) {
- var RAF = window['requestAnimationFrame'] ||
- window['mozRequestAnimationFrame'] ||
- window['webkitRequestAnimationFrame'] ||
- window['msRequestAnimationFrame'] ||
- window['setTimeout'];
- RAF.apply(window, [func]);
- },
+ }
},
glutGetModifiers: function() { return GLUT.modifiers; },
@@ -413,7 +404,7 @@ var LibraryGLUT = {
glutPostRedisplay: function() {
if (GLUT.displayFunc) {
- GLUT.requestAnimationFrame(FUNCTION_TABLE[GLUT.displayFunc]);
+ Browser.requestAnimationFrame(FUNCTION_TABLE[GLUT.displayFunc]);
}
},
diff --git a/system/include/emscripten.h b/system/include/emscripten.h
index fa95645a..4725e68a 100644
--- a/system/include/emscripten.h
+++ b/system/include/emscripten.h
@@ -22,8 +22,8 @@ extern void emscripten_async_run_script(const char *script, int millis);
/*
* Set a C function as the main event loop. The JS environment
* will call that function at a specified number of frames per
- * second. Setting 0 as the fps will use the default browser
- * frame rate.
+ * second. Setting 0 or a negative value as the fps will use
+ * the browser's requestAnimationFrame mechanism.
*/
extern void emscripten_set_main_loop(void (*func)(), int fps);
extern void emscripten_cancel_main_loop();
@@ -33,6 +33,9 @@ extern void emscripten_cancel_main_loop();
* control to the JS event loop. This is done by a setTimeout.
* When building natively this becomes a simple direct call,
* after SDL_Delay (you must include SDL.h for that).
+ *
+ * If millis is negative, the browser's requestAnimationFrame
+ * mechanism is used.
*/
#if EMSCRIPTEN
extern void emscripten_async_call(void (*func)(), int millis);
diff --git a/tests/emscripten_api_browser.cpp b/tests/emscripten_api_browser.cpp
index 0226eae5..a2a19359 100644
--- a/tests/emscripten_api_browser.cpp
+++ b/tests/emscripten_api_browser.cpp
@@ -9,12 +9,25 @@ int last = 0;
extern "C" {
+void mainey() {
+ static int counter = 0;
+ printf("mainey: %d\n", counter++);
+ if (counter == 10) {
+ int result = 1;
+ REPORT_RESULT();
+ }
+}
+
+void four() {
+ printf("four!\n");
+ emscripten_set_main_loop(mainey, 0);
+}
+
void __attribute__((used)) third() {
int now = SDL_GetTicks();
printf("thard! %d\n", now);
assert(fabs(now - last - 1000) < 500);
- int result = 1;
- REPORT_RESULT();
+ emscripten_async_call(four, -1); // triggers requestAnimationFrame
}
void second() {