diff --git a/src/main/java/cz/jzitnik/Cli.java b/src/main/java/cz/jzitnik/Cli.java index 02398e8..8b4aa52 100644 --- a/src/main/java/cz/jzitnik/Cli.java +++ b/src/main/java/cz/jzitnik/Cli.java @@ -42,7 +42,7 @@ public class Cli implements Runnable { terminal.setCursorPosition(null); terminal.doResizeIfNecessary(); - terminal.getTerminal().addResizeListener((_, terminalSize) -> { + terminal.getTerminal().addResizeListener((ignored, terminalSize) -> { terminal.doResizeIfNecessary(); eventManager.emitEvent(new TerminalResizeEvent(terminalSize)); }); diff --git a/src/main/java/cz/jzitnik/events/handlers/CliHandler.java b/src/main/java/cz/jzitnik/events/handlers/CliHandler.java index 49c8d83..6af2415 100644 --- a/src/main/java/cz/jzitnik/events/handlers/CliHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/CliHandler.java @@ -6,6 +6,7 @@ import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.game.Constants; +import cz.jzitnik.states.RenderState; import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.states.TerminalState; import cz.jzitnik.ui.pixels.Empty; @@ -25,12 +26,19 @@ public class CliHandler extends AbstractEventHandler { @InjectState private ScreenBuffer screenBuffer; + @InjectState + private RenderState renderState; + public CliHandler(DependencyManager dm) { super(dm); } @Override public void handle(RerenderScreen event) { + if (renderState.isTerminalTooSmall()) { + return; + } + var parts = event.parts(); var buffer = screenBuffer.getRenderedBuffer(); var terminalScreen = terminalState.getTerminalScreen(); diff --git a/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java index 16b1e93..7ed6482 100644 --- a/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java @@ -1,6 +1,7 @@ package cz.jzitnik.events.handlers; import com.googlecode.lanterna.TerminalPosition; +import com.googlecode.lanterna.input.MouseActionType; import cz.jzitnik.annotations.EventHandler; import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.annotations.injectors.InjectDependency; @@ -29,7 +30,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -40,6 +40,8 @@ public class MouseMoveEventHandler extends AbstractEventHandler super(dm); } + private MouseMoveEvent lastEvent = new MouseMoveEvent(new MouseAction(MouseActionType.MOVE, 1, new TerminalPosition(0, 0))); + @InjectState private GameState gameState; @@ -63,22 +65,34 @@ public class MouseMoveEventHandler extends AbstractEventHandler private double distancePointToRect( double px, double py, - double left, double top, - double right, double bottom) { + double rectTopLeftX, double rectTopLeftY, + double rectBottomRightX, double rectBottomRightY) { + double minX = Math.min(rectTopLeftX, rectBottomRightX); + double maxX = Math.max(rectTopLeftX, rectBottomRightX); + double minY = Math.min(rectTopLeftY, rectBottomRightY); + double maxY = Math.max(rectTopLeftY, rectBottomRightY); - // Clamp point to rectangle - double closestX = Math.max(left, Math.min(px, right)); - double closestY = Math.max(top, Math.min(py, bottom)); + boolean isInside = (px > minX && px < maxX && py > minY && py < maxY); - double dx = px - closestX; - double dy = py - closestY; + if (isInside) { + return 0; + } else { + double closestX = Math.max(minX, Math.min(px, maxX)); + double closestY = Math.max(minY, Math.min(py, maxY)); + double dx = px - closestX; + double dy = py - closestY; - return Math.sqrt(dx * dx + dy * dy); + return Math.sqrt(dx * dx + dy * dy); + } } @Override public void handle(MouseMoveEvent event) { - MouseAction mouseAction = event.getMouseAction(); + if (event.getMouseAction() != null) { + this.lastEvent = event; + } + + MouseAction mouseAction = lastEvent.getMouseAction(); int mouseX = mouseAction.getPosition().getColumn(); int mouseY = mouseAction.getPosition().getRow(); diff --git a/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java index 5a49ea6..c7e24c4 100644 --- a/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java @@ -9,6 +9,7 @@ import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.config.Debugging; import cz.jzitnik.config.Logging; import cz.jzitnik.config.PlayerConfig; +import cz.jzitnik.events.MouseMoveEvent; import cz.jzitnik.events.PlayerMoveEvent; import cz.jzitnik.events.RerenderScreen; import cz.jzitnik.events.RoomChangeEvent; @@ -25,6 +26,7 @@ import cz.jzitnik.ui.Stats; import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.utils.events.AbstractEventHandler; +import cz.jzitnik.utils.events.Event; import cz.jzitnik.utils.events.EventManager; import lombok.extern.slf4j.Slf4j; @@ -151,18 +153,21 @@ public class PlayerMoveEventHandler extends AbstractEventHandler, AbstractEventHandler> handlers = new HashMap<>(); - private final BlockingQueue eventQueue = new LinkedBlockingQueue<>(); + private final BlockingQueue eventQueue = new LinkedBlockingQueue<>(); private final DependencyManager dependencyManager; @SuppressWarnings("unchecked") @@ -33,7 +33,26 @@ public class EventManager extends Thread { } public void emitEvent(Event event) { - eventQueue.add(event); + eventQueue.add(new EventRecord(new Event[]{event})); + } + + public void emitEvent(Event event, Runnable callback) { + eventQueue.add(new EventRecord(new Event[]{event}, callback)); + } + + public void emitEvent(Event[] events) { + eventQueue.add(new EventRecord(events)); + } + + public void emitEvent(Event[] events, Runnable callback) { + eventQueue.add(new EventRecord(events, callback)); + } + + private record EventRecord(Event[] events, Runnable callback) { + public EventRecord(Event[] events) { + this(events, () -> { + }); + } } @SuppressWarnings("unchecked") @@ -64,7 +83,7 @@ public class EventManager extends Thread { eventExecutor = Executors.newFixedThreadPool(threadPoolConfig.getEventThreadCount()); while (runningState.isRunning()) { try { - Event event = eventQueue.take(); + EventRecord event = eventQueue.take(); handleEvent(event); } catch (InterruptedException e) { // The game is shutting down. @@ -76,18 +95,17 @@ public class EventManager extends Thread { } @SuppressWarnings("unchecked") - private void handleEvent(Event event) { - T typedEvent = (T) event; - AbstractEventHandler handler = getHandler((Class) event.getClass()); - - if (handler != null) { - eventExecutor.submit(() -> { - try { - handler.handle(typedEvent); - } catch (Exception e) { - log.error("Error", e); + private void handleEvent(EventRecord eventRecord) { + eventExecutor.submit(() -> { + try { + for (Event event : eventRecord.events) { + AbstractEventHandler handler = getHandler((Class) event.getClass()); + handler.handle(event); } - }); - } + eventRecord.callback.run(); + } catch (Exception e) { + log.error("Error", e); + } + }); } }