20
20
#include < GLES/gl.h>
21
21
#include < android/log.h>
22
22
#include < android/sensor.h>
23
+ #include < android/set_abort_message.h>
23
24
#include < android_native_app_glue.h>
24
25
#include < jni.h>
25
26
35
36
#define _LOG (priority, fmt, ...) \
36
37
((void )__android_log_print((priority), (LOG_TAG), (fmt)__VA_OPT__(, ) __VA_ARGS__))
37
38
39
+ #define LOGE (fmt, ...) _LOG(ANDROID_LOG_ERROR, (fmt)__VA_OPT__(, ) __VA_ARGS__)
38
40
#define LOGW (fmt, ...) _LOG(ANDROID_LOG_WARN, (fmt)__VA_OPT__(, ) __VA_ARGS__)
39
41
#define LOGI (fmt, ...) _LOG(ANDROID_LOG_INFO, (fmt)__VA_OPT__(, ) __VA_ARGS__)
40
42
43
+ [[noreturn]] __attribute__((__format__(__printf__, 1 , 2 ))) static void fatal (
44
+ const char * fmt, ...) {
45
+ va_list ap;
46
+ va_start (ap, fmt);
47
+ char * buf;
48
+ if (vasprintf (&buf, fmt, ap) < 0 ) {
49
+ android_set_abort_message (" failed for format error message" );
50
+ } else {
51
+ android_set_abort_message (buf);
52
+ // Also log directly, since the default Android Studio logcat filter hides
53
+ // the backtrace which would otherwise show the abort message.
54
+ LOGE (" %s" , buf);
55
+ }
56
+ std::abort ();
57
+ }
58
+
59
+ #define CHECK_NOT_NULL (value ) \
60
+ do { \
61
+ if ((value) == nullptr ) { \
62
+ fatal (" %s:%d:%s must not be null" , __PRETTY_FUNCTION__, __LINE__, \
63
+ #value); \
64
+ } \
65
+ } while (false )
66
+
41
67
/* *
42
68
* Our saved state data.
43
69
*/
@@ -64,6 +90,20 @@ struct engine {
64
90
int32_t width;
65
91
int32_t height;
66
92
struct saved_state state;
93
+
94
+ void CreateSensorListener (ALooper_callbackFunc callback) {
95
+ CHECK_NOT_NULL (app);
96
+
97
+ sensorManager = ASensorManager_getInstance ();
98
+ if (sensorManager == nullptr ) {
99
+ return ;
100
+ }
101
+
102
+ accelerometerSensor = ASensorManager_getDefaultSensor (
103
+ sensorManager, ASENSOR_TYPE_ACCELEROMETER);
104
+ sensorEventQueue = ASensorManager_createEventQueue (
105
+ sensorManager, app->looper , ALOOPER_POLL_CALLBACK, callback, this );
106
+ }
67
107
};
68
108
69
109
/* *
@@ -269,6 +309,24 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
269
309
}
270
310
}
271
311
312
+ int OnSensorEvent (int /* fd */ , int /* events */ , void * data) {
313
+ CHECK_NOT_NULL (data);
314
+ engine* engine = reinterpret_cast <struct engine *>(data);
315
+
316
+ CHECK_NOT_NULL (engine->accelerometerSensor );
317
+ ASensorEvent event;
318
+ while (ASensorEventQueue_getEvents (engine->sensorEventQueue , &event, 1 ) > 0 ) {
319
+ LOGI (" accelerometer: x=%f y=%f z=%f" , event.acceleration .x ,
320
+ event.acceleration .y , event.acceleration .z );
321
+ }
322
+
323
+ // From the docs:
324
+ //
325
+ // Implementations should return 1 to continue receiving callbacks, or 0 to
326
+ // have this file descriptor and callback unregistered from the looper.
327
+ return 1 ;
328
+ }
329
+
272
330
/* *
273
331
* This is the main entry point of a native application that is using
274
332
* android_native_app_glue. It runs in its own thread, with its own
@@ -284,11 +342,7 @@ void android_main(struct android_app* state) {
284
342
engine.app = state;
285
343
286
344
// Prepare to monitor accelerometer
287
- engine.sensorManager = ASensorManager_getInstance ();
288
- engine.accelerometerSensor = ASensorManager_getDefaultSensor (
289
- engine.sensorManager , ASENSOR_TYPE_ACCELEROMETER);
290
- engine.sensorEventQueue = ASensorManager_createEventQueue (
291
- engine.sensorManager , state->looper , LOOPER_ID_USER, nullptr , nullptr );
345
+ engine.CreateSensorListener (OnSensorEvent);
292
346
293
347
if (state->savedState != nullptr ) {
294
348
// We are starting with a previous saved state; restore from it.
@@ -299,32 +353,19 @@ void android_main(struct android_app* state) {
299
353
300
354
while (true ) {
301
355
// Read all pending events.
302
- int ident;
303
356
int events;
304
357
struct android_poll_source * source;
305
358
306
359
// If not animating, we will block forever waiting for events.
307
360
// If animating, we loop until all events are read, then continue
308
361
// to draw the next frame of animation.
309
- while ((ident = ALooper_pollAll (engine.animating ? 0 : -1 , nullptr , &events,
310
- (void **)&source)) >= 0 ) {
362
+ while ((ALooper_pollAll (engine.animating ? 0 : -1 , nullptr , &events,
363
+ (void **)&source)) >= 0 ) {
311
364
// Process this event.
312
365
if (source != nullptr ) {
313
366
source->process (state, source);
314
367
}
315
368
316
- // If a sensor has data, process it now.
317
- if (ident == LOOPER_ID_USER) {
318
- if (engine.accelerometerSensor != nullptr ) {
319
- ASensorEvent event;
320
- while (ASensorEventQueue_getEvents (engine.sensorEventQueue , &event,
321
- 1 ) > 0 ) {
322
- LOGI (" accelerometer: x=%f y=%f z=%f" , event.acceleration .x ,
323
- event.acceleration .y , event.acceleration .z );
324
- }
325
- }
326
- }
327
-
328
369
// Check if we are exiting.
329
370
if (state->destroyRequested != 0 ) {
330
371
engine_term_display (&engine);
0 commit comments