summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/Makefile.am2
-rw-r--r--examples/cogl-emscripten-hello.c32
-rw-r--r--examples/emscripten-example-js-library.js19
-rw-r--r--examples/emscripten-example-js.h18
4 files changed, 61 insertions, 10 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 404920af..332fa137 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 de3821f8..c5d083d8 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 00000000..fbb3f5e1
--- /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 00000000..cf84ef8b
--- /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_ */