int32_t android_handle_motion(struct android_app* app, AInputEvent* event) { Director* director = static_cast<AInstance*>(app->userData)->director.get(); switch (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_POINTER_DOWN: { const int32_t index = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; Pointer p = get_pointer_event(event, index); director->input().on_pointer_began(ArrayView<Pointer>(p)); break; } case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_POINTER_UP: { const int32_t index = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; Pointer p = get_pointer_event(event, index); director->input().on_pointer_ended(ArrayView<Pointer>(p)); break; } case AMOTION_EVENT_ACTION_MOVE: { const size_t count = AMotionEvent_getPointerCount(event); auto pointers = std::make_unique<Pointer[]>(count); for (size_t i = 0; i < count; ++i) pointers[i] = get_pointer_event(event, i); director->input().on_pointer_moved( ArrayView<Pointer>(pointers.get(), count)); break; } case AMOTION_EVENT_ACTION_CANCEL: case AMOTION_EVENT_ACTION_OUTSIDE: director->input().on_pointer_canceled(); break; default: break; } return 1; }