com.facebook.react.uimanager.events.TouchEvent.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.react.uimanager.events.TouchEvent.java

Source

/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.react.uimanager.events;

import android.view.MotionEvent;
import androidx.annotation.Nullable;
import androidx.core.util.Pools;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.SoftAssertions;

/**
 * An event representing the start, end or movement of a touch. Corresponds to a single {@link
 * android.view.MotionEvent}.
 *
 * <p>TouchEvent coalescing can happen for move events if two move events have the same target view
 * and coalescing key. See {@link TouchEventCoalescingKeyHelper} for more information about how
 * these coalescing keys are determined.
 */
public class TouchEvent extends Event<TouchEvent> {

    private static final int TOUCH_EVENTS_POOL_SIZE = 3;

    private static final Pools.SynchronizedPool<TouchEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(
            TOUCH_EVENTS_POOL_SIZE);

    public static final long UNSET = Long.MIN_VALUE;

    public static TouchEvent obtain(int viewTag, TouchEventType touchEventType, MotionEvent motionEventToCopy,
            long gestureStartTime, float viewX, float viewY,
            TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
        TouchEvent event = EVENTS_POOL.acquire();
        if (event == null) {
            event = new TouchEvent();
        }
        event.init(viewTag, touchEventType, motionEventToCopy, gestureStartTime, viewX, viewY,
                touchEventCoalescingKeyHelper);
        return event;
    }

    private @Nullable MotionEvent mMotionEvent;
    private @Nullable TouchEventType mTouchEventType;
    private short mCoalescingKey;

    // Coordinates in the ViewTag coordinate space
    private float mViewX;
    private float mViewY;

    private TouchEvent() {
    }

    private void init(int viewTag, TouchEventType touchEventType, MotionEvent motionEventToCopy,
            long gestureStartTime, float viewX, float viewY,
            TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
        super.init(viewTag);

        SoftAssertions.assertCondition(gestureStartTime != UNSET, "Gesture start time must be initialized");
        short coalescingKey = 0;
        int action = (motionEventToCopy.getAction() & MotionEvent.ACTION_MASK);
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            touchEventCoalescingKeyHelper.addCoalescingKey(gestureStartTime);
            break;
        case MotionEvent.ACTION_UP:
            touchEventCoalescingKeyHelper.removeCoalescingKey(gestureStartTime);
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
        case MotionEvent.ACTION_POINTER_UP:
            touchEventCoalescingKeyHelper.incrementCoalescingKey(gestureStartTime);
            break;
        case MotionEvent.ACTION_MOVE:
            coalescingKey = touchEventCoalescingKeyHelper.getCoalescingKey(gestureStartTime);
            break;
        case MotionEvent.ACTION_CANCEL:
            touchEventCoalescingKeyHelper.removeCoalescingKey(gestureStartTime);
            break;
        default:
            throw new RuntimeException("Unhandled MotionEvent action: " + action);
        }
        mTouchEventType = touchEventType;
        mMotionEvent = MotionEvent.obtain(motionEventToCopy);
        mCoalescingKey = coalescingKey;
        mViewX = viewX;
        mViewY = viewY;
    }

    @Override
    public void onDispose() {
        Assertions.assertNotNull(mMotionEvent).recycle();
        mMotionEvent = null;
        EVENTS_POOL.release(this);
    }

    @Override
    public String getEventName() {
        return TouchEventType.getJSEventName(Assertions.assertNotNull(mTouchEventType));
    }

    @Override
    public boolean canCoalesce() {
        // We can coalesce move events but not start/end events. Coalescing move events should probably
        // append historical move data like MotionEvent batching does. This is left as an exercise for
        // the reader.
        switch (Assertions.assertNotNull(mTouchEventType)) {
        case START:
        case END:
        case CANCEL:
            return false;
        case MOVE:
            return true;
        default:
            throw new RuntimeException("Unknown touch event type: " + mTouchEventType);
        }
    }

    @Override
    public short getCoalescingKey() {
        return mCoalescingKey;
    }

    @Override
    public void dispatch(RCTEventEmitter rctEventEmitter) {
        TouchesHelper.sendTouchEvent(rctEventEmitter, Assertions.assertNotNull(mTouchEventType), getViewTag(),
                this);
    }

    public MotionEvent getMotionEvent() {
        Assertions.assertNotNull(mMotionEvent);
        return mMotionEvent;
    }

    public float getViewX() {
        return mViewX;
    }

    public float getViewY() {
        return mViewY;
    }
}