mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-06-17 14:21:08 +00:00
Use Handlers instead of Timers for one-shot events
This commit is contained in:
@@ -95,7 +95,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
private int lastButtonState = 0;
|
private int lastButtonState = 0;
|
||||||
|
|
||||||
// Only 2 touches are supported
|
// Only 2 touches are supported
|
||||||
private Timer touchTimer;
|
|
||||||
private final TouchContext[] touchContextMap = new TouchContext[2];
|
private final TouchContext[] touchContextMap = new TouchContext[2];
|
||||||
private long threeFingerDownTime = 0;
|
private long threeFingerDownTime = 0;
|
||||||
|
|
||||||
@@ -479,15 +478,14 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
inputManager.registerInputDeviceListener(keyboardTranslator, null);
|
inputManager.registerInputDeviceListener(keyboardTranslator, null);
|
||||||
|
|
||||||
// Initialize touch contexts
|
// Initialize touch contexts
|
||||||
touchTimer = new Timer("TouchTimer", true);
|
|
||||||
for (int i = 0; i < touchContextMap.length; i++) {
|
for (int i = 0; i < touchContextMap.length; i++) {
|
||||||
if (!prefConfig.touchscreenTrackpad) {
|
if (!prefConfig.touchscreenTrackpad) {
|
||||||
touchContextMap[i] = new AbsoluteTouchContext(conn, i, streamView, touchTimer);
|
touchContextMap[i] = new AbsoluteTouchContext(conn, i, streamView);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
touchContextMap[i] = new RelativeTouchContext(conn, i,
|
touchContextMap[i] = new RelativeTouchContext(conn, i,
|
||||||
REFERENCE_HORIZ_RES, REFERENCE_VERT_RES,
|
REFERENCE_HORIZ_RES, REFERENCE_VERT_RES,
|
||||||
streamView, prefConfig, touchTimer);
|
streamView, prefConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,10 +1029,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
if (touchTimer != null) {
|
|
||||||
touchTimer.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
|
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
|
||||||
if (controllerHandler != null) {
|
if (controllerHandler != null) {
|
||||||
inputManager.unregisterInputDeviceListener(controllerHandler);
|
inputManager.unregisterInputDeviceListener(controllerHandler);
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import android.view.View;
|
|||||||
import com.limelight.nvstream.NvConnection;
|
import com.limelight.nvstream.NvConnection;
|
||||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class AbsoluteTouchContext implements TouchContext {
|
public class AbsoluteTouchContext implements TouchContext {
|
||||||
private int lastTouchDownX = 0;
|
private int lastTouchDownX = 0;
|
||||||
private int lastTouchDownY = 0;
|
private int lastTouchDownY = 0;
|
||||||
@@ -22,13 +19,33 @@ public class AbsoluteTouchContext implements TouchContext {
|
|||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private boolean confirmedLongPress;
|
private boolean confirmedLongPress;
|
||||||
private boolean confirmedTap;
|
private boolean confirmedTap;
|
||||||
private TimerTask longPressTimerTask;
|
|
||||||
private TimerTask tapDownTimerTask;
|
private final Runnable longPressRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// This timer should have already expired, but cancel it just in case
|
||||||
|
cancelTapDownTimer();
|
||||||
|
|
||||||
|
// Switch from a left click to a right click after a long press
|
||||||
|
confirmedLongPress = true;
|
||||||
|
if (confirmedTap) {
|
||||||
|
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT);
|
||||||
|
}
|
||||||
|
conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_RIGHT);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Runnable tapDownRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Start our tap
|
||||||
|
tapConfirmed();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final NvConnection conn;
|
private final NvConnection conn;
|
||||||
private final int actionIndex;
|
private final int actionIndex;
|
||||||
private final View targetView;
|
private final View targetView;
|
||||||
private final Timer timer;
|
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
|
|
||||||
private final Runnable leftButtonUpRunnable = new Runnable() {
|
private final Runnable leftButtonUpRunnable = new Runnable() {
|
||||||
@@ -49,12 +66,11 @@ public class AbsoluteTouchContext implements TouchContext {
|
|||||||
private static final int TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD = 100;
|
private static final int TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD = 100;
|
||||||
private static final int TOUCH_DOWN_DEAD_ZONE_DISTANCE_THRESHOLD = 20;
|
private static final int TOUCH_DOWN_DEAD_ZONE_DISTANCE_THRESHOLD = 20;
|
||||||
|
|
||||||
public AbsoluteTouchContext(NvConnection conn, int actionIndex, View view, Timer timer)
|
public AbsoluteTouchContext(NvConnection conn, int actionIndex, View view)
|
||||||
{
|
{
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.actionIndex = actionIndex;
|
this.actionIndex = actionIndex;
|
||||||
this.targetView = view;
|
this.targetView = view;
|
||||||
this.timer = timer;
|
|
||||||
this.handler = new Handler(Looper.getMainLooper());
|
this.handler = new Handler(Looper.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,69 +154,22 @@ public class AbsoluteTouchContext implements TouchContext {
|
|||||||
lastTouchUpTime = eventTime;
|
lastTouchUpTime = eventTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startLongPressTimer() {
|
private void startLongPressTimer() {
|
||||||
cancelLongPressTimer();
|
cancelLongPressTimer();
|
||||||
longPressTimerTask = new TimerTask() {
|
handler.postDelayed(longPressRunnable, LONG_PRESS_TIME_THRESHOLD);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
synchronized (AbsoluteTouchContext.this) {
|
|
||||||
// Check if someone cancelled us
|
|
||||||
if (longPressTimerTask == null) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncancellable now
|
private void cancelLongPressTimer() {
|
||||||
longPressTimerTask = null;
|
handler.removeCallbacks(longPressRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
// This timer should have already expired, but cancel it just in case
|
private void startTapDownTimer() {
|
||||||
cancelTapDownTimer();
|
cancelTapDownTimer();
|
||||||
|
handler.postDelayed(tapDownRunnable, TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD);
|
||||||
// Switch from a left click to a right click after a long press
|
|
||||||
confirmedLongPress = true;
|
|
||||||
if (confirmedTap) {
|
|
||||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT);
|
|
||||||
}
|
|
||||||
conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_RIGHT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
timer.schedule(longPressTimerTask, LONG_PRESS_TIME_THRESHOLD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void cancelLongPressTimer() {
|
private void cancelTapDownTimer() {
|
||||||
if (longPressTimerTask != null) {
|
handler.removeCallbacks(tapDownRunnable);
|
||||||
longPressTimerTask.cancel();
|
|
||||||
longPressTimerTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void startTapDownTimer() {
|
|
||||||
cancelTapDownTimer();
|
|
||||||
tapDownTimerTask = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
synchronized (AbsoluteTouchContext.this) {
|
|
||||||
// Check if someone cancelled us
|
|
||||||
if (tapDownTimerTask == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncancellable now
|
|
||||||
tapDownTimerTask = null;
|
|
||||||
|
|
||||||
// Start our tap
|
|
||||||
tapConfirmed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
timer.schedule(tapDownTimerTask, TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void cancelTapDownTimer() {
|
|
||||||
if (tapDownTimerTask != null) {
|
|
||||||
tapDownTimerTask.cancel();
|
|
||||||
tapDownTimerTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tapConfirmed() {
|
private void tapConfirmed() {
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ import com.limelight.nvstream.NvConnection;
|
|||||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||||
import com.limelight.preferences.PreferenceConfiguration;
|
import com.limelight.preferences.PreferenceConfiguration;
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class RelativeTouchContext implements TouchContext {
|
public class RelativeTouchContext implements TouchContext {
|
||||||
private int lastTouchX = 0;
|
private int lastTouchX = 0;
|
||||||
private int lastTouchY = 0;
|
private int lastTouchY = 0;
|
||||||
@@ -21,7 +18,6 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
private boolean confirmedMove;
|
private boolean confirmedMove;
|
||||||
private boolean confirmedDrag;
|
private boolean confirmedDrag;
|
||||||
private boolean confirmedScroll;
|
private boolean confirmedScroll;
|
||||||
private TimerTask dragTimerTask;
|
|
||||||
private double distanceMoved;
|
private double distanceMoved;
|
||||||
private double xFactor, yFactor;
|
private double xFactor, yFactor;
|
||||||
private int pointerCount;
|
private int pointerCount;
|
||||||
@@ -33,9 +29,27 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
private final int referenceHeight;
|
private final int referenceHeight;
|
||||||
private final View targetView;
|
private final View targetView;
|
||||||
private final PreferenceConfiguration prefConfig;
|
private final PreferenceConfiguration prefConfig;
|
||||||
private final Timer timer;
|
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
|
|
||||||
|
private final Runnable dragTimerRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Check if someone already set move
|
||||||
|
if (confirmedMove) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The drag should only be processed for the primary finger
|
||||||
|
if (actionIndex != maxPointerCountInGesture - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We haven't been cancelled before the timer expired so begin dragging
|
||||||
|
confirmedDrag = true;
|
||||||
|
conn.sendMouseButtonDown(getMouseButtonIndex());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Indexed by MouseButtonPacket.BUTTON_XXX - 1
|
// Indexed by MouseButtonPacket.BUTTON_XXX - 1
|
||||||
private final Runnable[] buttonUpRunnables = new Runnable[] {
|
private final Runnable[] buttonUpRunnables = new Runnable[] {
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@@ -79,8 +93,7 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
|
|
||||||
public RelativeTouchContext(NvConnection conn, int actionIndex,
|
public RelativeTouchContext(NvConnection conn, int actionIndex,
|
||||||
int referenceWidth, int referenceHeight,
|
int referenceWidth, int referenceHeight,
|
||||||
View view, PreferenceConfiguration prefConfig,
|
View view, PreferenceConfiguration prefConfig)
|
||||||
Timer timer)
|
|
||||||
{
|
{
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.actionIndex = actionIndex;
|
this.actionIndex = actionIndex;
|
||||||
@@ -88,7 +101,6 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
this.referenceHeight = referenceHeight;
|
this.referenceHeight = referenceHeight;
|
||||||
this.targetView = view;
|
this.targetView = view;
|
||||||
this.prefConfig = prefConfig;
|
this.prefConfig = prefConfig;
|
||||||
this.timer = timer;
|
|
||||||
this.handler = new Handler(Looper.getMainLooper());
|
this.handler = new Handler(Looper.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,47 +199,16 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startDragTimer() {
|
private void startDragTimer() {
|
||||||
cancelDragTimer();
|
cancelDragTimer();
|
||||||
dragTimerTask = new TimerTask() {
|
handler.postDelayed(dragTimerRunnable, DRAG_TIME_THRESHOLD);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
synchronized (RelativeTouchContext.this) {
|
|
||||||
// Check if someone already set move
|
|
||||||
if (confirmedMove) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The drag should only be processed for the primary finger
|
private void cancelDragTimer() {
|
||||||
if (actionIndex != maxPointerCountInGesture - 1) {
|
handler.removeCallbacks(dragTimerRunnable);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if someone cancelled us
|
private void checkForConfirmedMove(int eventX, int eventY) {
|
||||||
if (dragTimerTask == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncancellable now
|
|
||||||
dragTimerTask = null;
|
|
||||||
|
|
||||||
// We haven't been cancelled before the timer expired so begin dragging
|
|
||||||
confirmedDrag = true;
|
|
||||||
conn.sendMouseButtonDown(getMouseButtonIndex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
timer.schedule(dragTimerTask, DRAG_TIME_THRESHOLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void cancelDragTimer() {
|
|
||||||
if (dragTimerTask != null) {
|
|
||||||
dragTimerTask.cancel();
|
|
||||||
dragTimerTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void checkForConfirmedMove(int eventX, int eventY) {
|
|
||||||
// If we've already confirmed something, get out now
|
// If we've already confirmed something, get out now
|
||||||
if (confirmedMove || confirmedDrag) {
|
if (confirmedMove || confirmedDrag) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+9
-23
@@ -14,7 +14,6 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a digital button on screen element. It is used to get click and double click user input.
|
* This is a digital button on screen element. It is used to get click and double click user input.
|
||||||
@@ -42,21 +41,16 @@ public class DigitalButton extends VirtualControllerElement {
|
|||||||
void onRelease();
|
void onRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private class TimerLongClickTimerTask extends TimerTask {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
onLongClickCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<DigitalButtonListener> listeners = new ArrayList<>();
|
private List<DigitalButtonListener> listeners = new ArrayList<>();
|
||||||
private String text = "";
|
private String text = "";
|
||||||
private int icon = -1;
|
private int icon = -1;
|
||||||
private long timerLongClickTimeout = 3000;
|
private long timerLongClickTimeout = 3000;
|
||||||
private TimerLongClickTimerTask longClickTimerTask = null;
|
private final Runnable longClickRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
onLongClickCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final Paint paint = new Paint();
|
private final Paint paint = new Paint();
|
||||||
private final RectF rect = new RectF();
|
private final RectF rect = new RectF();
|
||||||
@@ -175,13 +169,8 @@ public class DigitalButton extends VirtualControllerElement {
|
|||||||
listener.onClick();
|
listener.onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longClickTimerTask != null) {
|
virtualController.getHandler().removeCallbacks(longClickRunnable);
|
||||||
longClickTimerTask.cancel();
|
virtualController.getHandler().postDelayed(longClickRunnable, timerLongClickTimeout);
|
||||||
longClickTimerTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
longClickTimerTask = new TimerLongClickTimerTask();
|
|
||||||
virtualController.getTimer().schedule(longClickTimerTask, timerLongClickTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onLongClickCallback() {
|
private void onLongClickCallback() {
|
||||||
@@ -200,10 +189,7 @@ public class DigitalButton extends VirtualControllerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We may be called for a release without a prior click
|
// We may be called for a release without a prior click
|
||||||
if (longClickTimerTask != null) {
|
virtualController.getHandler().removeCallbacks(longClickRunnable);
|
||||||
longClickTimerTask.cancel();
|
|
||||||
longClickTimerTask = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+6
-2
@@ -5,6 +5,8 @@
|
|||||||
package com.limelight.binding.input.virtual_controller;
|
package com.limelight.binding.input.virtual_controller;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -42,6 +44,7 @@ public class VirtualController {
|
|||||||
private final ControllerHandler controllerHandler;
|
private final ControllerHandler controllerHandler;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Timer timer;
|
private final Timer timer;
|
||||||
|
private final Handler handler;
|
||||||
|
|
||||||
private TimerTask retransmitTimerTask;
|
private TimerTask retransmitTimerTask;
|
||||||
private FrameLayout frame_layout = null;
|
private FrameLayout frame_layout = null;
|
||||||
@@ -58,6 +61,7 @@ public class VirtualController {
|
|||||||
this.frame_layout = layout;
|
this.frame_layout = layout;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.timer = new Timer("OSC timer", true);
|
this.timer = new Timer("OSC timer", true);
|
||||||
|
this.handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
buttonConfigure = new Button(context);
|
buttonConfigure = new Button(context);
|
||||||
buttonConfigure.setAlpha(0.25f);
|
buttonConfigure.setAlpha(0.25f);
|
||||||
@@ -92,8 +96,8 @@ public class VirtualController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer getTimer() {
|
Handler getHandler() {
|
||||||
return timer;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
|||||||
Reference in New Issue
Block a user