+
+redef class App
+ var accelerometer = new AndroidSensor
+ var magnetic_field = new AndroidSensor
+ var gyroscope = new AndroidSensor
+ var light = new AndroidSensor
+ var proximity = new AndroidSensor
+ var sensormanager: ASensorManager
+ var eventqueue: ASensorEventQueue
+ var sensors_support_enabled writable = false
+
+ private fun extern_input_sensor_accelerometer(event: ASensorAccelerometer) do input(event)
+ private fun extern_input_sensor_magnetic_field(event: ASensorMagneticField) do input(event)
+ private fun extern_input_sensor_gyroscope(event: ASensorGyroscope) do input(event)
+ private fun extern_input_sensor_light(event: ASensorLight) do input(event)
+ private fun extern_input_sensor_proximity(event: ASensorProximity) do input(event)
+
+ # Sensors support
+ # The user decides which sensors he wants to use by setting them enabled
+ private fun enable_sensors
+ do
+ if sensors_support_enabled then enable_sensors_management else return
+ if accelerometer.enabled then enable_accelerometer
+ if magnetic_field.enabled then enable_magnetic_field
+ if gyroscope.enabled then enable_gyroscope
+ if light.enabled then enable_light
+ if proximity.enabled then enable_proximity
+ end
+
+ private fun enable_sensors_management
+ do
+ sensormanager = new ASensorManager.get_instance
+ #eventqueue = sensormanager.create_event_queue(new NdkAndroidApp)
+ eventqueue = initialize_event_queue(sensormanager, native_app_glue.looper)
+ end
+
+ # HACK: need a nit method to get mnit_java_app, then we can use the appropriate sensormanager.create_event_queue method to initialize the event queue
+ private fun initialize_event_queue(sensormanager: ASensorManager, looper: ALooper): ASensorEventQueue `{
+ return ASensorManager_createEventQueue(sensormanager, looper, LOOPER_ID_USER, NULL, NULL);
+ `}
+
+ private fun enable_accelerometer
+ do
+ accelerometer.asensor = sensormanager.get_default_sensor(new ASensorType.accelerometer)
+ if accelerometer.asensor.address_is_null then
+ print "Accelerometer sensor unavailable"
+ else
+ if eventqueue.enable_sensor(accelerometer.asensor) < 0 then print "Accelerometer enabling failed"
+ eventqueue.set_event_rate(accelerometer.asensor, accelerometer.event_rate)
+ end
+ end
+
+ private fun enable_magnetic_field
+ do
+ magnetic_field.asensor = sensormanager.get_default_sensor(new ASensorType.magnetic_field)
+ if magnetic_field.asensor.address_is_null then
+ print "Magnetic Field unavailable"
+ else
+ if eventqueue.enable_sensor(magnetic_field.asensor) < 0 then print "Magnetic Field enabling failed"
+ eventqueue.set_event_rate(magnetic_field.asensor, magnetic_field.event_rate)
+ end
+ end
+
+ private fun enable_gyroscope
+ do
+ gyroscope.asensor = sensormanager.get_default_sensor(new ASensorType.gyroscope)
+ if gyroscope.asensor.address_is_null then
+ print "Gyroscope sensor unavailable"
+ else
+ if eventqueue.enable_sensor(gyroscope.asensor) < 0 then print "Gyroscope enabling failed"
+ eventqueue.set_event_rate(gyroscope.asensor, gyroscope.event_rate)
+ end
+ end
+
+ private fun enable_light
+ do
+ light.asensor = sensormanager.get_default_sensor(new ASensorType.light)
+ if light.asensor.address_is_null then
+ print "Light sensor unavailable"
+ else
+ if eventqueue.enable_sensor(light.asensor) < 0 then print "Light enabling failed"
+ eventqueue.set_event_rate(light.asensor, light.event_rate)
+ end
+ end
+
+ private fun enable_proximity
+ do
+ proximity.asensor = sensormanager.get_default_sensor(new ASensorType.proximity)
+ if proximity.asensor.address_is_null then
+ print "Proximity sensor unavailable"
+ else
+ if eventqueue.enable_sensor(proximity.asensor) < 0 then print "Proximity enabling failed"
+ eventqueue.set_event_rate(light.asensor, light.event_rate)
+ end
+ end
+
+ redef fun run
+ do
+ enable_sensors
+
+ super
+ end
+
+ redef fun handle_looper_event(ident, event, data)
+ do
+ super
+ handle_sensor_events(ident)
+ end
+
+ private fun handle_sensor_events(ident: Int) import extern_input_sensor_accelerometer, extern_input_sensor_magnetic_field, extern_input_sensor_gyroscope, extern_input_sensor_light, extern_input_sensor_proximity, eventqueue `{
+ //If a sensor has data, process it
+ if(ident == LOOPER_ID_USER) {
+ //maybe add a boolean to the app to know if we want to use Sensor API or ASensorEvent directly ...
+ ASensorEvent* events = malloc(sizeof(ASensorEvent)*10);
+ int nbevents;
+ ASensorEventQueue* queue = App_eventqueue(recv);
+ while((nbevents = ASensorEventQueue_getEvents(queue, events, 10)) > 0) {
+ int i;
+ for(i = 0; i < nbevents; i++){
+ ASensorEvent event = events[i];
+ switch (event.type) {
+ case ASENSOR_TYPE_ACCELEROMETER:
+ App_extern_input_sensor_accelerometer(recv, &event);
+ break;
+ case ASENSOR_TYPE_MAGNETIC_FIELD:
+ App_extern_input_sensor_magnetic_field(recv, &event);
+ break;
+ case ASENSOR_TYPE_GYROSCOPE:
+ App_extern_input_sensor_gyroscope(recv, &event);
+ break;
+ case ASENSOR_TYPE_LIGHT:
+ App_extern_input_sensor_light(recv, &event);
+ break;
+ case ASENSOR_TYPE_PROXIMITY:
+ App_extern_input_sensor_proximity(recv, &event);
+ break;
+ }
+ }
+ }
+ }
+ `}
+end