From afdebf8f4f532ed5b456040c6c481f3cfbf8d236 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Tue, 17 Jul 2018 20:24:54 +0300 Subject: [PATCH] Refactoring. --- .../sixth/e3d/gui/GuiComponent.java | 14 +- .../svjatoslav/sixth/e3d/gui/ViewPanel.java | 3 + .../e3d/gui/humaninput/UserInputHandler.java | 26 +++- .../e3d/gui/humaninput/UserInputTracker.java | 143 ++++++++++-------- .../humaninput/WorldNavigationTracker.java | 12 +- .../TextEditComponent.java | 3 +- 6 files changed, 121 insertions(+), 80 deletions(-) diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java index 64dc879..75dbbf4 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/GuiComponent.java @@ -56,13 +56,15 @@ public class GuiComponent extends AbstractCompositeShape implements } @Override - public void focusLost(final ViewPanel viewPanel) { + public boolean focusLost(final ViewPanel viewPanel) { hideBorder(); + return true; } @Override - public void focusReceived(final ViewPanel viewPanel) { + public boolean focusReceived(final ViewPanel viewPanel) { showBorder(); + return true; } public WireframeBox getBorders() { @@ -91,13 +93,15 @@ public class GuiComponent extends AbstractCompositeShape implements } @Override - public void keyPressed(final KeyEvent event, final ViewPanel viewPanel) { + public boolean keyPressed(final KeyEvent event, final ViewPanel viewPanel) { if (event.getKeyChar() == KeyboardHelper.ESC) viewPanel.getKeyboardFocusTracker().popFocusOwner(); + return true; } @Override - public void keyReleased(final KeyEvent event, final ViewPanel viewPanel) { + public boolean keyReleased(final KeyEvent event, final ViewPanel viewPanel) { + return false; } @Override @@ -117,7 +121,7 @@ public class GuiComponent extends AbstractCompositeShape implements containingBox.setSizeCentered(size); } - public void showBorder() { + private void showBorder() { if (borderShown) return; borderShown = true; diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java index 2c6afe2..6fda153 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/ViewPanel.java @@ -22,6 +22,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Timer; +/** + * Java Swing GUI panel that contains canvas for 3D rendering. + */ public class ViewPanel extends JPanel implements ComponentListener { private static final long serialVersionUID = 1683277888885045387L; private final UserInputTracker userInputTracker = new UserInputTracker(this); diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java index 21fd667..dcfef5e 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputHandler.java @@ -16,12 +16,24 @@ import java.awt.event.KeyEvent; public interface UserInputHandler extends ViewRenderListener { - void focusLost(ViewPanel viewPanel); - - void focusReceived(ViewPanel viewPanel); - - void keyPressed(KeyEvent event, ViewPanel viewPanel); - - void keyReleased(KeyEvent event, ViewPanel viewPanel); + /** + * @return true if view update is needed. + */ + boolean focusLost(ViewPanel viewPanel); + + /** + * @return true if view update is needed. + */ + boolean focusReceived(ViewPanel viewPanel); + + /** + * @return true if view update is needed. + */ + boolean keyPressed(KeyEvent event, ViewPanel viewPanel); + + /** + * @return true if view update is needed. + */ + boolean keyReleased(KeyEvent event, ViewPanel viewPanel); } diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputTracker.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputTracker.java index 63bfd19..3060691 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputTracker.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/UserInputTracker.java @@ -21,8 +21,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class UserInputTracker - implements MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener { +public class UserInputTracker implements + MouseMotionListener, KeyListener, MouseListener, MouseWheelListener, ViewRenderListener { /** *
@@ -54,14 +54,10 @@ public class UserInputTracker
     @Override
     public boolean beforeRender(final ViewPanel viewPanel, final int millisecondsSinceLastFrame) {
 
-        boolean viewUpdateNeeded = handleDetectedMouseClicks(viewPanel);
-
-        viewUpdateNeeded |= handleDetectedKeyEvents();
-
-        viewPanel.getKeyboardFocusTracker().getCurrentFocusOwner().beforeRender(viewPanel,
-                millisecondsSinceLastFrame);
-
-        viewUpdateNeeded |= trackMouse();
+        boolean viewUpdateNeeded = handleKeyboardEvents();
+        viewUpdateNeeded |= handleMouseClicksAndHover(viewPanel);
+        viewUpdateNeeded |= handleMouseDragging();
+        viewUpdateNeeded |= handleMouseVerticalScrolling();
 
         return viewUpdateNeeded;
     }
@@ -76,56 +72,81 @@ public class UserInputTracker
         panel.addMouseWheelListener(this);
     }
 
-    private boolean handleDetectedKeyEvents() {
-        boolean keyEventsHandled = false;
-
+    /**
+     * @return true if view needs to be repainted.
+     */
+    private boolean handleKeyboardEvents() {
         final UserInputHandler currentFocusOwner = viewPanel.getKeyboardFocusTracker().getCurrentFocusOwner();
+        ArrayList unprocessedKeyboardEvents = getUnprocessedKeyboardEvents();
 
+        return currentFocusOwner == null ? false :
+                forwardKeyboardEventsToFocusOwner(currentFocusOwner, unprocessedKeyboardEvents);
+    }
+
+    private ArrayList getUnprocessedKeyboardEvents() {
         synchronized (detectedKeyEvents) {
-            if (currentFocusOwner == null) {
-                detectedKeyEvents.clear();
-                return false;
-            }
-
-            while (!detectedKeyEvents.isEmpty()) {
-                final KeyEvent keyEvent = detectedKeyEvents.remove(0);
-
-                switch (keyEvent.getID()) {
-                    case KeyEvent.KEY_PRESSED:
-                        currentFocusOwner.keyPressed(keyEvent, viewPanel);
-                        keyEventsHandled = true;
-                        break;
-
-                    case KeyEvent.KEY_RELEASED:
-                        currentFocusOwner.keyReleased(keyEvent, viewPanel);
-                        keyEventsHandled = true;
-                        break;
-                }
-            }
+            ArrayList result = new ArrayList<>(detectedKeyEvents);
+            detectedKeyEvents.clear();
+            return result;
         }
+    }
 
-        return keyEventsHandled;
+    /**
+     * @return true if view update is needed.
+     */
+    private boolean forwardKeyboardEventsToFocusOwner(
+            UserInputHandler currentFocusOwner, ArrayList keyEvents) {
+        boolean viewUpdateNeeded = false;
+
+        for (KeyEvent keyEvent : keyEvents)
+            viewUpdateNeeded |= processKeyEvent(currentFocusOwner, keyEvent);
+
+        return viewUpdateNeeded;
+    }
+
+    private boolean processKeyEvent(UserInputHandler currentFocusOwner, KeyEvent keyEvent) {
+        switch (keyEvent.getID()) {
+            case KeyEvent.KEY_PRESSED:
+                return currentFocusOwner.keyPressed(keyEvent, viewPanel);
+
+            case KeyEvent.KEY_RELEASED:
+                return currentFocusOwner.keyReleased(keyEvent, viewPanel);
+        }
+        return false;
     }
 
     /**
      * @return true if view needs to be repainted.
      */
-    private synchronized boolean handleDetectedMouseClicks(final ViewPanel viewPanel) {
-        if (detectedMouseClicks.isEmpty()) {
+    private synchronized boolean handleMouseClicksAndHover(final ViewPanel viewPanel) {
+        MouseClick unprocessedMouseClick = findUnprocessedMouseClick();
+
+        if (unprocessedMouseClick != null) {
+            viewPanel.getRenderingContext().mouseClick = unprocessedMouseClick;
+            return false;
+        } else
+            return handleMouseHovering(viewPanel);
+    }
 
-            if (currentMouseLocation != null)
-                viewPanel.getRenderingContext().mouseClick = new MouseClick(currentMouseLocation, 0);
+    private MouseClick findUnprocessedMouseClick() {
+        synchronized (detectedMouseClicks) {
+            if (detectedMouseClicks.isEmpty())
+                return null;
 
-            if (mouseMoved) {
-                mouseMoved = false;
-                return true;
-            } else
-                return false;
+            return detectedMouseClicks.remove(0);
         }
+    }
 
-        viewPanel.getRenderingContext().mouseClick = detectedMouseClicks.remove(0);
+    private boolean handleMouseHovering(ViewPanel viewPanel) {
+        if (currentMouseLocation != null)
+            // mouse click with button 0 amounts to mouse hovering event
+            viewPanel.getRenderingContext().mouseClick = new MouseClick(currentMouseLocation, 0);
 
-        return true;
+        if (mouseMoved) {
+            mouseMoved = false;
+            return true;
+        } else
+            return false;
     }
 
     boolean isKeyPressed(final int keyCode) {
@@ -137,7 +158,6 @@ public class UserInputTracker
         synchronized (detectedKeyEvents) {
             pressedKeysToPressedTimeMap.put(evt.getKeyCode(), System.currentTimeMillis());
             detectedKeyEvents.add(evt);
-            viewPanel.repaintDuringNextViewUpdate();
         }
     }
 
@@ -146,7 +166,6 @@ public class UserInputTracker
         synchronized (detectedKeyEvents) {
             pressedKeysToPressedTimeMap.remove(evt.getKeyCode());
             detectedKeyEvents.add(evt);
-            viewPanel.repaintDuringNextViewUpdate();
         }
     }
 
@@ -207,31 +226,25 @@ public class UserInputTracker
     }
 
     /**
-     * Interpret mouse movement
+     * @return true if view needs to be repainted.
      */
-    private boolean trackMouse() {
+    private boolean handleMouseVerticalScrolling() {
         final Avatar avatar = viewPanel.getAvatar();
-        trackDragging(avatar);
-        trackVerticalScrolling(avatar);
-
-        boolean repaintNeeded = !mouseDraggedDirection.isZero() || (wheelMovedDirection != 0);
-
-        // reset movement counters
-        wheelMovedDirection = 0;
-        mouseDraggedDirection.zero();
-
-        return repaintNeeded;
-    }
-
-    private void trackVerticalScrolling(Avatar avatar) {
         final double actualAcceleration = 50 * avatar.avatarAcceleration * (1 + (avatar.getMovementSpeed() / 10));
         avatar.getMovementVector().y += (wheelMovedDirection * actualAcceleration);
         avatar.enforceSpeedLimit();
+        boolean repaintNeeded = wheelMovedDirection != 0;
+        wheelMovedDirection = 0;
+        return repaintNeeded;
     }
 
-    private void trackDragging(Avatar avatar) {
+    /**
+     * @return true if view needs to be repainted.
+     */
+    private boolean handleMouseDragging() {
         // TODO: need to detect whether user moved mouse or touch screen
 
+        final Avatar avatar = viewPanel.getAvatar();
         // for mouse
         avatar.setAngleXZ(avatar.getAngleXZ() - ((float) mouseDraggedDirection.x / 50));
         avatar.setAngleYZ(avatar.getAngleYZ() - ((float) mouseDraggedDirection.y / 50));
@@ -241,6 +254,10 @@ public class UserInputTracker
         // mouseDraggedDirection.x / 50));
         // avatar.setAngleYZ(avatar.getAngleYZ() + ((float)
         // mouseDraggedDirection.y / 50));
+
+        boolean viewUpdateNeeded = !mouseDraggedDirection.isZero();
+        mouseDraggedDirection.zero();
+        return viewUpdateNeeded;
     }
 
 }
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/WorldNavigationTracker.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/WorldNavigationTracker.java
index 44e09d2..28d485c 100644
--- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/WorldNavigationTracker.java
+++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/humaninput/WorldNavigationTracker.java
@@ -26,19 +26,23 @@ public class WorldNavigationTracker implements UserInputHandler {
     }
 
     @Override
-    public void focusLost(final ViewPanel viewPanel) {
+    public boolean focusLost(final ViewPanel viewPanel) {
+        return false;
     }
 
     @Override
-    public void focusReceived(final ViewPanel viewContext) {
+    public boolean focusReceived(final ViewPanel viewContext) {
+        return false;
     }
 
     @Override
-    public void keyPressed(final KeyEvent event, final ViewPanel viewContext) {
+    public boolean keyPressed(final KeyEvent event, final ViewPanel viewContext) {
+        return true;
     }
 
     @Override
-    public void keyReleased(final KeyEvent event, final ViewPanel viewContext) {
+    public boolean keyReleased(final KeyEvent event, final ViewPanel viewContext) {
+        return true;
     }
 
     /**
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/TextEditComponent.java b/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/TextEditComponent.java
index ee4def7..7262d21 100755
--- a/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/TextEditComponent.java
+++ b/src/main/java/eu/svjatoslav/sixth/e3d/gui/textEditorComponent/TextEditComponent.java
@@ -249,7 +249,7 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
      * Parse key presses.
      */
     @Override
-    public void keyPressed(final KeyEvent event, final ViewPanel viewPanel) {
+    public boolean keyPressed(final KeyEvent event, final ViewPanel viewPanel) {
         super.keyPressed(event, viewPanel);
 
         processKeyEvent(event);
@@ -259,6 +259,7 @@ public class TextEditComponent extends GuiComponent implements ClipboardOwner {
         checkCursorBoundaries();
 
         repaintWhatNeeded();
+        return true;
     }
 
     /**
-- 
2.20.1