[cogl/cogl-1.16] emscripten-hello: improve mainloop integration



commit 9ef37423fcfe863523f185f1ee671f7aa3f9883e
Author: Robert Bragg <robert linux intel com>
Date:   Mon May 13 13:28:15 2013 +0100

    emscripten-hello: improve mainloop integration
    
    Instead of simply relying on the emscripten mainloop api to wake us up
    periodically so that we can poll for SDL events we now pause the
    emscripten mainloop whenever no redraw is queued and instead hook an
    input event listener into the real browser mainloop to resume the
    emscripten mainloop whenever input is received. This way the example
    can go to sleep while there's no input to handle.
    
    This provides a simple example of binding custom javascript into native
    code.
    
    Reviewed-by: Neil Roberts <neil linux intel com>
    
    (cherry picked from commit a8b1e2eda491dc7c44c84cd47e160c7b8ba0f792)

 examples/Makefile.am                      |    2 +-
 examples/cogl-emscripten-hello.c          |   32 ++++++++++++++++++++--------
 examples/emscripten-example-js-library.js |   19 +++++++++++++++++
 examples/emscripten-example-js.h          |   18 ++++++++++++++++
 4 files changed, 61 insertions(+), 10 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 404920a..332fa13 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -105,7 +105,7 @@ endif
 
 if USING_EMSCRIPTEN
 %.html: %.o $(top_builddir)/cogl/.libs/libcogl2.so $(top_builddir)/deps/glib/.libs/libglib.a
-       $(CC) $(AM_CFLAGS) $(CFLAGS) -o $@ $^
+       $(CC) $(AM_CFLAGS) $(CFLAGS) --js-library $(top_srcdir)/examples/emscripten-example-js-library.js -o 
$@ $^
 
 all-local: $(addsuffix .html, $(programs))
 endif
diff --git a/examples/cogl-emscripten-hello.c b/examples/cogl-emscripten-hello.c
index de3821f..c5d083d 100644
--- a/examples/cogl-emscripten-hello.c
+++ b/examples/cogl-emscripten-hello.c
@@ -2,9 +2,10 @@
 #include <stdio.h>
 #include <SDL.h>
 #include <emscripten.h>
+#include "emscripten-example-js.h"
 
-/* This short example is just to demonstrate mixing SDL with Cogl as a
-   simple way to get portable support for events */
+/* This short example is just to demonstrate using Cogl with
+ * Emscripten using SDL to receive input events */
 
 typedef struct Data
 {
@@ -40,10 +41,6 @@ handle_event (Data *data, SDL_Event *event)
 {
   switch (event->type)
     {
-    case SDL_VIDEOEXPOSE:
-      data->redraw_queued = TRUE;
-      break;
-
     case SDL_MOUSEMOTION:
       {
         int width =
@@ -76,15 +73,23 @@ static void
 mainloop (void)
 {
   SDL_Event event;
+
   while (SDL_PollEvent (&event))
     {
       handle_event (&data, &event);
       cogl_sdl_handle_event (ctx, &event);
     }
 
-  redraw (&data);
-  data.redraw_queued = FALSE;
-  data.ready_to_draw = FALSE;
+  if (data.redraw_queued && data.ready_to_draw)
+    {
+      data.redraw_queued = FALSE;
+      data.ready_to_draw = FALSE;
+      redraw (&data);
+    }
+
+  /* NB: The mainloop will be automatically resumed if user input is received */
+  if (!data.redraw_queued)
+    emscripten_pause_main_loop ();
 
   cogl_sdl_idle (ctx);
 }
@@ -127,6 +132,15 @@ main (int argc, char **argv)
   data.redraw_queued = TRUE;
   data.ready_to_draw = TRUE;
 
+  /* The emscripten mainloop isn't event driven, it's periodic and so
+   * we aim to pause the emscripten mainlooop whenever we don't have a
+   * redraw queued. What we do instead is hook into the real browser
+   * mainloop using this javascript binding api to add an input event
+   * listener that will resume the emscripten mainloop whenever input
+   * is received.
+   */
+  example_js_add_input_listener ();
+
   emscripten_set_main_loop (mainloop, -1, TRUE);
 
   cogl_object_unref (ctx);
diff --git a/examples/emscripten-example-js-library.js b/examples/emscripten-example-js-library.js
new file mode 100644
index 0000000..fbb3f5e
--- /dev/null
+++ b/examples/emscripten-example-js-library.js
@@ -0,0 +1,19 @@
+//"use strict";
+
+var LibraryEXAMPLE = {
+    $EXAMPLE__deps: ['$Browser'],
+    $EXAMPLE: {
+       receiveEvent: function(event) {
+           Browser.mainLoop.resume();
+       },
+    },
+    example_js_add_input_listener: function() {
+       ['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll',
+         'mousewheel', 'mouseout'].forEach(function(event) {
+           Module['canvas'].addEventListener(event, EXAMPLE.receiveEvent, true);
+       });
+    }
+};
+
+autoAddDeps(LibraryEXAMPLE, '$EXAMPLE');
+mergeInto(LibraryManager.library, LibraryEXAMPLE);
diff --git a/examples/emscripten-example-js.h b/examples/emscripten-example-js.h
new file mode 100644
index 0000000..cf84ef8
--- /dev/null
+++ b/examples/emscripten-example-js.h
@@ -0,0 +1,18 @@
+
+#ifndef _EMSCRIPTEN_EXAMPLE_JS_H_
+#define _EMSCRIPTEN_EXAMPLE_JS_H_
+
+/*
+ * example_js_add_input_listener:
+ *
+ * Adds an input event listener to the browser's mainloop and whenever
+ * input is received then the emscripten mainloop is resumed, if it
+ * has been paused.
+ *
+ * This means we don't have to poll SDL for events and can instead go
+ * to sleep waiting in the browser mainloop when there's no input and
+ * nothing being animated.
+ */
+void example_js_add_input_listener (void);
+
+#endif /* _EMSCRIPTEN_EXAMPLE_JS_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]