From 344839976339937ad18722c5f5daaaa4af0d7c2e Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sat, 20 Jan 2024 21:47:06 +0100 Subject: [PATCH 01/23] adjust todos --- TODO.md | 55 +++++-------------------------------------------------- 1 file changed, 5 insertions(+), 50 deletions(-) diff --git a/TODO.md b/TODO.md index bd93217f..cb9e1b82 100644 --- a/TODO.md +++ b/TODO.md @@ -5,59 +5,14 @@ * panning * zooming * - * Command-Queue (->) - * add commands to queue (/) - * A Command is a class with a type and can check by itself if its condition is met or not. (/) - * Commands are Singletons or at least reusable (/) - * Commands have to be registered/activated in the central InputManager (/) - * execute commands in update by InputComponents (/) - * after execution, remove command from queue (after Input has been processed; clear queue) (/) - * Commands: (<-) - * - * - * There are two types of commands: Instant and Continuous - * Instant/Sequential Commands (e.g. MouseClick) - * Sequence (amount of repetitions, delay between repetitions is counted by the command ITSELF -> stored in central event-queue and popped by the command itself after update delta time) - * Instant Commands are executed immediately after they are added to the queue - * Instant Commands are removed from the queue after they are executed - * Mouse Commands: - * Left ( Pixel position ) - * Right ( Pixel position ) - * Center ( Pixel position ) - * Double Click ( Pixel position ) - * Mouse Wheel ( Pixel position, Wheel delta ) - * Keyboard Commands: - * Key Press ( Key ) - * Keys can be pressed multiple times - * Key is pressed after key-release - * Continuous Commands (e.g. MouseDrag) - * Continuous Commands are executed every update cycle as long as they are in the queue - * Continuous Commands are removed from the queue after they are released - * Mouse Commands: - * Drag Left ( Pixel position, Drag vector ) - * Drag Right ( Pixel position, Drag vector ) - * Drag Center ( Pixel position, Drag vector ) - * Hold Left ( Pixel position, Drag vector ) - * Hold Right ( Pixel position, Drag vector ) - * Hold Center ( Pixel position, Drag vector ) - * Mouse Click - * Left ( Pixel position ) - * Right ( Pixel position ) - * Drag Left ( Pixel position, Drag vector ) - * Drag Right ( Pixel position, Drag vector ) - * Mouse Wheel ( Pixel position, Wheel delta ) - * - * - * + * InputCommands (<-) + * MouseClick (/) + * MouseDrag (<-) + * MouseWheel + * Keyboard * PhysicsCore holds position in TransformComponent or Object * Transform is modified when moved! - * RenderPipeline Renders a SceneGraph ... our MergeableLayer is kind of a SceneGraph - * a RenderableComponent could be a node in the SceneGraph - * so other RenderableComponents could be added to the RenderableComponent Node - * this way we could implement a "graphical" scene graph - * the both interfaces: ParentPropagatableDirtyState + ChildPropagatableDirtyState will be put into the graph-node concept! -* * * NULLImplementations -> Optionals ... * dynamic changeable render properties! From ed26ca09aae70ce5819c8f14d46f591039667fae Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sun, 21 Jan 2024 14:01:20 +0100 Subject: [PATCH 02/23] some reanimgs; tidy up --- .../{Updatable.java => IsUpdatable.java} | 2 +- .../engine/commands/CommandTemplate.java | 8 ------- .../tacview/engine/commands/Commandable.java | 7 ------ .../component/IsComponent.java | 4 ++-- .../entitycomponentsystem/entity/Entity.java | 4 ++-- .../entity/IsEntity.java | 4 ++-- .../environment/IsEnvironment.java | 4 ++-- .../{Bufferable.java => IsBufferable.java} | 4 ++-- .../{Composable.java => IsComposable.java} | 2 +- .../{Renderable.java => IsRenderable.java} | 16 +++++++------- .../{Scanable.java => IsScanable.java} | 2 +- .../engine/graphics/ScreenComposer.java | 2 +- .../engine/graphics/buffer/PixelBuffer.java | 4 ++-- .../graphics/scanable/ScanableNoise.java | 4 ++-- .../tacview/engine/module/EngineModule.java | 5 ++--- .../engine/renderables/HasMergeable.java | 2 +- .../{Mergeable.java => IsMergeable.java} | 6 ++--- ...{Positionable.java => IsPositionable.java} | 2 +- .../{Soilable.java => IsSoilable.java} | 2 +- .../mergeable/BufferedMergeableTemplate.java | 8 +++---- .../mergeable/IsMergeableComponentLayer.java | 4 ++-- .../NullMergeableComponentLayer.java | 4 ++-- .../mergeable/ScanableMergeableTemplate.java | 6 ++--- .../mergeable/ScanableNoiseMergeable.java | 4 ++-- .../tile/{Tile.java => IsTile.java} | 4 ++-- .../MultithreadedSoftwareRenderer.java | 8 +++---- .../engine/renderer/RenderProvider.java | 6 ++--- .../engine/renderer/RendererTemplate.java | 22 +++++++++---------- ...PSProfilable.java => IsFPSProfilable.java} | 2 +- .../tacview/strategy/ProfileFPSStrategy.java | 2 +- .../MultithreadedSoftwareRendererTest.java | 8 +++---- .../engine/renderer/SoftwareRendererTest.java | 8 +++---- 32 files changed, 77 insertions(+), 93 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/{Updatable.java => IsUpdatable.java} (73%) delete mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/CommandTemplate.java delete mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/Commandable.java rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/{Bufferable.java => IsBufferable.java} (80%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/{Composable.java => IsComposable.java} (82%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/{Renderable.java => IsRenderable.java} (59%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/{Scanable.java => IsScanable.java} (89%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/{Mergeable.java => IsMergeable.java} (75%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/{Positionable.java => IsPositionable.java} (80%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/{Soilable.java => IsSoilable.java} (79%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/{Tile.java => IsTile.java} (78%) rename libs/tacviewfx/src/main/java/com/recom/tacview/strategy/{FPSProfilable.java => IsFPSProfilable.java} (76%) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/Updatable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/IsUpdatable.java similarity index 73% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/Updatable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/IsUpdatable.java index a16d96ad..cbef3a78 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/Updatable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/IsUpdatable.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine; -public interface Updatable { +public interface IsUpdatable { void update(final long elapsedNanoTime); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/CommandTemplate.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/CommandTemplate.java deleted file mode 100644 index 5dafabca..00000000 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/CommandTemplate.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.recom.tacview.engine.commands; - -public abstract class CommandTemplate implements Commandable { - - @Override - public abstract void execute(); - -} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/Commandable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/Commandable.java deleted file mode 100644 index 5b5dc256..00000000 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/commands/Commandable.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.recom.tacview.engine.commands; - -public interface Commandable { - - void execute(); - -} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/IsComponent.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/IsComponent.java index 90afac35..e57711bc 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/IsComponent.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/IsComponent.java @@ -1,9 +1,9 @@ package com.recom.tacview.engine.entitycomponentsystem.component; -import com.recom.tacview.engine.Updatable; +import com.recom.tacview.engine.IsUpdatable; import lombok.NonNull; -public interface IsComponent extends BelongsToEntity, HasComponentType, Updatable { +public interface IsComponent extends BelongsToEntity, HasComponentType, IsUpdatable { @NonNull ComponentType componentType(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java index decff3a8..dfc2b4ec 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.entitycomponentsystem.entity; -import com.recom.tacview.engine.Updatable; +import com.recom.tacview.engine.IsUpdatable; import com.recom.tacview.engine.entitycomponentsystem.component.ComponentType; import com.recom.tacview.engine.entitycomponentsystem.component.IsComponent; import com.recom.tacview.engine.entitycomponentsystem.environment.IsEnvironment; @@ -83,7 +83,7 @@ public List getComponents() { @Override public void update(final long elapsedNanoTime) { - for (@NonNull final Updatable component : components) { + for (@NonNull final IsUpdatable component : components) { component.update(elapsedNanoTime); } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/IsEntity.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/IsEntity.java index 18e421db..1082a06a 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/IsEntity.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/IsEntity.java @@ -1,7 +1,7 @@ package com.recom.tacview.engine.entitycomponentsystem.entity; -import com.recom.tacview.engine.Updatable; +import com.recom.tacview.engine.IsUpdatable; -public interface IsEntity extends BelongsToEnvironment, HasLocatableComponents, Updatable { +public interface IsEntity extends BelongsToEnvironment, HasLocatableComponents, IsUpdatable { } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/environment/IsEnvironment.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/environment/IsEnvironment.java index 621f8a3a..15d04eb5 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/environment/IsEnvironment.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/environment/IsEnvironment.java @@ -1,13 +1,13 @@ package com.recom.tacview.engine.entitycomponentsystem.environment; -import com.recom.tacview.engine.Updatable; +import com.recom.tacview.engine.IsUpdatable; import com.recom.tacview.engine.graphics.renderpipeline.IsRenderPipeline; import com.recom.tacview.engine.renderer.RenderProvider; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.service.RendererExecutorProvider; import lombok.NonNull; -public interface IsEnvironment extends Updatable, HasManagableEntities { +public interface IsEnvironment extends IsUpdatable, HasManagableEntities { void update(final long elapsedNanoTime); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Bufferable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsBufferable.java similarity index 80% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Bufferable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsBufferable.java index 4918548e..0d2554a9 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Bufferable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsBufferable.java @@ -1,9 +1,9 @@ package com.recom.tacview.engine.graphics; -import com.recom.tacview.engine.renderables.Soilable; +import com.recom.tacview.engine.renderables.IsSoilable; import com.recom.tacview.engine.units.PixelDimension; -public interface Bufferable extends Scanable, Soilable { +public interface IsBufferable extends IsScanable, IsSoilable { PixelDimension getDimension(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Composable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsComposable.java similarity index 82% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Composable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsComposable.java index 6fc616e3..7bf68745 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Composable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsComposable.java @@ -4,7 +4,7 @@ import com.recom.tacview.engine.renderables.HasPixelBuffer; import lombok.NonNull; -public interface Composable extends HasPixelBuffer { +public interface IsComposable extends HasPixelBuffer { int compose(@NonNull final Environment environment); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Renderable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsRenderable.java similarity index 59% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Renderable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsRenderable.java index f0009bb7..736699d2 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Renderable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsRenderable.java @@ -1,34 +1,34 @@ package com.recom.tacview.engine.graphics; -import com.recom.tacview.engine.renderables.Mergeable; +import com.recom.tacview.engine.renderables.IsMergeable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import lombok.NonNull; -public interface Renderable { +public interface IsRenderable { void render( - @NonNull final Scanable sourceScanable, - @NonNull final Bufferable targetBuffer, + @NonNull final IsScanable sourceScanable, + @NonNull final IsBufferable targetBuffer, final int xOffset, final int yOffset ); void renderMergeable( - @NonNull final Mergeable source, + @NonNull final IsMergeable source, @NonNull final PixelBuffer targetBuffer, final int xOffset, final int yOffset ); void renderMergeable( - @NonNull final Mergeable source, - @NonNull final Bufferable target, + @NonNull final IsMergeable source, + @NonNull final IsBufferable target, final int xOffset, final int yOffset ); void setPixelAt( - @NonNull final Bufferable target, + @NonNull final IsBufferable target, final int x, final int y, final int newPixelValue diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Scanable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsScanable.java similarity index 89% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Scanable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsScanable.java index 4861e03e..e66a1684 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/Scanable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/IsScanable.java @@ -3,7 +3,7 @@ import com.recom.tacview.engine.units.PixelDimension; -public interface Scanable { +public interface IsScanable { PixelDimension getDimension(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java index b2bc7edb..3eb6f616 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java @@ -16,7 +16,7 @@ @Slf4j @Component -public class ScreenComposer implements Composable { +public class ScreenComposer implements IsComposable { @NonNull private final ExecutorService renderExecutorService; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/buffer/PixelBuffer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/buffer/PixelBuffer.java index 44f75c96..31c7291a 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/buffer/PixelBuffer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/buffer/PixelBuffer.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.graphics.buffer; -import com.recom.tacview.engine.graphics.Bufferable; +import com.recom.tacview.engine.graphics.IsBufferable; import com.recom.tacview.engine.units.PixelDimension; import lombok.Getter; import lombok.NonNull; @@ -8,7 +8,7 @@ import java.util.Arrays; -public class PixelBuffer implements Bufferable { +public class PixelBuffer implements IsBufferable { @Getter protected PixelDimension dimension; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/scanable/ScanableNoise.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/scanable/ScanableNoise.java index 6855b6dc..96e22b23 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/scanable/ScanableNoise.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/scanable/ScanableNoise.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.graphics.scanable; -import com.recom.tacview.engine.graphics.Scanable; +import com.recom.tacview.engine.graphics.IsScanable; import com.recom.tacview.engine.units.PixelDimension; import com.recom.tacview.service.RandomProvider; import lombok.Getter; @@ -8,7 +8,7 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class ScanableNoise implements Scanable { +public class ScanableNoise implements IsScanable { @NonNull private final RandomProvider randomProvider; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java index 20ea668d..269d9bb2 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java @@ -1,11 +1,10 @@ package com.recom.tacview.engine.module; -import com.recom.tacview.engine.Updatable; +import com.recom.tacview.engine.IsUpdatable; import com.recom.tacview.engine.entitycomponentsystem.component.ComponentType; import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; import com.recom.tacview.engine.entitycomponentsystem.environment.Environment; import com.recom.tacview.engine.input.command.IsInputCommand; -import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -15,7 +14,7 @@ @Getter @RequiredArgsConstructor -public abstract class EngineModule implements Updatable { +public abstract class EngineModule implements IsUpdatable { @NonNull private final Environment environment; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/HasMergeable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/HasMergeable.java index 132c1220..18380b16 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/HasMergeable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/HasMergeable.java @@ -5,6 +5,6 @@ public interface HasMergeable { @NonNull - Mergeable getMergeable(); + IsMergeable getMergeable(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Mergeable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsMergeable.java similarity index 75% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Mergeable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsMergeable.java index 7fc42c14..2eaf493b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Mergeable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsMergeable.java @@ -1,10 +1,10 @@ package com.recom.tacview.engine.renderables; -import com.recom.tacview.engine.graphics.Bufferable; +import com.recom.tacview.engine.graphics.IsBufferable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import lombok.NonNull; -public interface Mergeable extends Soilable { +public interface IsMergeable extends IsSoilable { boolean isDirty(); @@ -18,7 +18,7 @@ void mergeBufferWith( ); void mergeBufferWith( - @NonNull final Bufferable targetBuffer, + @NonNull final IsBufferable targetBuffer, final int offsetX, final int offsetY ); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Positionable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsPositionable.java similarity index 80% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Positionable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsPositionable.java index 813a6ea9..e0d9ead9 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Positionable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsPositionable.java @@ -2,7 +2,7 @@ import com.recom.tacview.engine.units.PixelCoordinate; -public interface Positionable { +public interface IsPositionable { PixelCoordinate getPosition(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Soilable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsSoilable.java similarity index 79% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Soilable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsSoilable.java index 59c8311e..f88b9e27 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/Soilable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/IsSoilable.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderables; -public interface Soilable { +public interface IsSoilable { boolean isDirty(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java index a90ccdb6..78ff2200 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java @@ -1,16 +1,16 @@ package com.recom.tacview.engine.renderables.mergeable; -import com.recom.tacview.engine.graphics.Bufferable; +import com.recom.tacview.engine.graphics.IsBufferable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import com.recom.tacview.engine.renderables.HasPixelBuffer; -import com.recom.tacview.engine.renderables.Mergeable; +import com.recom.tacview.engine.renderables.IsMergeable; import com.recom.tacview.engine.renderer.RenderProvider; import com.recom.tacview.engine.units.PixelDimension; import lombok.Getter; import lombok.NonNull; -public abstract class BufferedMergeableTemplate implements Mergeable, HasPixelBuffer { +public abstract class BufferedMergeableTemplate implements IsMergeable, HasPixelBuffer { @Getter @NonNull @@ -59,7 +59,7 @@ public void mergeBufferWith( @Override public void mergeBufferWith( - @NonNull final Bufferable targetBuffer, + @NonNull final IsBufferable targetBuffer, final int offsetX, final int offsetY ) { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/IsMergeableComponentLayer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/IsMergeableComponentLayer.java index 0995f2c4..ab566fbc 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/IsMergeableComponentLayer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/IsMergeableComponentLayer.java @@ -3,8 +3,8 @@ import com.recom.tacview.engine.entitycomponentsystem.ChildPropagateableSoilableState; import com.recom.tacview.engine.entitycomponentsystem.ParentPropagateableSoilableState; import com.recom.tacview.engine.renderables.HasPixelBuffer; -import com.recom.tacview.engine.renderables.Mergeable; +import com.recom.tacview.engine.renderables.IsMergeable; -public interface IsMergeableComponentLayer extends Mergeable, HasPixelBuffer, ParentPropagateableSoilableState, ChildPropagateableSoilableState { +public interface IsMergeableComponentLayer extends IsMergeable, HasPixelBuffer, ParentPropagateableSoilableState, ChildPropagateableSoilableState { } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/NullMergeableComponentLayer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/NullMergeableComponentLayer.java index 294bb6f8..4f57ed71 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/NullMergeableComponentLayer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/NullMergeableComponentLayer.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderables.mergeable; -import com.recom.tacview.engine.graphics.Bufferable; +import com.recom.tacview.engine.graphics.IsBufferable; import com.recom.tacview.engine.graphics.buffer.NullPixelBuffer; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import lombok.NonNull; @@ -35,7 +35,7 @@ public void mergeBufferWith(@NonNull PixelBuffer targetBuffer, int offsetX, int } @Override - public void mergeBufferWith(@NonNull Bufferable targetBuffer, int offsetX, int offsetY) { + public void mergeBufferWith(@NonNull IsBufferable targetBuffer, int offsetX, int offsetY) { } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableMergeableTemplate.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableMergeableTemplate.java index d20b8b46..ec6a36be 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableMergeableTemplate.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableMergeableTemplate.java @@ -1,14 +1,14 @@ package com.recom.tacview.engine.renderables.mergeable; -import com.recom.tacview.engine.graphics.Scanable; -import com.recom.tacview.engine.renderables.Mergeable; +import com.recom.tacview.engine.graphics.IsScanable; +import com.recom.tacview.engine.renderables.IsMergeable; import com.recom.tacview.engine.units.PixelDimension; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public abstract class ScanableMergeableTemplate implements Scanable, Mergeable { +public abstract class ScanableMergeableTemplate implements IsScanable, IsMergeable { @Getter @NonNull diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableNoiseMergeable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableNoiseMergeable.java index 31fb21b6..9694a620 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableNoiseMergeable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/ScanableNoiseMergeable.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderables.mergeable; -import com.recom.tacview.engine.graphics.Bufferable; +import com.recom.tacview.engine.graphics.IsBufferable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import com.recom.tacview.engine.graphics.scanable.ScanableNoise; import com.recom.tacview.engine.renderer.RenderProvider; @@ -37,7 +37,7 @@ public void mergeBufferWith( @Override public void mergeBufferWith( - @NonNull final Bufferable targetBuffer, + @NonNull final IsBufferable targetBuffer, final int offsetX, final int offsetY ) { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/Tile.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/IsTile.java similarity index 78% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/Tile.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/IsTile.java index 8536094d..ecd7acaf 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/Tile.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/tile/IsTile.java @@ -2,12 +2,12 @@ import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import com.recom.tacview.engine.renderables.HasPixelBuffer; -import com.recom.tacview.engine.renderables.Positionable; +import com.recom.tacview.engine.renderables.IsPositionable; import com.recom.tacview.engine.renderables.sprite.Sprite; import com.recom.tacview.engine.units.PixelCoordinate; import lombok.NonNull; -public interface Tile extends HasPixelBuffer, Positionable { +public interface IsTile extends HasPixelBuffer, IsPositionable { @NonNull PixelCoordinate getPosition(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRenderer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRenderer.java index 3b1d322c..5a0124ba 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRenderer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRenderer.java @@ -1,7 +1,7 @@ package com.recom.tacview.engine.renderer; -import com.recom.tacview.engine.graphics.Bufferable; -import com.recom.tacview.engine.graphics.Scanable; +import com.recom.tacview.engine.graphics.IsBufferable; +import com.recom.tacview.engine.graphics.IsScanable; import com.recom.tacview.service.RendererExecutorProvider; import com.recom.tacview.service.argb.ARGBCalculatorProvider; import lombok.NonNull; @@ -29,8 +29,8 @@ class MultithreadedSoftwareRenderer extends RendererTemplate { @Override public void render( - @NonNull final Scanable source, - @NonNull final Bufferable target, + @NonNull final IsScanable source, + @NonNull final IsBufferable target, final int xOffset, final int yOffset ) { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RenderProvider.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RenderProvider.java index d67b730d..6cfe1960 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RenderProvider.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RenderProvider.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderer; -import com.recom.tacview.engine.graphics.Renderable; +import com.recom.tacview.engine.graphics.IsRenderable; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.service.RendererExecutorProvider; import com.recom.tacview.service.argb.ARGBCalculatorProvider; @@ -20,9 +20,9 @@ public final class RenderProvider { @NonNull private final ARGBCalculatorProvider argbCalculatorProvider; @Nullable - private Renderable instance; + private IsRenderable instance; - public Renderable provide() { + public IsRenderable provide() { if (instance == null) { if (rendererProperties.isParallelizedRendering()) { instance = new MultithreadedSoftwareRenderer(rendererExecutorProvider, argbCalculatorProvider); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RendererTemplate.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RendererTemplate.java index 13001d06..eaf8c4bb 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RendererTemplate.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderer/RendererTemplate.java @@ -1,16 +1,16 @@ package com.recom.tacview.engine.renderer; -import com.recom.tacview.engine.graphics.Bufferable; -import com.recom.tacview.engine.graphics.Renderable; -import com.recom.tacview.engine.graphics.Scanable; +import com.recom.tacview.engine.graphics.IsBufferable; +import com.recom.tacview.engine.graphics.IsRenderable; +import com.recom.tacview.engine.graphics.IsScanable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; -import com.recom.tacview.engine.renderables.Mergeable; +import com.recom.tacview.engine.renderables.IsMergeable; import com.recom.tacview.service.argb.ARGBCalculatorProvider; import lombok.NonNull; import org.springframework.stereotype.Component; @Component -abstract class RendererTemplate implements Renderable { +abstract class RendererTemplate implements IsRenderable { @NonNull protected final ARGBCalculatorProvider argbCalculatorProvider; @@ -20,8 +20,8 @@ public RendererTemplate(@NonNull final ARGBCalculatorProvider argbCalculatorProv } public void render( - @NonNull final Scanable source, - @NonNull final Bufferable target, + @NonNull final IsScanable source, + @NonNull final IsBufferable target, final int xOffset, final int yOffset ) { @@ -52,7 +52,7 @@ public void render( @Override public void renderMergeable( - @NonNull final Mergeable source, + @NonNull final IsMergeable source, @NonNull final PixelBuffer targetBuffer, final int xOffset, final int yOffset @@ -62,8 +62,8 @@ public void renderMergeable( @Override public void renderMergeable( - @NonNull final Mergeable source, - @NonNull final Bufferable target, + @NonNull final IsMergeable source, + @NonNull final IsBufferable target, final int xOffset, final int yOffset ) { @@ -72,7 +72,7 @@ public void renderMergeable( @Override public void setPixelAt( - @NonNull final Bufferable target, + @NonNull final IsBufferable target, final int x, final int y, final int newPixelValue diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/FPSProfilable.java b/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/IsFPSProfilable.java similarity index 76% rename from libs/tacviewfx/src/main/java/com/recom/tacview/strategy/FPSProfilable.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/strategy/IsFPSProfilable.java index fb6765da..ae3d3d5b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/FPSProfilable.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/IsFPSProfilable.java @@ -2,7 +2,7 @@ import lombok.NonNull; -public interface FPSProfilable { +public interface IsFPSProfilable { void setFPS(@NonNull final String profiled); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/ProfileFPSStrategy.java b/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/ProfileFPSStrategy.java index babfadcc..93fa0073 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/ProfileFPSStrategy.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/strategy/ProfileFPSStrategy.java @@ -9,7 +9,7 @@ public class ProfileFPSStrategy { @NonNull - private final FPSProfilable runnable; + private final IsFPSProfilable runnable; public void execute(@NonNull final String profiled) { runnable.setFPS(profiled); diff --git a/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRendererTest.java b/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRendererTest.java index 1c64785f..ab3bdfb0 100644 --- a/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRendererTest.java +++ b/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/MultithreadedSoftwareRendererTest.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderer; -import com.recom.tacview.engine.graphics.Scanable; +import com.recom.tacview.engine.graphics.IsScanable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import com.recom.tacview.engine.renderables.sprite.SpriteAtlas; import com.recom.tacview.engine.units.PixelDimension; @@ -61,7 +61,7 @@ void renderScanableToBuffer() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, 0, 0); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, 0, 0); // ASSERT assertEquals(sourceBufferContent, targetBuffer.scanPixelAt(0, 0)); @@ -79,7 +79,7 @@ void renderScanableToBufferWithOffset() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, 1, 1); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, 1, 1); // ASSERT assertEquals(0, targetBuffer.scanPixelAt(0, 0)); @@ -97,7 +97,7 @@ void renderScanableToBufferWithNegativeOffset() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, -1, -1); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, -1, -1); // ASSERT assertEquals(sourceBufferContent, targetBuffer.scanPixelAt(0, 0)); diff --git a/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/SoftwareRendererTest.java b/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/SoftwareRendererTest.java index 93b8d53d..29316a52 100644 --- a/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/SoftwareRendererTest.java +++ b/libs/tacviewfx/src/test/java/com/recom/tacview/engine/renderer/SoftwareRendererTest.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.renderer; -import com.recom.tacview.engine.graphics.Scanable; +import com.recom.tacview.engine.graphics.IsScanable; import com.recom.tacview.engine.graphics.buffer.PixelBuffer; import com.recom.tacview.engine.renderables.sprite.SpriteAtlas; import com.recom.tacview.engine.units.PixelDimension; @@ -55,7 +55,7 @@ void renderScanableToBuffer() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, 0, 0); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, 0, 0); // ASSERT assertEquals(sourceBufferContent, targetBuffer.scanPixelAt(0, 0)); @@ -73,7 +73,7 @@ void renderScanableToBufferWithOffset() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, 1, 1); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, 1, 1); // ASSERT assertEquals(0, targetBuffer.scanPixelAt(0, 0)); @@ -91,7 +91,7 @@ void renderScanableToBufferWithNegativeOffset() { sourceBuffer.fillBuffer(sourceBufferContent); // EXECUTE - rendererToTest.render((Scanable) sourceBuffer, targetBuffer, -1, -1); + rendererToTest.render((IsScanable) sourceBuffer, targetBuffer, -1, -1); // ASSERT assertEquals(sourceBufferContent, targetBuffer.scanPixelAt(0, 0)); From 7f2a17dd082826b976f647de2c0ebb348eda8c99 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sun, 21 Jan 2024 15:31:52 +0100 Subject: [PATCH 03/23] refactorings ... --- .../com/recom/tacview/engine/TacViewer.java | 4 +- .../MouseCommandMapper.java} | 21 +++------- .../command/mapper/mouse/fsm/FSMStates.java | 6 +++ .../mapper/mouse/fsm/InputAlphabet.java | 6 +++ .../fsm/MouseEventMachine.java} | 40 +++++++------------ 5 files changed, 34 insertions(+), 43 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/{MouseClickCommandMapper.java => mouse/MouseCommandMapper.java} (59%) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/{MouseClickMachine.java => mouse/fsm/MouseEventMachine.java} (71%) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index be7bfbbc..9445eedd 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -3,7 +3,7 @@ import com.recom.tacview.engine.graphics.ScreenComposer; import com.recom.tacview.engine.input.GenericInputEventListener; import com.recom.tacview.engine.input.InputManager; -import com.recom.tacview.engine.input.command.mapper.MouseClickCommandMapper; +import com.recom.tacview.engine.input.command.mapper.mouse.MouseCommandMapper; import com.recom.tacview.engine.module.EngineModule; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.property.TickProperties; @@ -74,7 +74,7 @@ public TacViewer( this.requestFocus(); this.setEventHandler(InputEvent.ANY, this.genericInputEventListener); - this.inputManager.registerCommandMapper(new MouseClickCommandMapper()); + this.inputManager.registerCommandMapper(new MouseCommandMapper()); } @NonNull diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java similarity index 59% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickCommandMapper.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java index 77288ebd..ee9f6833 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java @@ -1,7 +1,9 @@ -package com.recom.tacview.engine.input.command.mapper; +package com.recom.tacview.engine.input.command.mapper.mouse; import com.recom.tacview.engine.input.NanoTimedEvent; import com.recom.tacview.engine.input.command.MouseClickCommand; +import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; +import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseEventMachine; import javafx.scene.input.InputEvent; import javafx.scene.input.MouseEvent; import lombok.NonNull; @@ -12,29 +14,16 @@ import java.util.stream.Stream; @Slf4j -public class MouseClickCommandMapper implements IsInputCommandMapper { +public class MouseCommandMapper implements IsInputCommandMapper { @NonNull private final LinkedList> unprocessedMouseClicks = new LinkedList<>(); @NonNull - private final MouseClickMachine fsm = new MouseClickMachine(Duration.ofMillis(250)); + private final MouseEventMachine fsm = new MouseEventMachine(Duration.ofMillis(250)); @Override public boolean mapEvents(Stream> timedMouseEventStream) { -/* - leerer stream kann hier kommen ... - wir können als in jedem tick rückwirkend schauen ob es einen unprocessedMouseClickStream eintrag - dazu schauen wir ob das erste event 200ms alt ist - wenn ja, dann ist es ein click-kanidat - wenn es ein zweites, nachfolgendes event gibt welches maximal 200 ms älter ist, dann ist es ein doubleclick-event; - wird gemapped und die beiden events werden aus der liste entfernt; dann wird der strom rekursiv weiterverarbeitet - bis er leer ist oder kein klick-kandidadat oder doubleclick-event mehr gefunden wird - - das machen wir mit einem Zustandsautomaten? Ist das nicht zu kompliziert? - Eignet sich ein Zustandsautomat dafür? - Zustände: idle/leer, klick-kandidat, doubleclick-kandidat, klick-emitter, doubleclick-emitter - */ timedMouseEventStream .filter(nanoTimedEvent -> nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_CLICKED) .forEach(unprocessedMouseClicks::add); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java new file mode 100644 index 00000000..5bcf8b54 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java @@ -0,0 +1,6 @@ +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; + +enum FSMStates { + IDLE, + CLICK_CANDIDATE +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java new file mode 100644 index 00000000..8c935c12 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java @@ -0,0 +1,6 @@ +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; + +enum InputAlphabet { + EMPTY, + NEW_CLICK_CANDIDATE +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickMachine.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java similarity index 71% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickMachine.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java index 357761ae..78e50ae6 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/MouseClickMachine.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java @@ -1,4 +1,4 @@ -package com.recom.tacview.engine.input.command.mapper; +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; import com.recom.tacview.engine.input.NanoTimedEvent; import com.recom.tacview.engine.input.command.MouseClickCommand; @@ -12,13 +12,13 @@ import java.util.LinkedList; @Slf4j -public class MouseClickMachine { +public class MouseEventMachine { @NonNull private final long doubleClickThresholdNanos; @NonNull - private STATE currentMachineState = STATE.IDLE; + private FSMStates currentMachineState = FSMStates.IDLE; @Nullable private NanoTimedEvent eventCandidateBuffer; @@ -28,7 +28,7 @@ public class MouseClickMachine { private final LinkedList bufferedCommands = new LinkedList<>(); - public MouseClickMachine(@NonNull final Duration doubleClickThreshold) { + public MouseEventMachine(@NonNull final Duration doubleClickThreshold) { this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); } @@ -41,35 +41,35 @@ public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouse } private void update(@Nullable final NanoTimedEvent nextEvent) { - final INPUT_ALPHABET input = determineInputAlphabet(nextEvent); + final InputAlphabet input = determineInputAlphabet(nextEvent); switch (currentMachineState) { case IDLE -> { - if (input == INPUT_ALPHABET.NEW_CLICK_CANDIDATE) { + if (input == InputAlphabet.NEW_CLICK_CANDIDATE) { assert nextEvent != null; eventCandidateBuffer = nextEvent; - currentMachineState = STATE.CLICK_CANDIDATE; + currentMachineState = FSMStates.CLICK_CANDIDATE; } } case CLICK_CANDIDATE -> { - if (input == INPUT_ALPHABET.EMPTY) { + if (input == InputAlphabet.EMPTY) { assert nextEvent == null; assert eventCandidateBuffer != null; if (doubleClickThresholdExpired(eventCandidateBuffer)) { bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); eventCandidateBuffer = null; - currentMachineState = STATE.IDLE; + currentMachineState = FSMStates.IDLE; } - } else if (input == INPUT_ALPHABET.NEW_CLICK_CANDIDATE) { + } else if (input == InputAlphabet.NEW_CLICK_CANDIDATE) { assert nextEvent != null; assert eventCandidateBuffer != null; if (doubleClickThresholdExpired(eventCandidateBuffer)) { bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); eventCandidateBuffer = nextEvent; - currentMachineState = STATE.CLICK_CANDIDATE; + currentMachineState = FSMStates.CLICK_CANDIDATE; } else { eventCandidateBuffer = null; bufferedCommands.add(MouseClickCommand.doubleClickCommand(nextEvent)); - currentMachineState = STATE.IDLE; + currentMachineState = FSMStates.IDLE; } } } @@ -84,22 +84,12 @@ private boolean doubleClickThresholdExpired(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { + private InputAlphabet determineInputAlphabet(@Nullable final NanoTimedEvent nextNanoTimedMouseEvent) { if (nextNanoTimedMouseEvent == null) { - return INPUT_ALPHABET.EMPTY; + return InputAlphabet.EMPTY; } else { - return INPUT_ALPHABET.NEW_CLICK_CANDIDATE; + return InputAlphabet.NEW_CLICK_CANDIDATE; } } - enum STATE { - IDLE, - CLICK_CANDIDATE - } - - enum INPUT_ALPHABET { - EMPTY, - NEW_CLICK_CANDIDATE - } - } From 64f2e004c7fb7afc888fa400c37f5de38586e376 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sun, 21 Jan 2024 17:59:15 +0100 Subject: [PATCH 04/23] fix: different mouse-click-buttons can lead to a double click issue --- TODO.md | 2 +- .../com/recom/tacview/engine/TacViewer.java | 11 ++++++----- ...r.java => GenericFXInputEventListener.java} | 5 +---- .../command/mapper/IsInputCommandMapper.java | 4 +++- .../mapper/mouse/MouseCommandMapper.java | 5 +++-- .../mapper/mouse/fsm/MouseEventMachine.java | 18 ++++++++++++------ .../initializr/TacViewStageInitializer.java | 6 +++--- 7 files changed, 29 insertions(+), 22 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{GenericInputEventListener.java => GenericFXInputEventListener.java} (69%) diff --git a/TODO.md b/TODO.md index cb9e1b82..4c226869 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,7 @@ * * InputCommands (<-) * MouseClick (/) - * MouseDrag (<-) + * MouseDrag (<--------------------) * MouseWheel * Keyboard * PhysicsCore holds position in TransformComponent or Object diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 9445eedd..8482bb8b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -1,7 +1,7 @@ package com.recom.tacview.engine; import com.recom.tacview.engine.graphics.ScreenComposer; -import com.recom.tacview.engine.input.GenericInputEventListener; +import com.recom.tacview.engine.input.GenericFXInputEventListener; import com.recom.tacview.engine.input.InputManager; import com.recom.tacview.engine.input.command.mapper.mouse.MouseCommandMapper; import com.recom.tacview.engine.module.EngineModule; @@ -31,7 +31,7 @@ public class TacViewer extends Canvas { @NonNull private final EngineModule engineModule; @NonNull - private final GenericInputEventListener genericInputEventListener; + private final GenericFXInputEventListener genericFXInputEventListener; @NonNull private final InputManager inputManager; @@ -53,7 +53,7 @@ public TacViewer( @NonNull final ProfilerProvider profilerProvider, @NonNull final ScreenComposer screenComposer, @NonNull final EngineModule engineModule, - @NonNull final GenericInputEventListener genericInputEventListener, + @NonNull final GenericFXInputEventListener genericFXInputEventListener, @NonNull final InputManager inputManager ) { super(rendererProperties.getWidth(), rendererProperties.getHeight()); @@ -61,7 +61,7 @@ public TacViewer( this.tickProperties = tickProperties; this.screenComposer = screenComposer; this.engineModule = engineModule; - this.genericInputEventListener = genericInputEventListener; + this.genericFXInputEventListener = genericFXInputEventListener; this.inputManager = inputManager; this.canvasBuffer = new CanvasBufferSwapCommand(this, rendererProperties, screenComposer); @@ -72,8 +72,9 @@ public TacViewer( this.setFocusTraversable(true); this.requestFocus(); - this.setEventHandler(InputEvent.ANY, this.genericInputEventListener); + // register input event listener + this.setEventHandler(InputEvent.ANY, this.genericFXInputEventListener); this.inputManager.registerCommandMapper(new MouseCommandMapper()); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericInputEventListener.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericFXInputEventListener.java similarity index 69% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericInputEventListener.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericFXInputEventListener.java index fcdd0a47..5059a070 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericInputEventListener.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/GenericFXInputEventListener.java @@ -1,10 +1,7 @@ package com.recom.tacview.engine.input; -import com.recom.tacview.engine.input.InputManager; -import com.recom.tacview.engine.input.NanoTimedEvent; import javafx.event.EventHandler; import javafx.scene.input.InputEvent; -import javafx.scene.input.MouseEvent; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -13,7 +10,7 @@ @Slf4j @Service @RequiredArgsConstructor -public class GenericInputEventListener implements EventHandler { +public class GenericFXInputEventListener implements EventHandler { @NonNull private final InputManager inputManager; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java index eac89b9e..dbd4bd44 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java @@ -3,6 +3,7 @@ import com.recom.tacview.engine.input.NanoTimedEvent; import com.recom.tacview.engine.input.command.IsInputCommand; import javafx.scene.input.InputEvent; +import lombok.NonNull; import java.util.Collection; import java.util.LinkedList; @@ -10,8 +11,9 @@ public interface IsInputCommandMapper { - boolean mapEvents(final Stream> inputEventStream); + boolean mapEvents(@NonNull final Stream> inputEventStream); + @NonNull LinkedList getCreatedCommands(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java index ee9f6833..073eef24 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java @@ -19,11 +19,11 @@ public class MouseCommandMapper implements IsInputCommandMapper { @NonNull private final LinkedList> unprocessedMouseClicks = new LinkedList<>(); @NonNull - private final MouseEventMachine fsm = new MouseEventMachine(Duration.ofMillis(250)); + private final MouseEventMachine fsm = new MouseEventMachine(Duration.ofMillis(200)); @Override - public boolean mapEvents(Stream> timedMouseEventStream) { + public boolean mapEvents(@NonNull final Stream> timedMouseEventStream) { timedMouseEventStream .filter(nanoTimedEvent -> nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_CLICKED) .forEach(unprocessedMouseClicks::add); @@ -41,6 +41,7 @@ private boolean runMouseClickFSM() { return !fsm.getBufferedCommands().isEmpty(); } + @NonNull @Override @SuppressWarnings("unchecked") public LinkedList getCreatedCommands() { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java index 78e50ae6..57709f71 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java @@ -33,14 +33,14 @@ public MouseEventMachine(@NonNull final Duration doubleClickThreshold) { } public void iterate() { - update(null); + updateMachine(null); } public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { - update(nextNanoTimedMouseEvent); + updateMachine(nextNanoTimedMouseEvent); } - private void update(@Nullable final NanoTimedEvent nextEvent) { + private void updateMachine(@Nullable final NanoTimedEvent nextEvent) { final InputAlphabet input = determineInputAlphabet(nextEvent); switch (currentMachineState) { case IDLE -> { @@ -67,9 +67,15 @@ private void update(@Nullable final NanoTimedEvent nextEvent) { eventCandidateBuffer = nextEvent; currentMachineState = FSMStates.CLICK_CANDIDATE; } else { - eventCandidateBuffer = null; - bufferedCommands.add(MouseClickCommand.doubleClickCommand(nextEvent)); - currentMachineState = FSMStates.IDLE; + if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { + bufferedCommands.add(MouseClickCommand.doubleClickCommand(nextEvent)); + eventCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } else { + bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); + eventCandidateBuffer = nextEvent; + currentMachineState = FSMStates.CLICK_CANDIDATE; + } } } } diff --git a/services/recom-commander/src/main/java/com/recom/commander/initializr/TacViewStageInitializer.java b/services/recom-commander/src/main/java/com/recom/commander/initializr/TacViewStageInitializer.java index 6b29709c..b16b742f 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/initializr/TacViewStageInitializer.java +++ b/services/recom-commander/src/main/java/com/recom/commander/initializr/TacViewStageInitializer.java @@ -7,7 +7,7 @@ import com.recom.tacview.engine.TacViewer; import com.recom.tacview.engine.graphics.ScreenComposer; import com.recom.tacview.engine.input.InputManager; -import com.recom.tacview.engine.input.GenericInputEventListener; +import com.recom.tacview.engine.input.GenericFXInputEventListener; import com.recom.tacview.engine.module.EngineModule; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.property.TickProperties; @@ -49,7 +49,7 @@ public class TacViewStageInitializer { @NonNull private final EngineModule engineModule; @NonNull - private final GenericInputEventListener genericInputEventListener; + private final GenericFXInputEventListener genericFXInputEventListener; @NonNull private final InputManager inputManager; @@ -79,7 +79,7 @@ private void populateTacViewStage(@NonNull final Stage stage) { profilerProvider, screenComposer, engineModule, - genericInputEventListener, + genericFXInputEventListener, inputManager ); root.setCenter(tacViewer); From f7431964fa43b7a0aa629452876f698ef945efef Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 00:11:50 +0100 Subject: [PATCH 05/23] work in mouseFSM wip; works good --- .../com/recom/tacview/engine/TacViewer.java | 4 +- .../tacview/engine/input/NanoTimedEvent.java | 5 + .../mouse/JavaFxMouseCommandMapper.java | 84 +++++++++ .../mapper/mouse/MouseCommandMapper.java | 54 ------ .../command/mapper/mouse/fsm/FSMStates.java | 5 +- .../mapper/mouse/fsm/InputAlphabet.java | 13 +- .../mapper/mouse/fsm/IsMouseEventFSM.java | 25 +++ .../mapper/mouse/fsm/MouseEventFSM0.java | 145 +++++++++++++++ .../mapper/mouse/fsm/MouseEventFSM1.java | 176 ++++++++++++++++++ .../mapper/mouse/fsm/MouseEventFSM1.puml | 36 ++++ .../mapper/mouse/fsm/MouseEventMachine.java | 101 ---------- .../input/command/mouse/IsMouseCommand.java | 6 + .../input/command/mouse/MouseButton.java | 8 + .../MouseButtonCommand.java} | 27 +-- .../input/command/mouse/MouseDragCommand.java | 78 ++++++++ .../component/RECOMMapInputComponent.java | 8 +- 16 files changed, 594 insertions(+), 181 deletions(-) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java delete mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml delete mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{MouseClickCommand.java => mouse/MouseButtonCommand.java} (71%) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 8482bb8b..41d669e3 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -3,7 +3,7 @@ import com.recom.tacview.engine.graphics.ScreenComposer; import com.recom.tacview.engine.input.GenericFXInputEventListener; import com.recom.tacview.engine.input.InputManager; -import com.recom.tacview.engine.input.command.mapper.mouse.MouseCommandMapper; +import com.recom.tacview.engine.input.command.mapper.mouse.JavaFxMouseCommandMapper; import com.recom.tacview.engine.module.EngineModule; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.property.TickProperties; @@ -75,7 +75,7 @@ public TacViewer( // register input event listener this.setEventHandler(InputEvent.ANY, this.genericFXInputEventListener); - this.inputManager.registerCommandMapper(new MouseCommandMapper()); + this.inputManager.registerCommandMapper(new JavaFxMouseCommandMapper()); } @NonNull diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/NanoTimedEvent.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/NanoTimedEvent.java index 80d4ef1f..c23622ce 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/NanoTimedEvent.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/NanoTimedEvent.java @@ -26,4 +26,9 @@ public static NanoTimedEvent of( return new NanoTimedEvent(timestamp, event); } + @SuppressWarnings("unchecked") + public NanoTimedEvent cast() { + return new NanoTimedEvent<>(this.getNanos(), (TARGET) this.getEvent()); + } + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java new file mode 100644 index 00000000..0ca16e7d --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -0,0 +1,84 @@ +package com.recom.tacview.engine.input.command.mapper.mouse; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; +import com.recom.tacview.engine.input.command.mapper.mouse.fsm.IsMouseEventFSM; +import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseEventFSM1; +import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import javafx.scene.input.InputEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.util.LinkedList; +import java.util.stream.Stream; + +@Slf4j +public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoCloseable { + + @NonNull + private final LinkedList> unprocessedMouseEvents = new LinkedList<>(); + @NonNull + private final IsMouseEventFSM primaryMouseButtonFSM = new MouseEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); + @NonNull + private final IsMouseEventFSM secondaryMouseButtonFSM = new MouseEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); + + public JavaFxMouseCommandMapper() { + primaryMouseButtonFSM.start(); + secondaryMouseButtonFSM.start(); + } + + + @Override + @SuppressWarnings("unchecked") + public boolean mapEvents(@NonNull final Stream> timedMouseEventStream) { + timedMouseEventStream + .filter(event -> event.getEvent() instanceof MouseEvent) + .map(event -> (NanoTimedEvent) event) + .filter(this::isObservedMouseEvent) + .forEach(unprocessedMouseEvents::add); + + return runMouseClickFSM(); + } + + private boolean isObservedMouseEvent( + @NonNull final NanoTimedEvent nanoTimedEvent + ) { + return nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED + || nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED + || nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_DRAGGED; + } + + private boolean runMouseClickFSM() { + while (!unprocessedMouseEvents.isEmpty()) { + final NanoTimedEvent polledMouseEvent = unprocessedMouseEvents.poll(); + primaryMouseButtonFSM.iterate(polledMouseEvent); + secondaryMouseButtonFSM.iterate(polledMouseEvent); + } + primaryMouseButtonFSM.iterate(); + secondaryMouseButtonFSM.iterate(); + + return !primaryMouseButtonFSM.getBufferedCommands().isEmpty() || !secondaryMouseButtonFSM.getBufferedCommands().isEmpty(); + } + + @NonNull + @Override + @SuppressWarnings("unchecked") + public LinkedList getCreatedCommands() { + final LinkedList createdCommands = (LinkedList) primaryMouseButtonFSM.getBufferedCommands().clone(); + createdCommands.addAll((LinkedList) secondaryMouseButtonFSM.getBufferedCommands().clone()); + primaryMouseButtonFSM.getBufferedCommands().clear(); + secondaryMouseButtonFSM.getBufferedCommands().clear(); + + return createdCommands; + } + + @Override + public void close() { + primaryMouseButtonFSM.stop(); + secondaryMouseButtonFSM.stop(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java deleted file mode 100644 index 073eef24..00000000 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/MouseCommandMapper.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.recom.tacview.engine.input.command.mapper.mouse; - -import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.MouseClickCommand; -import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; -import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseEventMachine; -import javafx.scene.input.InputEvent; -import javafx.scene.input.MouseEvent; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; - -import java.time.Duration; -import java.util.LinkedList; -import java.util.stream.Stream; - -@Slf4j -public class MouseCommandMapper implements IsInputCommandMapper { - - @NonNull - private final LinkedList> unprocessedMouseClicks = new LinkedList<>(); - @NonNull - private final MouseEventMachine fsm = new MouseEventMachine(Duration.ofMillis(200)); - - - @Override - public boolean mapEvents(@NonNull final Stream> timedMouseEventStream) { - timedMouseEventStream - .filter(nanoTimedEvent -> nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_CLICKED) - .forEach(unprocessedMouseClicks::add); - - return runMouseClickFSM(); - } - - @SuppressWarnings("unchecked") - private boolean runMouseClickFSM() { - while (!unprocessedMouseClicks.isEmpty()) { - fsm.iterate((NanoTimedEvent) unprocessedMouseClicks.poll()); - } - fsm.iterate(); - - return !fsm.getBufferedCommands().isEmpty(); - } - - @NonNull - @Override - @SuppressWarnings("unchecked") - public LinkedList getCreatedCommands() { - final LinkedList createdCommands = (LinkedList) fsm.getBufferedCommands().clone(); - fsm.getBufferedCommands().clear(); - - return createdCommands; - } - -} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java index 5bcf8b54..9ea8f659 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java @@ -1,6 +1,9 @@ package com.recom.tacview.engine.input.command.mapper.mouse.fsm; enum FSMStates { + NEW, IDLE, - CLICK_CANDIDATE + CLICK_CANDIDATE, + MOUSE_DRAGGING, + STOPPED } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java index 8c935c12..9a7b5350 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java @@ -1,6 +1,15 @@ package com.recom.tacview.engine.input.command.mapper.mouse.fsm; enum InputAlphabet { - EMPTY, - NEW_CLICK_CANDIDATE + IDLING, + CLICK_THRESHOLD_EXCEEDED, + DOUBLECLICK_THRESHOLD_EXCEEDED, + CLICK_COMMAND, + DOUBLE_CLICK_COMMAND, + MOUSE_PRESSED, + MOUSE_RELEASED, + MOUSE_DRAG_STARTED, + MOUSE_DRAGGING, + UNHANDLED, + STOP } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java new file mode 100644 index 00000000..279a24f2 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java @@ -0,0 +1,25 @@ +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; +import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import javafx.scene.input.MouseEvent; +import lombok.NonNull; + +import java.util.LinkedList; + +public interface IsMouseEventFSM { + + void iterate(); + + void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent); + + @NonNull + LinkedList getBufferedCommands(); + + void start(); + + void stop(); + + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java new file mode 100644 index 00000000..c44a5145 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java @@ -0,0 +1,145 @@ +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; +import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import javafx.event.EventType; +import javafx.scene.input.MouseEvent; +import lombok.Getter; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.Nullable; + +import java.time.Duration; +import java.util.LinkedList; + +@Slf4j +public class MouseEventFSM0 implements IsMouseEventFSM { + + @NonNull + private final long doubleClickThresholdNanos; + @NonNull + private final long dragThresholdNanos; + + @NonNull + private FSMStates currentMachineState = FSMStates.IDLE; + + @Nullable + private NanoTimedEvent eventCandidateBuffer; + + @Getter + @NonNull + private final LinkedList bufferedCommands = new LinkedList<>(); + + + public MouseEventFSM0(@NonNull final Duration doubleClickThreshold) { + this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); + this.dragThresholdNanos = Duration.ofMillis(200).toNanos(); + } + + @Override + public void start() { + currentMachineState = FSMStates.IDLE; + } + + @Override + public void stop() { + currentMachineState = FSMStates.STOPPED; + } + + public void iterate() { + engineRevolution(null); + } + + public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { + engineRevolution(nextNanoTimedMouseEvent); + } + + private void engineRevolution(@Nullable final NanoTimedEvent nextEvent) { + final InputAlphabet input = determineInputAlphabet(nextEvent); +// if (nextEvent != null && !input.equals(InputAlphabet.UNHANDLED)) { +// log.info("Next Event: {}", nextEvent.getEvent().toString()); +// } + switch (currentMachineState) { + case IDLE -> { + if (input == InputAlphabet.MOUSE_PRESSED) { + assert nextEvent != null; + eventCandidateBuffer = nextEvent; + currentMachineState = FSMStates.CLICK_CANDIDATE; + } + } + case CLICK_CANDIDATE -> { + if (input == InputAlphabet.IDLING) { + assert nextEvent == null; + assert eventCandidateBuffer != null; + if (clickThresholdExpired(eventCandidateBuffer)) { + bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); + eventCandidateBuffer = null; + currentMachineState = FSMStates.MOUSE_DRAGGING; + } + } else if (input == InputAlphabet.MOUSE_RELEASED) { + assert nextEvent != null; + if (eventCandidateBuffer != null && !clickThresholdExpired(eventCandidateBuffer)) { + if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { + bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); + eventCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } else { + // @TODO: ?! + // anderer Button gedrückt -> ignorieren ! ? + // ansonsten bräuchte buffers für jeden button!!!! + } + } + } else if (input == InputAlphabet.MOUSE_PRESSED) { + assert nextEvent != null; + assert eventCandidateBuffer != null; + if (clickThresholdExpired(eventCandidateBuffer)) { + bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); + eventCandidateBuffer = nextEvent; + currentMachineState = FSMStates.CLICK_CANDIDATE; + } else { + if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { + bufferedCommands.add(MouseButtonCommand.doubleClickCommand(nextEvent)); + eventCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } else { + bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); + eventCandidateBuffer = nextEvent; + currentMachineState = FSMStates.CLICK_CANDIDATE; + } + } + } + } + case MOUSE_DRAGGING -> { + log.info("Mouse drag entered"); + } + default -> { + throw new IllegalStateException(String.format("Unexpected Transition via State:%1s -> Input:%2s", currentMachineState, input)); + } + } + } + + private boolean clickThresholdExpired(@NonNull final NanoTimedEvent event) { + return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; + } + + private boolean dragThresholdExpired(@NonNull final NanoTimedEvent event) { + return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; + } + + @NonNull + private InputAlphabet determineInputAlphabet(@Nullable final NanoTimedEvent nextNanoTimedMouseEvent) { + if (nextNanoTimedMouseEvent == null) { + return InputAlphabet.IDLING; + } else { + final EventType eventType = nextNanoTimedMouseEvent.getEvent().getEventType(); + + if (eventType == MouseEvent.MOUSE_PRESSED) { + return InputAlphabet.MOUSE_PRESSED; + } + } + + return InputAlphabet.UNHANDLED; + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java new file mode 100644 index 00000000..64ddc115 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java @@ -0,0 +1,176 @@ +package com.recom.tacview.engine.input.command.mapper.mouse.fsm; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; +import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import com.recom.tacview.engine.input.command.mouse.MouseDragCommand; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseDragEvent; +import javafx.scene.input.MouseEvent; +import lombok.Getter; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.Nullable; + +import java.time.Duration; +import java.util.LinkedList; + +@Slf4j +public class MouseEventFSM1 implements IsMouseEventFSM { + + @NonNull + private final long doubleClickThresholdNanos; + @NonNull + private final long dragThresholdNanos; + @NonNull + private final MouseButton responsibleForMouseButton; + + @NonNull + private FSMStates currentMachineState = FSMStates.NEW; + + @Nullable + private NanoTimedEvent clickCandidateBuffer; + + @Getter + @NonNull + private final LinkedList bufferedCommands = new LinkedList<>(); + + + public MouseEventFSM1( + @NonNull final Duration doubleClickThreshold, + @NonNull final Duration dragThreshold, + @NonNull final MouseButton responsibleForMouseButton + ) { + this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); + this.dragThresholdNanos = dragThreshold.toNanos(); + this.responsibleForMouseButton = responsibleForMouseButton; + } + + public void iterate() { + machineRevolution(null); + } + + public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { + machineRevolution(nextNanoTimedMouseEvent); + } + + @Override + public void start() { + currentMachineState = FSMStates.IDLE; + } + + @Override + public void stop() { + currentMachineState = FSMStates.STOPPED; + } + + private void machineRevolution(@Nullable final NanoTimedEvent nextEvent) { + if (fsmIsNotResponsibleForMouseButtonRelatedEvents(nextEvent)) { + return; + } + + switch (currentMachineState) { + case IDLE -> { + switch (idleAlphabet(nextEvent)) { + case IDLING -> { + // do nothing + } + case MOUSE_PRESSED -> { + assert nextEvent != null; + + clickCandidateBuffer = nextEvent; + currentMachineState = FSMStates.CLICK_CANDIDATE; + } + } + } + case CLICK_CANDIDATE -> { + assert clickCandidateBuffer != null; + switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { + case CLICK_THRESHOLD_EXCEEDED -> { + bufferedCommands.add(MouseButtonCommand.singleClickCommand(clickCandidateBuffer)); + clickCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } + case MOUSE_PRESSED -> { + assert nextEvent != null; + + bufferedCommands.add(MouseButtonCommand.doubleClickCommand(nextEvent)); + clickCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } + case MOUSE_DRAG_STARTED -> { + assert clickCandidateBuffer != null; + assert clickCandidateBuffer.getEvent() instanceof MouseDragEvent; + + bufferedCommands.add(MouseDragCommand.dragStartCommand(clickCandidateBuffer.cast())); + clickCandidateBuffer = null; + currentMachineState = FSMStates.MOUSE_DRAGGING; + } + case IDLING -> { + // do nothing + } + } + } + case MOUSE_DRAGGING -> { + switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { + case IDLING -> { + // do nothing + } + case MOUSE_DRAGGING -> { + + } + case MOUSE_RELEASED -> { + assert clickCandidateBuffer.getEvent() instanceof MouseDragEvent; + + bufferedCommands.add(MouseDragCommand.dragStopCommand(clickCandidateBuffer.cast())); + clickCandidateBuffer = null; + currentMachineState = FSMStates.IDLE; + } + } + } + default -> { + throw new IllegalStateException(String.format("Unexpected Transition via State:%1s -> Input:%2s", currentMachineState, nextEvent)); + } + } + } + + private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final NanoTimedEvent nextEvent) { + return nextEvent != null && (nextEvent.getEvent().getButton() != responsibleForMouseButton); + } + + @NonNull + private InputAlphabet idleAlphabet(@Nullable final NanoTimedEvent nextEvent) { + if (nextEvent == null) { + return InputAlphabet.IDLING; + } else if (nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { + return InputAlphabet.MOUSE_PRESSED; + } else { + return InputAlphabet.UNHANDLED; + } + } + + @NonNull + private InputAlphabet clickCandidateAlphabet( + @Nullable final NanoTimedEvent nextEvent, + @NonNull NanoTimedEvent clickCandidateBuffer + ) { + if (nextEvent == null && clickThresholdExceeded(clickCandidateBuffer)) { + return InputAlphabet.CLICK_THRESHOLD_EXCEEDED; + } else if (nextEvent == null && dragThresholdExceeded(clickCandidateBuffer) && clickCandidateBuffer.getEvent() instanceof MouseDragEvent) { + return InputAlphabet.MOUSE_DRAG_STARTED; + } else if (nextEvent != null && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { + return InputAlphabet.MOUSE_PRESSED; + } else { + return InputAlphabet.IDLING; + } + } + + private boolean clickThresholdExceeded(@NonNull final NanoTimedEvent event) { + return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; + } + + private boolean dragThresholdExceeded(@NonNull final NanoTimedEvent event) { + return (System.nanoTime() - event.getNanos()) > dragThresholdNanos; + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml new file mode 100644 index 00000000..d3db4dc1 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml @@ -0,0 +1,36 @@ +@startuml + +header RECOM Tacviewer +title Mouse Event FSM v1.0 +caption Each mouse button has its own state machine +footer RECOM.one + + +[*] --> IDLE :start + +IDLE --> IDLE : IDLING +IDLE --> CLICK_CANDIDATE : MOUSE_PRESSED +CLICK_CANDIDATE --> IDLE : CLICK_THRESHOLD_EXCEEDED\n MOUSE_PRESS\n +CLICK_CANDIDATE --> MOUSE_DRAGGING : MOUSE_DRAG_STARTED +CLICK_CANDIDATE --> CLICK_CANDIDATE : IDLING +MOUSE_DRAGGING --> MOUSE_DRAGGING : MOUSE_DRAGGING +MOUSE_DRAGGING --> IDLE : MOUSE_RELEASED + +IDLE --> [*] :stop +CLICK_CANDIDATE --> [*] :stop +MOUSE_DRAGGING --> [*] :stop + + +legend left +__**ALPHABET**__ +| **Symbol** | **Description** | +| start | on class initialization | +| IDLING | new engine revolution without event | +| CLICK_THRESHOLD_EXCEEDED | new engine revolution without event | +| MOUSE_PRESSED | Mouse Press Event | +| MOUSE_RELEASED | Mouse Release Event | +| MOUSE_DRAG_STARTED | when mouse is pushed and not released within mouse click threshold | +| MOUSE_DRAGGING | when mouse is pushed and moved | +endlegend + +@enduml \ No newline at end of file diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java deleted file mode 100644 index 57709f71..00000000 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventMachine.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; - -import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.MouseClickCommand; -import javafx.scene.input.MouseEvent; -import lombok.Getter; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import org.springframework.lang.Nullable; - -import java.time.Duration; -import java.util.LinkedList; - -@Slf4j -public class MouseEventMachine { - - @NonNull - private final long doubleClickThresholdNanos; - - @NonNull - private FSMStates currentMachineState = FSMStates.IDLE; - - @Nullable - private NanoTimedEvent eventCandidateBuffer; - - @Getter - @NonNull - private final LinkedList bufferedCommands = new LinkedList<>(); - - - public MouseEventMachine(@NonNull final Duration doubleClickThreshold) { - this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); - } - - public void iterate() { - updateMachine(null); - } - - public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { - updateMachine(nextNanoTimedMouseEvent); - } - - private void updateMachine(@Nullable final NanoTimedEvent nextEvent) { - final InputAlphabet input = determineInputAlphabet(nextEvent); - switch (currentMachineState) { - case IDLE -> { - if (input == InputAlphabet.NEW_CLICK_CANDIDATE) { - assert nextEvent != null; - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } - } - case CLICK_CANDIDATE -> { - if (input == InputAlphabet.EMPTY) { - assert nextEvent == null; - assert eventCandidateBuffer != null; - if (doubleClickThresholdExpired(eventCandidateBuffer)) { - bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = null; - currentMachineState = FSMStates.IDLE; - } - } else if (input == InputAlphabet.NEW_CLICK_CANDIDATE) { - assert nextEvent != null; - assert eventCandidateBuffer != null; - if (doubleClickThresholdExpired(eventCandidateBuffer)) { - bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } else { - if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { - bufferedCommands.add(MouseClickCommand.doubleClickCommand(nextEvent)); - eventCandidateBuffer = null; - currentMachineState = FSMStates.IDLE; - } else { - bufferedCommands.add(MouseClickCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } - } - } - } - default -> { - throw new IllegalStateException(String.format("Unexpected Transition via State:%1s -> Input:%2s", currentMachineState, input)); - } - } - } - - private boolean doubleClickThresholdExpired(@NonNull final NanoTimedEvent event) { - return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; - } - - @NonNull - private InputAlphabet determineInputAlphabet(@Nullable final NanoTimedEvent nextNanoTimedMouseEvent) { - if (nextNanoTimedMouseEvent == null) { - return InputAlphabet.EMPTY; - } else { - return InputAlphabet.NEW_CLICK_CANDIDATE; - } - } - -} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java new file mode 100644 index 00000000..a6af3ee3 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java @@ -0,0 +1,6 @@ +package com.recom.tacview.engine.input.command.mouse; + +import com.recom.tacview.engine.input.command.IsInputCommand; + +public interface IsMouseCommand extends IsInputCommand { +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java new file mode 100644 index 00000000..895838dd --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java @@ -0,0 +1,8 @@ +package com.recom.tacview.engine.input.command.mouse; + +public enum MouseButton { + PRIMARY, + SECONDARY, + MIDDLE, + OTHER +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/MouseClickCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java similarity index 71% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/MouseClickCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java index db7638f8..81fc35bb 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/MouseClickCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java @@ -1,41 +1,41 @@ -package com.recom.tacview.engine.input.command; +package com.recom.tacview.engine.input.command.mouse; import com.recom.tacview.engine.input.NanoTimedEvent; import javafx.scene.input.MouseEvent; import lombok.Getter; import lombok.NonNull; -public class MouseClickCommand implements IsInputCommand { +public class MouseButtonCommand implements IsMouseCommand { @NonNull private final NanoTimedEvent nanoTimedMouseEvent; @Getter - private final boolean isDoubleClick; + private final boolean doubleClick; @Getter @NonNull private final MouseButton mouseButton; @NonNull - public static MouseClickCommand singleClickCommand( + public static MouseButtonCommand singleClickCommand( @NonNull final NanoTimedEvent nanoTimedMouseEvent ) { - return new MouseClickCommand(nanoTimedMouseEvent, false); + return new MouseButtonCommand(nanoTimedMouseEvent, false); } @NonNull - public static MouseClickCommand doubleClickCommand( + public static MouseButtonCommand doubleClickCommand( @NonNull final NanoTimedEvent nanoTimedMouseEvent ) { - return new MouseClickCommand(nanoTimedMouseEvent, true); + return new MouseButtonCommand(nanoTimedMouseEvent, true); } - public MouseClickCommand( + public MouseButtonCommand( @NonNull final NanoTimedEvent nanoTimedMouseEvent, final boolean isDoubleClick ) { this.nanoTimedMouseEvent = nanoTimedMouseEvent; - this.isDoubleClick = isDoubleClick; + this.doubleClick = isDoubleClick; this.mouseButton = determineMouseButton(nanoTimedMouseEvent.getEvent()); } @@ -44,7 +44,7 @@ private MouseButton determineMouseButton(@NonNull final MouseEvent event) { return switch (event.getButton()) { case PRIMARY -> MouseButton.PRIMARY; case SECONDARY -> MouseButton.SECONDARY; - case MIDDLE -> MouseButton.TERNARY; + case MIDDLE -> MouseButton.MIDDLE; default -> MouseButton.OTHER; }; } @@ -66,11 +66,4 @@ public NanoTimedEvent getNanoTimedMouseEvent() { return nanoTimedMouseEvent; } - enum MouseButton { - PRIMARY, - SECONDARY, - TERNARY, - OTHER - } - } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java new file mode 100644 index 00000000..86af1c22 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java @@ -0,0 +1,78 @@ +package com.recom.tacview.engine.input.command.mouse; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import javafx.scene.input.MouseDragEvent; +import javafx.scene.input.MouseEvent; +import lombok.Getter; +import lombok.NonNull; + +public class MouseDragCommand implements IsMouseCommand { + + @NonNull + private final NanoTimedEvent nanoTimedMouseEvent; + @Getter + private final boolean dragStart; + private final boolean dragStop; + @Getter + @NonNull + private final MouseButton mouseButton; + + + @NonNull + public static MouseDragCommand dragStartCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + return new MouseDragCommand(nanoTimedMouseEvent, true, false); + } + + @NonNull + public static MouseDragCommand dragStopCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + return new MouseDragCommand(nanoTimedMouseEvent, false, true); + } + + @NonNull + public static MouseDragCommand dragginCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + return new MouseDragCommand(nanoTimedMouseEvent, false, false); + } + + public MouseDragCommand( + @NonNull final NanoTimedEvent nanoTimedMouseEvent, + final boolean startMouseDrag, + final boolean stopMouseDrag + ) { + this.nanoTimedMouseEvent = nanoTimedMouseEvent; + this.dragStart = startMouseDrag; + this.dragStop = stopMouseDrag; + this.mouseButton = determineMouseButton(nanoTimedMouseEvent.getEvent()); + } + + @NonNull + private MouseButton determineMouseButton(@NonNull final MouseEvent event) { + return switch (event.getButton()) { + case PRIMARY -> MouseButton.PRIMARY; + case SECONDARY -> MouseButton.SECONDARY; + case MIDDLE -> MouseButton.MIDDLE; + default -> MouseButton.OTHER; + }; + } + + public boolean isDragging() { + return !dragStart && !dragStop; + } + + public double getPositionX() { + return nanoTimedMouseEvent.getEvent().getX(); + } + + public double getPositionY() { + return nanoTimedMouseEvent.getEvent().getY(); + } + + @NonNull + public NanoTimedEvent getNanoTimedMouseEvent() { + nanoTimedMouseEvent.getEvent().getEventType(); + nanoTimedMouseEvent.getEvent().getButton(); + + + return nanoTimedMouseEvent; + } + +} diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 7aa6a86f..fa89640d 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -2,7 +2,7 @@ import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; import com.recom.tacview.engine.input.command.IsInputCommand; -import com.recom.tacview.engine.input.command.MouseClickCommand; +import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -13,9 +13,9 @@ public class RECOMMapInputComponent extends InputComponent { @Override public void handleInputCommand(@NonNull IsInputCommand inputCommand) { - if (inputCommand instanceof MouseClickCommand) { - final MouseClickCommand mouseClickCommand = (MouseClickCommand) inputCommand; - log.info("Mouse click command received: {} is doubleClick: {}", mouseClickCommand.getMouseButton(), mouseClickCommand.isDoubleClick()); + if (inputCommand instanceof MouseButtonCommand) { + final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; + log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); } } } From 25ca4ec891d28ad25a28354c071ae429847ec633 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 20:07:45 +0100 Subject: [PATCH 06/23] update namings --- .../mouse/JavaFxMouseCommandMapper.java | 8 ++++---- .../mapper/mouse/fsm/InputAlphabet.java | 7 ++----- ...entFSM.java => IsMouseButtonEventFSM.java} | 3 +-- ...entFSM0.java => MouseButtonEventFSM0.java} | 8 ++++---- ...entFSM1.java => MouseButtonEventFSM1.java} | 14 ++++++------- ...entFSM1.puml => MouseButtonEventFSM1.puml} | 20 ++++++++++--------- 6 files changed, 29 insertions(+), 31 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/{IsMouseEventFSM.java => IsMouseButtonEventFSM.java} (82%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/{MouseEventFSM0.java => MouseButtonEventFSM0.java} (95%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/{MouseEventFSM1.java => MouseButtonEventFSM1.java} (95%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/{MouseEventFSM1.puml => MouseButtonEventFSM1.puml} (60%) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index 0ca16e7d..7590afe6 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -2,8 +2,8 @@ import com.recom.tacview.engine.input.NanoTimedEvent; import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; -import com.recom.tacview.engine.input.command.mapper.mouse.fsm.IsMouseEventFSM; -import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseEventFSM1; +import com.recom.tacview.engine.input.command.mapper.mouse.fsm.IsMouseButtonEventFSM; +import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseButtonEventFSM1; import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; import javafx.scene.input.InputEvent; import javafx.scene.input.MouseButton; @@ -21,9 +21,9 @@ public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoClose @NonNull private final LinkedList> unprocessedMouseEvents = new LinkedList<>(); @NonNull - private final IsMouseEventFSM primaryMouseButtonFSM = new MouseEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); + private final IsMouseButtonEventFSM primaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); @NonNull - private final IsMouseEventFSM secondaryMouseButtonFSM = new MouseEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); + private final IsMouseButtonEventFSM secondaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); public JavaFxMouseCommandMapper() { primaryMouseButtonFSM.start(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java index 9a7b5350..012e260d 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java @@ -1,15 +1,12 @@ package com.recom.tacview.engine.input.command.mapper.mouse.fsm; enum InputAlphabet { - IDLING, + IDLEING, CLICK_THRESHOLD_EXCEEDED, - DOUBLECLICK_THRESHOLD_EXCEEDED, - CLICK_COMMAND, - DOUBLE_CLICK_COMMAND, MOUSE_PRESSED, + MOUSE_PRESSED_TWICE, MOUSE_RELEASED, MOUSE_DRAG_STARTED, MOUSE_DRAGGING, UNHANDLED, - STOP } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java similarity index 82% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java index 279a24f2..275f33ba 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseEventFSM.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java @@ -2,13 +2,12 @@ import com.recom.tacview.engine.input.NanoTimedEvent; import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; -import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; import javafx.scene.input.MouseEvent; import lombok.NonNull; import java.util.LinkedList; -public interface IsMouseEventFSM { +public interface IsMouseButtonEventFSM { void iterate(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java similarity index 95% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java index c44a5145..f0a32a29 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM0.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java @@ -14,7 +14,7 @@ import java.util.LinkedList; @Slf4j -public class MouseEventFSM0 implements IsMouseEventFSM { +public class MouseButtonEventFSM0 implements IsMouseButtonEventFSM { @NonNull private final long doubleClickThresholdNanos; @@ -32,7 +32,7 @@ public class MouseEventFSM0 implements IsMouseEventFSM { private final LinkedList bufferedCommands = new LinkedList<>(); - public MouseEventFSM0(@NonNull final Duration doubleClickThreshold) { + public MouseButtonEventFSM0(@NonNull final Duration doubleClickThreshold) { this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); this.dragThresholdNanos = Duration.ofMillis(200).toNanos(); } @@ -69,7 +69,7 @@ private void engineRevolution(@Nullable final NanoTimedEvent nextEve } } case CLICK_CANDIDATE -> { - if (input == InputAlphabet.IDLING) { + if (input == InputAlphabet.IDLEING) { assert nextEvent == null; assert eventCandidateBuffer != null; if (clickThresholdExpired(eventCandidateBuffer)) { @@ -130,7 +130,7 @@ private boolean dragThresholdExpired(@NonNull final NanoTimedEvent e @NonNull private InputAlphabet determineInputAlphabet(@Nullable final NanoTimedEvent nextNanoTimedMouseEvent) { if (nextNanoTimedMouseEvent == null) { - return InputAlphabet.IDLING; + return InputAlphabet.IDLEING; } else { final EventType eventType = nextNanoTimedMouseEvent.getEvent().getEventType(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java similarity index 95% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index 64ddc115..31768c8e 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -16,7 +16,7 @@ import java.util.LinkedList; @Slf4j -public class MouseEventFSM1 implements IsMouseEventFSM { +public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @NonNull private final long doubleClickThresholdNanos; @@ -36,7 +36,7 @@ public class MouseEventFSM1 implements IsMouseEventFSM { private final LinkedList bufferedCommands = new LinkedList<>(); - public MouseEventFSM1( + public MouseButtonEventFSM1( @NonNull final Duration doubleClickThreshold, @NonNull final Duration dragThreshold, @NonNull final MouseButton responsibleForMouseButton @@ -72,7 +72,7 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv switch (currentMachineState) { case IDLE -> { switch (idleAlphabet(nextEvent)) { - case IDLING -> { + case IDLEING -> { // do nothing } case MOUSE_PRESSED -> { @@ -106,14 +106,14 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv clickCandidateBuffer = null; currentMachineState = FSMStates.MOUSE_DRAGGING; } - case IDLING -> { + case IDLEING -> { // do nothing } } } case MOUSE_DRAGGING -> { switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { - case IDLING -> { + case IDLEING -> { // do nothing } case MOUSE_DRAGGING -> { @@ -141,7 +141,7 @@ private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final N @NonNull private InputAlphabet idleAlphabet(@Nullable final NanoTimedEvent nextEvent) { if (nextEvent == null) { - return InputAlphabet.IDLING; + return InputAlphabet.IDLEING; } else if (nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_PRESSED; } else { @@ -161,7 +161,7 @@ private InputAlphabet clickCandidateAlphabet( } else if (nextEvent != null && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_PRESSED; } else { - return InputAlphabet.IDLING; + return InputAlphabet.IDLEING; } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml similarity index 60% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml index d3db4dc1..b657a5ef 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseEventFSM1.puml +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml @@ -1,18 +1,18 @@ @startuml header RECOM Tacviewer -title Mouse Event FSM v1.0 +title Mouse Button Event FSM v1.0 caption Each mouse button has its own state machine footer RECOM.one [*] --> IDLE :start -IDLE --> IDLE : IDLING +IDLE --> IDLE : IDLEING IDLE --> CLICK_CANDIDATE : MOUSE_PRESSED -CLICK_CANDIDATE --> IDLE : CLICK_THRESHOLD_EXCEEDED\n MOUSE_PRESS\n +CLICK_CANDIDATE --> IDLE : CLICK_THRESHOLD_EXCEEDED\n MOUSE_PRESSED_TWIECE\n CLICK_CANDIDATE --> MOUSE_DRAGGING : MOUSE_DRAG_STARTED -CLICK_CANDIDATE --> CLICK_CANDIDATE : IDLING +CLICK_CANDIDATE --> CLICK_CANDIDATE : IDLEING MOUSE_DRAGGING --> MOUSE_DRAGGING : MOUSE_DRAGGING MOUSE_DRAGGING --> IDLE : MOUSE_RELEASED @@ -24,13 +24,15 @@ MOUSE_DRAGGING --> [*] :stop legend left __**ALPHABET**__ | **Symbol** | **Description** | -| start | on class initialization | -| IDLING | new engine revolution without event | +| start | on start() | +| stop | on autoclosable close() | +| IDLEING | new engine revolution without event | | CLICK_THRESHOLD_EXCEEDED | new engine revolution without event | -| MOUSE_PRESSED | Mouse Press Event | -| MOUSE_RELEASED | Mouse Release Event | +| MOUSE_PRESSED | first mouse press event | +| MOUSE_PRESSED_TWICE | second mouse press event before "click threshold exceeded" | +| MOUSE_RELEASED | mouse button released | | MOUSE_DRAG_STARTED | when mouse is pushed and not released within mouse click threshold | -| MOUSE_DRAGGING | when mouse is pushed and moved | +| MOUSE_DRAGGING | when mouse button is pushed and moved | endlegend @enduml \ No newline at end of file From ef970b6e5faa58ed2a1b8b5bf73bdda95ce2b2c8 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 20:09:04 +0100 Subject: [PATCH 07/23] tidy up --- .../command/mapper/mouse/fsm/MouseButtonEventFSM1.puml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml index b657a5ef..2077c5b2 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml @@ -1,9 +1,9 @@ @startuml -header RECOM Tacviewer -title Mouse Button Event FSM v1.0 +header RECOM Tacviewer +title Mouse Button Event FSM v1.0 caption Each mouse button has its own state machine -footer RECOM.one +footer RECOM.one [*] --> IDLE :start From a1d8c48055f4bc308a6aebdef14441ef6059fa42 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 22:26:27 +0100 Subject: [PATCH 08/23] optimize MouseButtonMachine --- .../com/recom/tacview/engine/TacViewer.java | 2 +- .../tacview/engine/input/InputManager.java | 23 +++---- .../engine/input/command/IsInputCommand.java | 3 + .../command/mapper/IsInputCommandMapper.java | 3 +- .../mouse/JavaFxMouseCommandMapper.java | 66 +++++++++++-------- .../mouse/fsm/IsMouseButtonEventFSM.java | 11 +++- .../mouse/fsm/MouseButtonEventFSM0.java | 22 ++++++- .../mouse/fsm/MouseButtonEventFSM1.java | 23 ++++++- .../input/command/mouse/IsMouseCommand.java | 5 ++ .../command/mouse/MouseButtonCommand.java | 7 ++ .../input/command/mouse/MouseDragCommand.java | 8 +++ 11 files changed, 124 insertions(+), 49 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 41d669e3..9537f084 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -112,7 +112,7 @@ private void engineLoop( // HANDLE INPUT final long inputHandlingStart = System.nanoTime(); inputManager.mapInputEventsToCommands(); - engineModule.handleInputCommands(inputManager.getCreatedInputCommands()); + engineModule.handleInputCommands(inputManager.popInputCommands()); inputManager.clearInputQueues(); profiler.inputHandlingNanoTime = System.nanoTime() - inputHandlingStart; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java index 502374b5..37b83e62 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java @@ -21,37 +21,34 @@ public class InputManager { private final LinkedList> inputEventQueue = new LinkedList<>(); @NonNull - private final LinkedList registeredInputCommands = new LinkedList<>(); + private final LinkedList registeredCommandsMappers = new LinkedList<>(); - @Getter @NonNull private final LinkedList createdInputCommands = new LinkedList<>(); public void mapInputEventsToCommands() { - for (final IsInputCommandMapper mapper : registeredInputCommands) { + for (final IsInputCommandMapper mapper : registeredCommandsMappers) { if (mapper.mapEvents(inputEventQueue.stream())) { - createdInputCommands.addAll(mapper.getCreatedCommands()); + createdInputCommands.addAll(mapper.popCreatedCommands()); } } } public void clearInputQueues() { inputEventQueue.clear(); - createdInputCommands.clear(); } - public void registerCommandMapper(@NonNull final IsInputCommandMapper inputCommand) { - registeredInputCommands.add(inputCommand); - } + @NonNull + public LinkedList popInputCommands() { + final LinkedList createdInputCommandsCopy = new LinkedList<>(createdInputCommands); + createdInputCommands.clear(); - public void unregisterInputCommand(@NonNull final IsInputCommandMapper inputCommand) { - registeredInputCommands.remove(inputCommand); + return createdInputCommandsCopy; } - public void clearRegisteredInputCommands() { - registeredInputCommands.clear(); + public void registerCommandMapper(@NonNull final IsInputCommandMapper inputCommandMapper) { + registeredCommandsMappers.add(inputCommandMapper); } - } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java index 6cd2e1da..c4940730 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java @@ -1,4 +1,7 @@ package com.recom.tacview.engine.input.command; public interface IsInputCommand { + + long getNanos(); + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java index dbd4bd44..77fe56ab 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java @@ -5,7 +5,6 @@ import javafx.scene.input.InputEvent; import lombok.NonNull; -import java.util.Collection; import java.util.LinkedList; import java.util.stream.Stream; @@ -14,6 +13,6 @@ public interface IsInputCommandMapper { boolean mapEvents(@NonNull final Stream> inputEventStream); @NonNull - LinkedList getCreatedCommands(); + LinkedList popCreatedCommands(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index 7590afe6..eb6fa1a2 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -1,10 +1,11 @@ package com.recom.tacview.engine.input.command.mapper.mouse; import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.IsInputCommand; import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; import com.recom.tacview.engine.input.command.mapper.mouse.fsm.IsMouseButtonEventFSM; import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseButtonEventFSM1; -import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; import javafx.scene.input.InputEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; @@ -12,7 +13,10 @@ import lombok.extern.slf4j.Slf4j; import java.time.Duration; +import java.util.Comparator; import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; import java.util.stream.Stream; @Slf4j @@ -20,14 +24,27 @@ public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoClose @NonNull private final LinkedList> unprocessedMouseEvents = new LinkedList<>(); + // @NonNull +// private final IsMouseButtonEventFSM primaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); +// @NonNull +// private final IsMouseButtonEventFSM secondaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); +// @NonNull +// private final IsMouseButtonEventFSM middleMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.MIDDLE); @NonNull - private final IsMouseButtonEventFSM primaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); - @NonNull - private final IsMouseButtonEventFSM secondaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); + private final List mouseButtonEventFSMs; public JavaFxMouseCommandMapper() { - primaryMouseButtonFSM.start(); - secondaryMouseButtonFSM.start(); + mouseButtonEventFSMs = List.of( + new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY), + new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY), + new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.MIDDLE) + ); + + startMachines(); + } + + private void startMachines() { + mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::start); } @@ -37,48 +54,45 @@ public boolean mapEvents(@NonNull final Stream event.getEvent() instanceof MouseEvent) .map(event -> (NanoTimedEvent) event) - .filter(this::isObservedMouseEvent) + .filter(this::isObservedMouseButtonEvent) .forEach(unprocessedMouseEvents::add); - return runMouseClickFSM(); + return runMouseButtonFSM(); } - private boolean isObservedMouseEvent( - @NonNull final NanoTimedEvent nanoTimedEvent - ) { + private boolean isObservedMouseButtonEvent(@NonNull final NanoTimedEvent nanoTimedEvent) { return nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED || nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED || nanoTimedEvent.getEvent().getEventType() == MouseEvent.MOUSE_DRAGGED; } - private boolean runMouseClickFSM() { + private boolean runMouseButtonFSM() { while (!unprocessedMouseEvents.isEmpty()) { final NanoTimedEvent polledMouseEvent = unprocessedMouseEvents.poll(); - primaryMouseButtonFSM.iterate(polledMouseEvent); - secondaryMouseButtonFSM.iterate(polledMouseEvent); + mouseButtonEventFSMs.forEach(fsm -> fsm.iterate(polledMouseEvent)); } - primaryMouseButtonFSM.iterate(); - secondaryMouseButtonFSM.iterate(); + mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::iterate); - return !primaryMouseButtonFSM.getBufferedCommands().isEmpty() || !secondaryMouseButtonFSM.getBufferedCommands().isEmpty(); + return mouseButtonEventFSMs.stream() + .map(IsMouseButtonEventFSM::hasBufferedCommands) + .reduce(false, (a, b) -> a || b); } @NonNull @Override - @SuppressWarnings("unchecked") - public LinkedList getCreatedCommands() { - final LinkedList createdCommands = (LinkedList) primaryMouseButtonFSM.getBufferedCommands().clone(); - createdCommands.addAll((LinkedList) secondaryMouseButtonFSM.getBufferedCommands().clone()); - primaryMouseButtonFSM.getBufferedCommands().clear(); - secondaryMouseButtonFSM.getBufferedCommands().clear(); + public LinkedList popCreatedCommands() { + final LinkedList collectCommands = mouseButtonEventFSMs.stream() + .flatMap(IsMouseButtonEventFSM::popBufferedCommands) + .sorted(Comparator.comparing(IsInputCommand::getNanos, Comparator.reverseOrder())) + .collect(Collectors.toCollection(LinkedList::new)); + - return createdCommands; + return collectCommands; } @Override public void close() { - primaryMouseButtonFSM.stop(); - secondaryMouseButtonFSM.stop(); + mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::stop); } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java index 275f33ba..01ed2094 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java @@ -6,6 +6,7 @@ import lombok.NonNull; import java.util.LinkedList; +import java.util.stream.Stream; public interface IsMouseButtonEventFSM { @@ -13,12 +14,16 @@ public interface IsMouseButtonEventFSM { void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent); - @NonNull - LinkedList getBufferedCommands(); - void start(); void stop(); + boolean hasBufferedCommands(); + +// void clearBufferedCommands(); + + @NonNull + Stream popBufferedCommands(); + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java index f0a32a29..b5595186 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java @@ -5,13 +5,13 @@ import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; import javafx.event.EventType; import javafx.scene.input.MouseEvent; -import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; import java.time.Duration; import java.util.LinkedList; +import java.util.stream.Stream; @Slf4j public class MouseButtonEventFSM0 implements IsMouseButtonEventFSM { @@ -27,7 +27,6 @@ public class MouseButtonEventFSM0 implements IsMouseButtonEventFSM { @Nullable private NanoTimedEvent eventCandidateBuffer; - @Getter @NonNull private final LinkedList bufferedCommands = new LinkedList<>(); @@ -47,6 +46,25 @@ public void stop() { currentMachineState = FSMStates.STOPPED; } + @Override + public boolean hasBufferedCommands() { + return !bufferedCommands.isEmpty(); + } + + @NonNull + @Override + public Stream popBufferedCommands() { + final LinkedList bufferedCommandsCopy = new LinkedList<>(bufferedCommands); + bufferedCommands.clear(); + + return bufferedCommandsCopy.stream(); + } + +// @Override +// public void clearBufferedCommands() { +// bufferedCommands.clear(); +// } + public void iterate() { engineRevolution(null); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index 31768c8e..d5e6b4c1 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -7,13 +7,13 @@ import javafx.scene.input.MouseButton; import javafx.scene.input.MouseDragEvent; import javafx.scene.input.MouseEvent; -import lombok.Getter; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; import java.time.Duration; import java.util.LinkedList; +import java.util.stream.Stream; @Slf4j public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @@ -31,7 +31,6 @@ public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @Nullable private NanoTimedEvent clickCandidateBuffer; - @Getter @NonNull private final LinkedList bufferedCommands = new LinkedList<>(); @@ -64,6 +63,26 @@ public void stop() { currentMachineState = FSMStates.STOPPED; } + @Override + public boolean hasBufferedCommands() { + return !bufferedCommands.isEmpty(); + } + + + @NonNull + @Override + public Stream popBufferedCommands() { + final LinkedList bufferedCommandsCopy = new LinkedList<>(bufferedCommands); + bufferedCommands.clear(); + + return bufferedCommandsCopy.stream(); + } + +// @Override +// public void clearBufferedCommands() { +// bufferedCommands.clear(); +// } + private void machineRevolution(@Nullable final NanoTimedEvent nextEvent) { if (fsmIsNotResponsibleForMouseButtonRelatedEvents(nextEvent)) { return; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java index a6af3ee3..f0f33596 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java @@ -3,4 +3,9 @@ import com.recom.tacview.engine.input.command.IsInputCommand; public interface IsMouseCommand extends IsInputCommand { + + double getPositionX(); + + double getPositionY(); + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java index 81fc35bb..a1d6e568 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java @@ -49,10 +49,12 @@ private MouseButton determineMouseButton(@NonNull final MouseEvent event) { }; } + @Override public double getPositionX() { return nanoTimedMouseEvent.getEvent().getX(); } + @Override public double getPositionY() { return nanoTimedMouseEvent.getEvent().getY(); } @@ -66,4 +68,9 @@ public NanoTimedEvent getNanoTimedMouseEvent() { return nanoTimedMouseEvent; } + @Override + public long getNanos() { + return nanoTimedMouseEvent.getNanos(); + } + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java index 86af1c22..3938afdd 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java @@ -8,6 +8,7 @@ public class MouseDragCommand implements IsMouseCommand { + @Getter @NonNull private final NanoTimedEvent nanoTimedMouseEvent; @Getter @@ -58,10 +59,12 @@ public boolean isDragging() { return !dragStart && !dragStop; } + @Override public double getPositionX() { return nanoTimedMouseEvent.getEvent().getX(); } + @Override public double getPositionY() { return nanoTimedMouseEvent.getEvent().getY(); } @@ -75,4 +78,9 @@ public NanoTimedEvent getNanoTimedMouseEvent() { return nanoTimedMouseEvent; } + @Override + public long getNanos() { + return nanoTimedMouseEvent.getNanos(); + } + } From c2cccb115996fe3550deedd5ec315f8c12c285f3 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 22:30:30 +0100 Subject: [PATCH 09/23] optimize MouseButtonMachine --- .../mapper/mouse/JavaFxMouseCommandMapper.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index eb6fa1a2..a5eea309 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -24,12 +24,6 @@ public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoClose @NonNull private final LinkedList> unprocessedMouseEvents = new LinkedList<>(); - // @NonNull -// private final IsMouseButtonEventFSM primaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY); -// @NonNull -// private final IsMouseButtonEventFSM secondaryMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY); -// @NonNull -// private final IsMouseButtonEventFSM middleMouseButtonFSM = new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.MIDDLE); @NonNull private final List mouseButtonEventFSMs; @@ -81,13 +75,13 @@ private boolean runMouseButtonFSM() { @NonNull @Override public LinkedList popCreatedCommands() { - final LinkedList collectCommands = mouseButtonEventFSMs.stream() + final LinkedList collectedCommands = mouseButtonEventFSMs.stream() .flatMap(IsMouseButtonEventFSM::popBufferedCommands) - .sorted(Comparator.comparing(IsInputCommand::getNanos, Comparator.reverseOrder())) + .sorted(Comparator.comparing(IsInputCommand::getNanos)) .collect(Collectors.toCollection(LinkedList::new)); - return collectCommands; + return collectedCommands; } @Override From 45ab14c4b14bcbe9f5b35de13d4f06c89d43b744 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 23:01:13 +0100 Subject: [PATCH 10/23] tidy up --- .../input/command/mapper/mouse/JavaFxMouseCommandMapper.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index a5eea309..9445f226 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -75,13 +75,10 @@ private boolean runMouseButtonFSM() { @NonNull @Override public LinkedList popCreatedCommands() { - final LinkedList collectedCommands = mouseButtonEventFSMs.stream() + return mouseButtonEventFSMs.stream() .flatMap(IsMouseButtonEventFSM::popBufferedCommands) .sorted(Comparator.comparing(IsInputCommand::getNanos)) .collect(Collectors.toCollection(LinkedList::new)); - - - return collectedCommands; } @Override From fab99ef872a19f89685e8770fd7838209b5b344b Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 23:03:12 +0100 Subject: [PATCH 11/23] optimize --- .../mapper/mouse/JavaFxMouseCommandMapper.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index 9445f226..743f3591 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -61,11 +61,14 @@ private boolean isObservedMouseButtonEvent(@NonNull final NanoTimedEvent polledMouseEvent = unprocessedMouseEvents.poll(); - mouseButtonEventFSMs.forEach(fsm -> fsm.iterate(polledMouseEvent)); + if (unprocessedMouseEvents.isEmpty()) { + mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::iterate); + } else { + while (!unprocessedMouseEvents.isEmpty()) { + final NanoTimedEvent polledMouseEvent = unprocessedMouseEvents.poll(); + mouseButtonEventFSMs.forEach(fsm -> fsm.iterate(polledMouseEvent)); + } } - mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::iterate); return mouseButtonEventFSMs.stream() .map(IsMouseButtonEventFSM::hasBufferedCommands) From 1c792ba01487d711c92e6ee77cbb22841bbb2be0 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 23:04:21 +0100 Subject: [PATCH 12/23] tidy up --- .../input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java | 5 ----- .../input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java | 5 ----- 2 files changed, 10 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java index b5595186..7f205a41 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java @@ -60,11 +60,6 @@ public Stream popBufferedCommands() { return bufferedCommandsCopy.stream(); } -// @Override -// public void clearBufferedCommands() { -// bufferedCommands.clear(); -// } - public void iterate() { engineRevolution(null); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index d5e6b4c1..2c2a6561 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -78,11 +78,6 @@ public Stream popBufferedCommands() { return bufferedCommandsCopy.stream(); } -// @Override -// public void clearBufferedCommands() { -// bufferedCommands.clear(); -// } - private void machineRevolution(@Nullable final NanoTimedEvent nextEvent) { if (fsmIsNotResponsibleForMouseButtonRelatedEvents(nextEvent)) { return; From e7aee5484b876ad51bfb1a630bd97e85cd82882c Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Mon, 22 Jan 2024 23:47:14 +0100 Subject: [PATCH 13/23] wip --- .../mouse/JavaFxMouseCommandMapper.java | 6 +-- .../mapper/mouse/fsm/InputAlphabet.java | 4 +- .../mouse/fsm/MouseButtonEventFSM1.java | 50 +++++++++++++++---- .../mouse/fsm/MouseButtonEventFSM1.puml | 10 ++-- .../command/mouse/MouseButtonCommand.java | 4 +- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java index 743f3591..f335eeed 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java @@ -29,9 +29,9 @@ public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoClose public JavaFxMouseCommandMapper() { mouseButtonEventFSMs = List.of( - new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.PRIMARY), - new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.SECONDARY), - new MouseButtonEventFSM1(Duration.ofMillis(200), Duration.ofMillis(200), MouseButton.MIDDLE) + new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.PRIMARY), + new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.SECONDARY), + new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.MIDDLE) ); startMachines(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java index 012e260d..4dfea219 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java @@ -2,9 +2,9 @@ enum InputAlphabet { IDLEING, - CLICK_THRESHOLD_EXCEEDED, + CLICK, MOUSE_PRESSED, - MOUSE_PRESSED_TWICE, + DOUBLECLICK, MOUSE_RELEASED, MOUSE_DRAG_STARTED, MOUSE_DRAGGING, diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index 2c2a6561..b9b470e3 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -15,13 +15,17 @@ import java.util.LinkedList; import java.util.stream.Stream; +import static com.recom.tacview.engine.input.command.mapper.mouse.fsm.InputAlphabet.IDLEING; + @Slf4j public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @NonNull private final long doubleClickThresholdNanos; + @NonNull private final long dragThresholdNanos; + @NonNull private final MouseButton responsibleForMouseButton; @@ -94,31 +98,42 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv clickCandidateBuffer = nextEvent; currentMachineState = FSMStates.CLICK_CANDIDATE; + log.info("MOUSE_PRESSED"); } } } case CLICK_CANDIDATE -> { assert clickCandidateBuffer != null; switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { - case CLICK_THRESHOLD_EXCEEDED -> { + case MOUSE_RELEASED -> { + assert nextEvent != null; + + clickCandidateBuffer = nextEvent; + log.info("MOUSE_RELEASED"); + } + case CLICK -> { bufferedCommands.add(MouseButtonCommand.singleClickCommand(clickCandidateBuffer)); clickCandidateBuffer = null; currentMachineState = FSMStates.IDLE; + log.info("CLICK"); } - case MOUSE_PRESSED -> { + case DOUBLECLICK -> { assert nextEvent != null; bufferedCommands.add(MouseButtonCommand.doubleClickCommand(nextEvent)); clickCandidateBuffer = null; currentMachineState = FSMStates.IDLE; + log.info("DOUBLECLICK"); } case MOUSE_DRAG_STARTED -> { + assert nextEvent == null; assert clickCandidateBuffer != null; assert clickCandidateBuffer.getEvent() instanceof MouseDragEvent; bufferedCommands.add(MouseDragCommand.dragStartCommand(clickCandidateBuffer.cast())); clickCandidateBuffer = null; currentMachineState = FSMStates.MOUSE_DRAGGING; + log.info("MOUSE_DRAG_STARTED"); } case IDLEING -> { // do nothing @@ -126,7 +141,7 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv } } case MOUSE_DRAGGING -> { - switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { + switch (mouseDraggingAlphabet(nextEvent, clickCandidateBuffer)) { case IDLEING -> { // do nothing } @@ -148,6 +163,15 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv } } + @NonNull + private InputAlphabet mouseDraggingAlphabet( + @Nullable final NanoTimedEvent nextEvent, + @Nullable final NanoTimedEvent clickCandidateBuffer + ) { + + return InputAlphabet.UNHANDLED; + } + private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final NanoTimedEvent nextEvent) { return nextEvent != null && (nextEvent.getEvent().getButton() != responsibleForMouseButton); } @@ -155,7 +179,7 @@ private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final N @NonNull private InputAlphabet idleAlphabet(@Nullable final NanoTimedEvent nextEvent) { if (nextEvent == null) { - return InputAlphabet.IDLEING; + return IDLEING; } else if (nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_PRESSED; } else { @@ -169,18 +193,24 @@ private InputAlphabet clickCandidateAlphabet( @NonNull NanoTimedEvent clickCandidateBuffer ) { if (nextEvent == null && clickThresholdExceeded(clickCandidateBuffer)) { - return InputAlphabet.CLICK_THRESHOLD_EXCEEDED; - } else if (nextEvent == null && dragThresholdExceeded(clickCandidateBuffer) && clickCandidateBuffer.getEvent() instanceof MouseDragEvent) { + return InputAlphabet.CLICK; + } else if (nextEvent == null && dragThresholdExceeded(clickCandidateBuffer) && clickCandidateBuffer.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_DRAG_STARTED; } else if (nextEvent != null && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { - return InputAlphabet.MOUSE_PRESSED; + return InputAlphabet.DOUBLECLICK; + } else if (nextEvent != null && nextEvent.getEvent() instanceof MouseEvent && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED) { + return InputAlphabet.MOUSE_RELEASED; } else { - return InputAlphabet.IDLEING; + return IDLEING; } } - private boolean clickThresholdExceeded(@NonNull final NanoTimedEvent event) { - return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; + private boolean clickThresholdExceeded(@NonNull final NanoTimedEvent clickCandidateBuffer) { + if (clickCandidateBuffer.getEvent().getEventType().equals(MouseEvent.MOUSE_RELEASED)) { + return (System.nanoTime() - clickCandidateBuffer.getNanos()) > doubleClickThresholdNanos; + } else { + return false; + } } private boolean dragThresholdExceeded(@NonNull final NanoTimedEvent event) { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml index 2077c5b2..e4087c26 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml @@ -10,9 +10,9 @@ footer RECOM.one IDLE --> IDLE : IDLEING IDLE --> CLICK_CANDIDATE : MOUSE_PRESSED -CLICK_CANDIDATE --> IDLE : CLICK_THRESHOLD_EXCEEDED\n MOUSE_PRESSED_TWIECE\n +CLICK_CANDIDATE --> IDLE : CLICK\n DOUBLECLICK\n CLICK_CANDIDATE --> MOUSE_DRAGGING : MOUSE_DRAG_STARTED -CLICK_CANDIDATE --> CLICK_CANDIDATE : IDLEING +CLICK_CANDIDATE --> CLICK_CANDIDATE : IDLEING\n MOUSE_RELEASED MOUSE_DRAGGING --> MOUSE_DRAGGING : MOUSE_DRAGGING MOUSE_DRAGGING --> IDLE : MOUSE_RELEASED @@ -27,9 +27,9 @@ __**ALPHABET**__ | start | on start() | | stop | on autoclosable close() | | IDLEING | new engine revolution without event | -| CLICK_THRESHOLD_EXCEEDED | new engine revolution without event | -| MOUSE_PRESSED | first mouse press event | -| MOUSE_PRESSED_TWICE | second mouse press event before "click threshold exceeded" | +| CLICK | "click threshold exceeded" after MOUSE_RELEASED | +| MOUSE_PRESSED | mouse button pressed event | +| DOUBLECLICK | second MOUSE_PRESSED before "click threshold exceeded" | | MOUSE_RELEASED | mouse button released | | MOUSE_DRAG_STARTED | when mouse is pushed and not released within mouse click threshold | | MOUSE_DRAGGING | when mouse button is pushed and moved | diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java index a1d6e568..ee9a9bcd 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java @@ -24,9 +24,7 @@ public static MouseButtonCommand singleClickCommand( } @NonNull - public static MouseButtonCommand doubleClickCommand( - @NonNull final NanoTimedEvent nanoTimedMouseEvent - ) { + public static MouseButtonCommand doubleClickCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { return new MouseButtonCommand(nanoTimedMouseEvent, true); } From bfcf68b98d235afa50fa18de0a6fa0e7ab4ff0df Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 20:38:06 +0100 Subject: [PATCH 14/23] working state --- .../mouse/fsm/MouseButtonEventFSM1.java | 83 +++++++++++-------- .../input/command/mouse/MouseDragCommand.java | 18 ++-- .../component/RECOMMapInputComponent.java | 2 + 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index b9b470e3..d0774d3b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -5,7 +5,6 @@ import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; import com.recom.tacview.engine.input.command.mouse.MouseDragCommand; import javafx.scene.input.MouseButton; -import javafx.scene.input.MouseDragEvent; import javafx.scene.input.MouseEvent; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -16,6 +15,7 @@ import java.util.stream.Stream; import static com.recom.tacview.engine.input.command.mapper.mouse.fsm.InputAlphabet.IDLEING; +import static com.recom.tacview.engine.input.command.mapper.mouse.fsm.InputAlphabet.MOUSE_DRAGGING; @Slf4j public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @@ -33,7 +33,9 @@ public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { private FSMStates currentMachineState = FSMStates.NEW; @Nullable - private NanoTimedEvent clickCandidateBuffer; + private NanoTimedEvent lastMouseEventBuffer; + @Nullable + private NanoTimedEvent mouseDragOriginEventBuffer; @NonNull private final LinkedList bufferedCommands = new LinkedList<>(); @@ -96,44 +98,39 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv case MOUSE_PRESSED -> { assert nextEvent != null; - clickCandidateBuffer = nextEvent; + lastMouseEventBuffer = nextEvent; currentMachineState = FSMStates.CLICK_CANDIDATE; - log.info("MOUSE_PRESSED"); } } } case CLICK_CANDIDATE -> { - assert clickCandidateBuffer != null; - switch (clickCandidateAlphabet(nextEvent, clickCandidateBuffer)) { + assert lastMouseEventBuffer != null; + switch (clickCandidateAlphabet(nextEvent, lastMouseEventBuffer)) { case MOUSE_RELEASED -> { assert nextEvent != null; - clickCandidateBuffer = nextEvent; - log.info("MOUSE_RELEASED"); + lastMouseEventBuffer = nextEvent; } case CLICK -> { - bufferedCommands.add(MouseButtonCommand.singleClickCommand(clickCandidateBuffer)); - clickCandidateBuffer = null; + bufferedCommands.add(MouseButtonCommand.singleClickCommand(lastMouseEventBuffer)); + lastMouseEventBuffer = null; currentMachineState = FSMStates.IDLE; - log.info("CLICK"); } case DOUBLECLICK -> { assert nextEvent != null; bufferedCommands.add(MouseButtonCommand.doubleClickCommand(nextEvent)); - clickCandidateBuffer = null; + lastMouseEventBuffer = null; currentMachineState = FSMStates.IDLE; - log.info("DOUBLECLICK"); } case MOUSE_DRAG_STARTED -> { assert nextEvent == null; - assert clickCandidateBuffer != null; - assert clickCandidateBuffer.getEvent() instanceof MouseDragEvent; + assert lastMouseEventBuffer != null; + assert lastMouseEventBuffer.getEvent().getEventType().equals(MouseEvent.MOUSE_PRESSED); - bufferedCommands.add(MouseDragCommand.dragStartCommand(clickCandidateBuffer.cast())); - clickCandidateBuffer = null; + mouseDragOriginEventBuffer = lastMouseEventBuffer; + bufferedCommands.add(MouseDragCommand.dragStartCommand(mouseDragOriginEventBuffer.cast())); currentMachineState = FSMStates.MOUSE_DRAGGING; - log.info("MOUSE_DRAG_STARTED"); } case IDLEING -> { // do nothing @@ -141,18 +138,32 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv } } case MOUSE_DRAGGING -> { - switch (mouseDraggingAlphabet(nextEvent, clickCandidateBuffer)) { + switch (mouseDraggingAlphabet(nextEvent)) { case IDLEING -> { - // do nothing + assert nextEvent == null; + assert lastMouseEventBuffer != null; + assert mouseDragOriginEventBuffer != null; + + // emit last known mouse drag command + bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer.cast())); } case MOUSE_DRAGGING -> { + assert nextEvent != null; + assert lastMouseEventBuffer != null; + assert mouseDragOriginEventBuffer != null; + lastMouseEventBuffer = nextEvent; + bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer.cast())); } case MOUSE_RELEASED -> { - assert clickCandidateBuffer.getEvent() instanceof MouseDragEvent; + assert nextEvent != null; + assert nextEvent.getEvent().getEventType().equals(MouseEvent.MOUSE_RELEASED); + assert lastMouseEventBuffer != null; + assert mouseDragOriginEventBuffer != null; - bufferedCommands.add(MouseDragCommand.dragStopCommand(clickCandidateBuffer.cast())); - clickCandidateBuffer = null; + bufferedCommands.add(MouseDragCommand.dragStopCommand(nextEvent.cast())); + lastMouseEventBuffer = null; + mouseDragOriginEventBuffer = null; currentMachineState = FSMStates.IDLE; } } @@ -163,15 +174,6 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv } } - @NonNull - private InputAlphabet mouseDraggingAlphabet( - @Nullable final NanoTimedEvent nextEvent, - @Nullable final NanoTimedEvent clickCandidateBuffer - ) { - - return InputAlphabet.UNHANDLED; - } - private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final NanoTimedEvent nextEvent) { return nextEvent != null && (nextEvent.getEvent().getButton() != responsibleForMouseButton); } @@ -183,14 +185,14 @@ private InputAlphabet idleAlphabet(@Nullable final NanoTimedEvent ne } else if (nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_PRESSED; } else { - return InputAlphabet.UNHANDLED; + return IDLEING; } } @NonNull private InputAlphabet clickCandidateAlphabet( @Nullable final NanoTimedEvent nextEvent, - @NonNull NanoTimedEvent clickCandidateBuffer + @NonNull final NanoTimedEvent clickCandidateBuffer ) { if (nextEvent == null && clickThresholdExceeded(clickCandidateBuffer)) { return InputAlphabet.CLICK; @@ -205,6 +207,19 @@ private InputAlphabet clickCandidateAlphabet( } } + @NonNull + private InputAlphabet mouseDraggingAlphabet(@Nullable final NanoTimedEvent nextEvent) { + if (nextEvent == null) { + return IDLEING; + } else if (nextEvent != null && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED) { + return InputAlphabet.MOUSE_RELEASED; + } else if (nextEvent != null && nextEvent.getEvent() instanceof MouseEvent && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_DRAGGED) { + return MOUSE_DRAGGING; + } else { + return IDLEING; + } + } + private boolean clickThresholdExceeded(@NonNull final NanoTimedEvent clickCandidateBuffer) { if (clickCandidateBuffer.getEvent().getEventType().equals(MouseEvent.MOUSE_RELEASED)) { return (System.nanoTime() - clickCandidateBuffer.getNanos()) > doubleClickThresholdNanos; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java index 3938afdd..b9b7b4a7 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java @@ -1,7 +1,6 @@ package com.recom.tacview.engine.input.command.mouse; import com.recom.tacview.engine.input.NanoTimedEvent; -import javafx.scene.input.MouseDragEvent; import javafx.scene.input.MouseEvent; import lombok.Getter; import lombok.NonNull; @@ -10,7 +9,7 @@ public class MouseDragCommand implements IsMouseCommand { @Getter @NonNull - private final NanoTimedEvent nanoTimedMouseEvent; + private final NanoTimedEvent nanoTimedMouseEvent; @Getter private final boolean dragStart; private final boolean dragStop; @@ -18,24 +17,29 @@ public class MouseDragCommand implements IsMouseCommand { @NonNull private final MouseButton mouseButton; + // send event with current x,y (/) + // radiant 0 + // distance from source to current position 0 + // vector from source to current position 0 0 + @NonNull - public static MouseDragCommand dragStartCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + public static MouseDragCommand dragStartCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { return new MouseDragCommand(nanoTimedMouseEvent, true, false); } @NonNull - public static MouseDragCommand dragStopCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + public static MouseDragCommand dragStopCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { return new MouseDragCommand(nanoTimedMouseEvent, false, true); } @NonNull - public static MouseDragCommand dragginCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { + public static MouseDragCommand dragginCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent) { return new MouseDragCommand(nanoTimedMouseEvent, false, false); } public MouseDragCommand( - @NonNull final NanoTimedEvent nanoTimedMouseEvent, + @NonNull final NanoTimedEvent nanoTimedMouseEvent, final boolean startMouseDrag, final boolean stopMouseDrag ) { @@ -70,7 +74,7 @@ public double getPositionY() { } @NonNull - public NanoTimedEvent getNanoTimedMouseEvent() { + public NanoTimedEvent getNanoTimedMouseEvent() { nanoTimedMouseEvent.getEvent().getEventType(); nanoTimedMouseEvent.getEvent().getButton(); diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index fa89640d..067484fd 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -16,6 +16,8 @@ public void handleInputCommand(@NonNull IsInputCommand inputCommand) { if (inputCommand instanceof MouseButtonCommand) { final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); + } else { + log.info("Input command received: {}", inputCommand); } } } From 186ccb46a679503ef19c4b5a85b52cc45b1537c2 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 21:13:50 +0100 Subject: [PATCH 15/23] working state --- .../tacview/engine/input/command/IsInputCommand.java | 9 ++++++++- .../mapper/mouse/fsm/MouseButtonEventFSM1.java | 10 ++++++---- .../engine/input/command/mouse/IsMouseCommand.java | 3 ++- .../input/command/mouse/MouseButtonCommand.java | 4 ++-- .../engine/input/command/mouse/MouseDragCommand.java | 4 ++-- .../entity/component/RECOMMapInputComponent.java | 11 ++++++++++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java index c4940730..5c893dde 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java @@ -1,7 +1,14 @@ package com.recom.tacview.engine.input.command; -public interface IsInputCommand { +import com.recom.tacview.engine.input.NanoTimedEvent; +import javafx.scene.input.InputEvent; +import lombok.NonNull; + +public interface IsInputCommand { long getNanos(); + @NonNull + NanoTimedEvent getNanoTimedEvent(); + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java index d0774d3b..262dcabd 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java @@ -129,7 +129,7 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv assert lastMouseEventBuffer.getEvent().getEventType().equals(MouseEvent.MOUSE_PRESSED); mouseDragOriginEventBuffer = lastMouseEventBuffer; - bufferedCommands.add(MouseDragCommand.dragStartCommand(mouseDragOriginEventBuffer.cast())); + bufferedCommands.add(MouseDragCommand.dragStartCommand(mouseDragOriginEventBuffer)); currentMachineState = FSMStates.MOUSE_DRAGGING; } case IDLEING -> { @@ -145,15 +145,17 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv assert mouseDragOriginEventBuffer != null; // emit last known mouse drag command - bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer.cast())); + bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer)); } case MOUSE_DRAGGING -> { assert nextEvent != null; assert lastMouseEventBuffer != null; + assert lastMouseEventBuffer.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED || lastMouseEventBuffer.getEvent().getEventType() == MouseEvent.MOUSE_DRAGGED; assert mouseDragOriginEventBuffer != null; + assert mouseDragOriginEventBuffer.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED; lastMouseEventBuffer = nextEvent; - bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer.cast())); + bufferedCommands.add(MouseDragCommand.dragginCommand(lastMouseEventBuffer)); } case MOUSE_RELEASED -> { assert nextEvent != null; @@ -161,7 +163,7 @@ private void machineRevolution(@Nullable final NanoTimedEvent nextEv assert lastMouseEventBuffer != null; assert mouseDragOriginEventBuffer != null; - bufferedCommands.add(MouseDragCommand.dragStopCommand(nextEvent.cast())); + bufferedCommands.add(MouseDragCommand.dragStopCommand(nextEvent)); lastMouseEventBuffer = null; mouseDragOriginEventBuffer = null; currentMachineState = FSMStates.IDLE; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java index f0f33596..65e21658 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java @@ -1,8 +1,9 @@ package com.recom.tacview.engine.input.command.mouse; import com.recom.tacview.engine.input.command.IsInputCommand; +import javafx.scene.input.MouseEvent; -public interface IsMouseCommand extends IsInputCommand { +public interface IsMouseCommand extends IsInputCommand { double getPositionX(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java index ee9a9bcd..d96b802a 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NonNull; -public class MouseButtonCommand implements IsMouseCommand { +public class MouseButtonCommand implements IsMouseCommand { @NonNull private final NanoTimedEvent nanoTimedMouseEvent; @@ -58,7 +58,7 @@ public double getPositionY() { } @NonNull - public NanoTimedEvent getNanoTimedMouseEvent() { + public NanoTimedEvent getNanoTimedEvent() { nanoTimedMouseEvent.getEvent().getEventType(); nanoTimedMouseEvent.getEvent().getButton(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java index b9b7b4a7..92fae96a 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NonNull; -public class MouseDragCommand implements IsMouseCommand { +public class MouseDragCommand implements IsMouseCommand { @Getter @NonNull @@ -74,7 +74,7 @@ public double getPositionY() { } @NonNull - public NanoTimedEvent getNanoTimedMouseEvent() { + public NanoTimedEvent getNanoTimedEvent() { nanoTimedMouseEvent.getEvent().getEventType(); nanoTimedMouseEvent.getEvent().getButton(); diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 067484fd..10ef9ce2 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -3,6 +3,8 @@ import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; import com.recom.tacview.engine.input.command.IsInputCommand; import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import javafx.event.Event; +import javafx.scene.input.MouseEvent; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -17,7 +19,14 @@ public void handleInputCommand(@NonNull IsInputCommand inputCommand) { final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); } else { - log.info("Input command received: {}", inputCommand); + Event event = inputCommand.getNanoTimedEvent().getEvent(); + if (event instanceof javafx.scene.input.MouseEvent) { + final MouseEvent mouseEvent = (MouseEvent) event; + log.info("Input command received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mouseEvent.getButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + } else { + log.info("Input command received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + } + } } } From 51a79df9096851fd1ceb3a6a2eb5cc745ee15531 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 21:30:10 +0100 Subject: [PATCH 16/23] adjust todo --- TODO.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO.md b/TODO.md index 4c226869..ff16c999 100644 --- a/TODO.md +++ b/TODO.md @@ -6,9 +6,9 @@ * zooming * * InputCommands (<-) - * MouseClick (/) - * MouseDrag (<--------------------) - * MouseWheel + * MouseClick (/) + * MouseDrag (/) + * MouseWheel (<-) * Keyboard * PhysicsCore holds position in TransformComponent or Object * Transform is modified when moved! From 57516770d1c7ddfb4b7ed3aba7d797d4f057f686 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 23:23:50 +0100 Subject: [PATCH 17/23] add scroll events/commands --- .../com/recom/tacview/engine/TacViewer.java | 6 +- .../component/HandlesInputCommand.java | 4 +- .../component/InputComponent.java | 4 +- .../tacview/engine/input/InputManager.java | 16 +- .../{IsInputCommand.java => IsCommand.java} | 2 +- .../engine/input/command/ScrollCommand.java | 36 ++++ .../mouse/fsm/MouseButtonEventFSM0.java | 158 ------------------ .../IsMouseCommand.java | 6 +- .../{mouse => mousebutton}/MouseButton.java | 2 +- .../MouseButtonCommand.java | 28 +--- .../MouseDragCommand.java | 31 ++-- .../mapper/IsInputCommandMapper.java | 8 +- .../JavaFxMouseButtonCommandMapper.java} | 33 ++-- .../mousebutton}/fsm/FSMStates.java | 2 +- .../mousebutton}/fsm/InputAlphabet.java | 2 +- .../fsm/IsMouseButtonEventFSM.java | 9 +- .../fsm/MouseButtonEventFSM1.java | 29 ++-- .../fsm/MouseButtonEventFSM1.puml | 0 .../JavaFxMouseScrollCommandMapper.java | 64 +++++++ .../tacview/engine/module/EngineModule.java | 6 +- .../component/RECOMMapInputComponent.java | 29 +++- 21 files changed, 205 insertions(+), 270 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{IsInputCommand.java => IsCommand.java} (81%) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java delete mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{mouse => mousebutton}/IsMouseCommand.java (54%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{mouse => mousebutton}/MouseButton.java (56%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{mouse => mousebutton}/MouseButtonCommand.java (65%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{mouse => mousebutton}/MouseDragCommand.java (72%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command => }/mapper/IsInputCommandMapper.java (52%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse/JavaFxMouseCommandMapper.java => mapper/mousebutton/JavaFxMouseButtonCommandMapper.java} (65%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse => mapper/mousebutton}/fsm/FSMStates.java (58%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse => mapper/mousebutton}/fsm/InputAlphabet.java (71%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse => mapper/mousebutton}/fsm/IsMouseButtonEventFSM.java (60%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse => mapper/mousebutton}/fsm/MouseButtonEventFSM1.java (90%) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/{command/mapper/mouse => mapper/mousebutton}/fsm/MouseButtonEventFSM1.puml (100%) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 9537f084..4a491600 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -3,7 +3,8 @@ import com.recom.tacview.engine.graphics.ScreenComposer; import com.recom.tacview.engine.input.GenericFXInputEventListener; import com.recom.tacview.engine.input.InputManager; -import com.recom.tacview.engine.input.command.mapper.mouse.JavaFxMouseCommandMapper; +import com.recom.tacview.engine.input.mapper.mousebutton.JavaFxMouseButtonCommandMapper; +import com.recom.tacview.engine.input.mapper.scroll.JavaFxMouseScrollCommandMapper; import com.recom.tacview.engine.module.EngineModule; import com.recom.tacview.property.RendererProperties; import com.recom.tacview.property.TickProperties; @@ -75,7 +76,8 @@ public TacViewer( // register input event listener this.setEventHandler(InputEvent.ANY, this.genericFXInputEventListener); - this.inputManager.registerCommandMapper(new JavaFxMouseCommandMapper()); + this.inputManager.registerCommandMapper(new JavaFxMouseButtonCommandMapper()); + this.inputManager.registerCommandMapper(new JavaFxMouseScrollCommandMapper()); } @NonNull diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java index 579845eb..e4b8e508 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java @@ -1,10 +1,10 @@ package com.recom.tacview.engine.entitycomponentsystem.component; -import com.recom.tacview.engine.input.command.IsInputCommand; +import com.recom.tacview.engine.input.command.IsCommand; import lombok.NonNull; public interface HandlesInputCommand { - void handleInputCommand(@NonNull final IsInputCommand inputCommand); + void handleInputCommand(@NonNull final IsCommand inputCommand); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java index da151e71..28379ba9 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java @@ -1,6 +1,6 @@ package com.recom.tacview.engine.entitycomponentsystem.component; -import com.recom.tacview.engine.input.command.IsInputCommand; +import com.recom.tacview.engine.input.command.IsCommand; import lombok.NonNull; public abstract class InputComponent extends ComponentTemplate implements HandlesInputCommand { @@ -10,6 +10,6 @@ public InputComponent() { } @Override - public abstract void handleInputCommand(@NonNull final IsInputCommand inputCommand); + public abstract void handleInputCommand(@NonNull final IsCommand inputCommand); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java index 37b83e62..c5c391f1 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/InputManager.java @@ -1,7 +1,7 @@ package com.recom.tacview.engine.input; -import com.recom.tacview.engine.input.command.IsInputCommand; -import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; +import com.recom.tacview.engine.input.command.IsCommand; +import com.recom.tacview.engine.input.mapper.IsInputCommandMapper; import javafx.scene.input.InputEvent; import lombok.Getter; import lombok.NonNull; @@ -21,14 +21,14 @@ public class InputManager { private final LinkedList> inputEventQueue = new LinkedList<>(); @NonNull - private final LinkedList registeredCommandsMappers = new LinkedList<>(); + private final LinkedList> registeredCommandsMappers = new LinkedList<>(); @NonNull - private final LinkedList createdInputCommands = new LinkedList<>(); + private final LinkedList> createdInputCommands = new LinkedList<>(); public void mapInputEventsToCommands() { - for (final IsInputCommandMapper mapper : registeredCommandsMappers) { + for (final IsInputCommandMapper mapper : registeredCommandsMappers) { if (mapper.mapEvents(inputEventQueue.stream())) { createdInputCommands.addAll(mapper.popCreatedCommands()); } @@ -40,14 +40,14 @@ public void clearInputQueues() { } @NonNull - public LinkedList popInputCommands() { - final LinkedList createdInputCommandsCopy = new LinkedList<>(createdInputCommands); + public LinkedList> popInputCommands() { + final LinkedList> createdInputCommandsCopy = new LinkedList<>(createdInputCommands); createdInputCommands.clear(); return createdInputCommandsCopy; } - public void registerCommandMapper(@NonNull final IsInputCommandMapper inputCommandMapper) { + public void registerCommandMapper(@NonNull final IsInputCommandMapper inputCommandMapper) { registeredCommandsMappers.add(inputCommandMapper); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsCommand.java similarity index 81% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsCommand.java index 5c893dde..a6893d1e 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsInputCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/IsCommand.java @@ -4,7 +4,7 @@ import javafx.scene.input.InputEvent; import lombok.NonNull; -public interface IsInputCommand { +public interface IsCommand { long getNanos(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java new file mode 100644 index 00000000..6caa4223 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java @@ -0,0 +1,36 @@ +package com.recom.tacview.engine.input.command; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import javafx.scene.input.ScrollEvent; +import lombok.Getter; +import lombok.NonNull; + +@Getter +public class ScrollCommand implements IsCommand { + + @NonNull + private final NanoTimedEvent nanoTimedEvent; + + + @NonNull + public static ScrollCommand of(@NonNull final NanoTimedEvent nanoTimedEvent) { + return new ScrollCommand(nanoTimedEvent); + } + + public ScrollCommand(@NonNull final NanoTimedEvent nanoTimedEvent) { + this.nanoTimedEvent = nanoTimedEvent; + } + + public double getPositionX() { + return nanoTimedEvent.getEvent().getX(); + } + + public double getPositionY() { + return nanoTimedEvent.getEvent().getY(); + } + + public long getNanos() { + return nanoTimedEvent.getNanos(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java deleted file mode 100644 index 7f205a41..00000000 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM0.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; - -import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; -import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; -import javafx.event.EventType; -import javafx.scene.input.MouseEvent; -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import org.springframework.lang.Nullable; - -import java.time.Duration; -import java.util.LinkedList; -import java.util.stream.Stream; - -@Slf4j -public class MouseButtonEventFSM0 implements IsMouseButtonEventFSM { - - @NonNull - private final long doubleClickThresholdNanos; - @NonNull - private final long dragThresholdNanos; - - @NonNull - private FSMStates currentMachineState = FSMStates.IDLE; - - @Nullable - private NanoTimedEvent eventCandidateBuffer; - - @NonNull - private final LinkedList bufferedCommands = new LinkedList<>(); - - - public MouseButtonEventFSM0(@NonNull final Duration doubleClickThreshold) { - this.doubleClickThresholdNanos = doubleClickThreshold.toNanos(); - this.dragThresholdNanos = Duration.ofMillis(200).toNanos(); - } - - @Override - public void start() { - currentMachineState = FSMStates.IDLE; - } - - @Override - public void stop() { - currentMachineState = FSMStates.STOPPED; - } - - @Override - public boolean hasBufferedCommands() { - return !bufferedCommands.isEmpty(); - } - - @NonNull - @Override - public Stream popBufferedCommands() { - final LinkedList bufferedCommandsCopy = new LinkedList<>(bufferedCommands); - bufferedCommands.clear(); - - return bufferedCommandsCopy.stream(); - } - - public void iterate() { - engineRevolution(null); - } - - public void iterate(@NonNull final NanoTimedEvent nextNanoTimedMouseEvent) { - engineRevolution(nextNanoTimedMouseEvent); - } - - private void engineRevolution(@Nullable final NanoTimedEvent nextEvent) { - final InputAlphabet input = determineInputAlphabet(nextEvent); -// if (nextEvent != null && !input.equals(InputAlphabet.UNHANDLED)) { -// log.info("Next Event: {}", nextEvent.getEvent().toString()); -// } - switch (currentMachineState) { - case IDLE -> { - if (input == InputAlphabet.MOUSE_PRESSED) { - assert nextEvent != null; - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } - } - case CLICK_CANDIDATE -> { - if (input == InputAlphabet.IDLEING) { - assert nextEvent == null; - assert eventCandidateBuffer != null; - if (clickThresholdExpired(eventCandidateBuffer)) { - bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = null; - currentMachineState = FSMStates.MOUSE_DRAGGING; - } - } else if (input == InputAlphabet.MOUSE_RELEASED) { - assert nextEvent != null; - if (eventCandidateBuffer != null && !clickThresholdExpired(eventCandidateBuffer)) { - if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { - bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = null; - currentMachineState = FSMStates.IDLE; - } else { - // @TODO: ?! - // anderer Button gedrückt -> ignorieren ! ? - // ansonsten bräuchte buffers für jeden button!!!! - } - } - } else if (input == InputAlphabet.MOUSE_PRESSED) { - assert nextEvent != null; - assert eventCandidateBuffer != null; - if (clickThresholdExpired(eventCandidateBuffer)) { - bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } else { - if (eventCandidateBuffer.getEvent().getButton().equals(nextEvent.getEvent().getButton())) { - bufferedCommands.add(MouseButtonCommand.doubleClickCommand(nextEvent)); - eventCandidateBuffer = null; - currentMachineState = FSMStates.IDLE; - } else { - bufferedCommands.add(MouseButtonCommand.singleClickCommand(eventCandidateBuffer)); - eventCandidateBuffer = nextEvent; - currentMachineState = FSMStates.CLICK_CANDIDATE; - } - } - } - } - case MOUSE_DRAGGING -> { - log.info("Mouse drag entered"); - } - default -> { - throw new IllegalStateException(String.format("Unexpected Transition via State:%1s -> Input:%2s", currentMachineState, input)); - } - } - } - - private boolean clickThresholdExpired(@NonNull final NanoTimedEvent event) { - return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; - } - - private boolean dragThresholdExpired(@NonNull final NanoTimedEvent event) { - return (System.nanoTime() - event.getNanos()) > doubleClickThresholdNanos; - } - - @NonNull - private InputAlphabet determineInputAlphabet(@Nullable final NanoTimedEvent nextNanoTimedMouseEvent) { - if (nextNanoTimedMouseEvent == null) { - return InputAlphabet.IDLEING; - } else { - final EventType eventType = nextNanoTimedMouseEvent.getEvent().getEventType(); - - if (eventType == MouseEvent.MOUSE_PRESSED) { - return InputAlphabet.MOUSE_PRESSED; - } - } - - return InputAlphabet.UNHANDLED; - } - -} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/IsMouseCommand.java similarity index 54% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/IsMouseCommand.java index 65e21658..0b62a455 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/IsMouseCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/IsMouseCommand.java @@ -1,9 +1,9 @@ -package com.recom.tacview.engine.input.command.mouse; +package com.recom.tacview.engine.input.command.mousebutton; -import com.recom.tacview.engine.input.command.IsInputCommand; +import com.recom.tacview.engine.input.command.IsCommand; import javafx.scene.input.MouseEvent; -public interface IsMouseCommand extends IsInputCommand { +public interface IsMouseCommand extends IsCommand { double getPositionX(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButton.java similarity index 56% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButton.java index 895838dd..fb2cb59f 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButton.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButton.java @@ -1,4 +1,4 @@ -package com.recom.tacview.engine.input.command.mouse; +package com.recom.tacview.engine.input.command.mousebutton; public enum MouseButton { PRIMARY, diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButtonCommand.java similarity index 65% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButtonCommand.java index d96b802a..51bec60d 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseButtonCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseButtonCommand.java @@ -1,17 +1,16 @@ -package com.recom.tacview.engine.input.command.mouse; +package com.recom.tacview.engine.input.command.mousebutton; import com.recom.tacview.engine.input.NanoTimedEvent; import javafx.scene.input.MouseEvent; import lombok.Getter; import lombok.NonNull; +@Getter public class MouseButtonCommand implements IsMouseCommand { @NonNull - private final NanoTimedEvent nanoTimedMouseEvent; - @Getter + private final NanoTimedEvent nanoTimedEvent; private final boolean doubleClick; - @Getter @NonNull private final MouseButton mouseButton; @@ -29,12 +28,12 @@ public static MouseButtonCommand doubleClickCommand(@NonNull final NanoTimedEven } public MouseButtonCommand( - @NonNull final NanoTimedEvent nanoTimedMouseEvent, + @NonNull final NanoTimedEvent nanoTimedEvent, final boolean isDoubleClick ) { - this.nanoTimedMouseEvent = nanoTimedMouseEvent; + this.nanoTimedEvent = nanoTimedEvent; this.doubleClick = isDoubleClick; - this.mouseButton = determineMouseButton(nanoTimedMouseEvent.getEvent()); + this.mouseButton = determineMouseButton(nanoTimedEvent.getEvent()); } @NonNull @@ -49,26 +48,17 @@ private MouseButton determineMouseButton(@NonNull final MouseEvent event) { @Override public double getPositionX() { - return nanoTimedMouseEvent.getEvent().getX(); + return nanoTimedEvent.getEvent().getX(); } @Override public double getPositionY() { - return nanoTimedMouseEvent.getEvent().getY(); - } - - @NonNull - public NanoTimedEvent getNanoTimedEvent() { - nanoTimedMouseEvent.getEvent().getEventType(); - nanoTimedMouseEvent.getEvent().getButton(); - - - return nanoTimedMouseEvent; + return nanoTimedEvent.getEvent().getY(); } @Override public long getNanos() { - return nanoTimedMouseEvent.getNanos(); + return nanoTimedEvent.getNanos(); } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseDragCommand.java similarity index 72% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseDragCommand.java index 92fae96a..bf820a79 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mouse/MouseDragCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mousebutton/MouseDragCommand.java @@ -1,19 +1,17 @@ -package com.recom.tacview.engine.input.command.mouse; +package com.recom.tacview.engine.input.command.mousebutton; import com.recom.tacview.engine.input.NanoTimedEvent; import javafx.scene.input.MouseEvent; import lombok.Getter; import lombok.NonNull; +@Getter public class MouseDragCommand implements IsMouseCommand { - @Getter - @NonNull - private final NanoTimedEvent nanoTimedMouseEvent; - @Getter private final boolean dragStart; private final boolean dragStop; - @Getter + @NonNull + private final NanoTimedEvent nanoTimedEvent; @NonNull private final MouseButton mouseButton; @@ -39,14 +37,14 @@ public static MouseDragCommand dragginCommand(@NonNull final NanoTimedEvent nanoTimedMouseEvent, + @NonNull final NanoTimedEvent nanoTimedEvent, final boolean startMouseDrag, final boolean stopMouseDrag ) { - this.nanoTimedMouseEvent = nanoTimedMouseEvent; + this.nanoTimedEvent = nanoTimedEvent; this.dragStart = startMouseDrag; this.dragStop = stopMouseDrag; - this.mouseButton = determineMouseButton(nanoTimedMouseEvent.getEvent()); + this.mouseButton = determineMouseButton(nanoTimedEvent.getEvent()); } @NonNull @@ -65,26 +63,17 @@ public boolean isDragging() { @Override public double getPositionX() { - return nanoTimedMouseEvent.getEvent().getX(); + return nanoTimedEvent.getEvent().getX(); } @Override public double getPositionY() { - return nanoTimedMouseEvent.getEvent().getY(); - } - - @NonNull - public NanoTimedEvent getNanoTimedEvent() { - nanoTimedMouseEvent.getEvent().getEventType(); - nanoTimedMouseEvent.getEvent().getButton(); - - - return nanoTimedMouseEvent; + return nanoTimedEvent.getEvent().getY(); } @Override public long getNanos() { - return nanoTimedMouseEvent.getNanos(); + return nanoTimedEvent.getNanos(); } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/IsInputCommandMapper.java similarity index 52% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/IsInputCommandMapper.java index 77fe56ab..093f5b26 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/IsInputCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/IsInputCommandMapper.java @@ -1,18 +1,18 @@ -package com.recom.tacview.engine.input.command.mapper; +package com.recom.tacview.engine.input.mapper; import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.IsInputCommand; +import com.recom.tacview.engine.input.command.IsCommand; import javafx.scene.input.InputEvent; import lombok.NonNull; import java.util.LinkedList; import java.util.stream.Stream; -public interface IsInputCommandMapper { +public interface IsInputCommandMapper> extends AutoCloseable { boolean mapEvents(@NonNull final Stream> inputEventStream); @NonNull - LinkedList popCreatedCommands(); + LinkedList popCreatedCommands(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/JavaFxMouseButtonCommandMapper.java similarity index 65% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/JavaFxMouseButtonCommandMapper.java index f335eeed..746dc621 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/JavaFxMouseCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/JavaFxMouseButtonCommandMapper.java @@ -1,11 +1,11 @@ -package com.recom.tacview.engine.input.command.mapper.mouse; +package com.recom.tacview.engine.input.mapper.mousebutton; import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.IsInputCommand; -import com.recom.tacview.engine.input.command.mapper.IsInputCommandMapper; -import com.recom.tacview.engine.input.command.mapper.mouse.fsm.IsMouseButtonEventFSM; -import com.recom.tacview.engine.input.command.mapper.mouse.fsm.MouseButtonEventFSM1; -import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; +import com.recom.tacview.engine.input.command.IsCommand; +import com.recom.tacview.engine.input.command.mousebutton.IsMouseCommand; +import com.recom.tacview.engine.input.mapper.IsInputCommandMapper; +import com.recom.tacview.engine.input.mapper.mousebutton.fsm.IsMouseButtonEventFSM; +import com.recom.tacview.engine.input.mapper.mousebutton.fsm.MouseButtonEventFSM1; import javafx.scene.input.InputEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; @@ -15,24 +15,21 @@ import java.time.Duration; import java.util.Comparator; import java.util.LinkedList; -import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @Slf4j -public class JavaFxMouseCommandMapper implements IsInputCommandMapper, AutoCloseable { +public class JavaFxMouseButtonCommandMapper implements IsInputCommandMapper> { @NonNull private final LinkedList> unprocessedMouseEvents = new LinkedList<>(); @NonNull - private final List mouseButtonEventFSMs; + private final LinkedList mouseButtonEventFSMs = new LinkedList<>(); - public JavaFxMouseCommandMapper() { - mouseButtonEventFSMs = List.of( - new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.PRIMARY), - new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.SECONDARY), - new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.MIDDLE) - ); + public JavaFxMouseButtonCommandMapper() { + mouseButtonEventFSMs.add(new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.PRIMARY)); + mouseButtonEventFSMs.add(new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.SECONDARY)); + mouseButtonEventFSMs.add(new MouseButtonEventFSM1(Duration.ofMillis(150), Duration.ofMillis(150), MouseButton.MIDDLE)); startMachines(); } @@ -77,16 +74,18 @@ private boolean runMouseButtonFSM() { @NonNull @Override - public LinkedList popCreatedCommands() { + public LinkedList> popCreatedCommands() { return mouseButtonEventFSMs.stream() .flatMap(IsMouseButtonEventFSM::popBufferedCommands) - .sorted(Comparator.comparing(IsInputCommand::getNanos)) + .sorted(Comparator.comparing(IsCommand::getNanos)) .collect(Collectors.toCollection(LinkedList::new)); } @Override public void close() { mouseButtonEventFSMs.forEach(IsMouseButtonEventFSM::stop); + mouseButtonEventFSMs.clear(); + unprocessedMouseEvents.clear(); } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/FSMStates.java similarity index 58% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/FSMStates.java index 9ea8f659..d504acf9 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/FSMStates.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/FSMStates.java @@ -1,4 +1,4 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; +package com.recom.tacview.engine.input.mapper.mousebutton.fsm; enum FSMStates { NEW, diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/InputAlphabet.java similarity index 71% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/InputAlphabet.java index 4dfea219..1670c21f 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/InputAlphabet.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/InputAlphabet.java @@ -1,4 +1,4 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; +package com.recom.tacview.engine.input.mapper.mousebutton.fsm; enum InputAlphabet { IDLEING, diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/IsMouseButtonEventFSM.java similarity index 60% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/IsMouseButtonEventFSM.java index 01ed2094..6c8ebfb8 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/IsMouseButtonEventFSM.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/IsMouseButtonEventFSM.java @@ -1,11 +1,10 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; +package com.recom.tacview.engine.input.mapper.mousebutton.fsm; import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; +import com.recom.tacview.engine.input.command.mousebutton.IsMouseCommand; import javafx.scene.input.MouseEvent; import lombok.NonNull; -import java.util.LinkedList; import java.util.stream.Stream; public interface IsMouseButtonEventFSM { @@ -20,10 +19,8 @@ public interface IsMouseButtonEventFSM { boolean hasBufferedCommands(); -// void clearBufferedCommands(); - @NonNull - Stream popBufferedCommands(); + Stream> popBufferedCommands(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.java similarity index 90% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.java index 262dcabd..d0a4048d 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.java @@ -1,9 +1,9 @@ -package com.recom.tacview.engine.input.command.mapper.mouse.fsm; +package com.recom.tacview.engine.input.mapper.mousebutton.fsm; import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.mouse.IsMouseCommand; -import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; -import com.recom.tacview.engine.input.command.mouse.MouseDragCommand; +import com.recom.tacview.engine.input.command.mousebutton.IsMouseCommand; +import com.recom.tacview.engine.input.command.mousebutton.MouseButtonCommand; +import com.recom.tacview.engine.input.command.mousebutton.MouseDragCommand; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import lombok.NonNull; @@ -14,9 +14,6 @@ import java.util.LinkedList; import java.util.stream.Stream; -import static com.recom.tacview.engine.input.command.mapper.mouse.fsm.InputAlphabet.IDLEING; -import static com.recom.tacview.engine.input.command.mapper.mouse.fsm.InputAlphabet.MOUSE_DRAGGING; - @Slf4j public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { @@ -38,7 +35,7 @@ public class MouseButtonEventFSM1 implements IsMouseButtonEventFSM { private NanoTimedEvent mouseDragOriginEventBuffer; @NonNull - private final LinkedList bufferedCommands = new LinkedList<>(); + private final LinkedList> bufferedCommands = new LinkedList<>(); public MouseButtonEventFSM1( @@ -77,8 +74,8 @@ public boolean hasBufferedCommands() { @NonNull @Override - public Stream popBufferedCommands() { - final LinkedList bufferedCommandsCopy = new LinkedList<>(bufferedCommands); + public Stream> popBufferedCommands() { + final LinkedList> bufferedCommandsCopy = new LinkedList<>(bufferedCommands); bufferedCommands.clear(); return bufferedCommandsCopy.stream(); @@ -183,11 +180,11 @@ private boolean fsmIsNotResponsibleForMouseButtonRelatedEvents(@Nullable final N @NonNull private InputAlphabet idleAlphabet(@Nullable final NanoTimedEvent nextEvent) { if (nextEvent == null) { - return IDLEING; + return InputAlphabet.IDLEING; } else if (nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_PRESSED) { return InputAlphabet.MOUSE_PRESSED; } else { - return IDLEING; + return InputAlphabet.IDLEING; } } @@ -205,20 +202,20 @@ private InputAlphabet clickCandidateAlphabet( } else if (nextEvent != null && nextEvent.getEvent() instanceof MouseEvent && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED) { return InputAlphabet.MOUSE_RELEASED; } else { - return IDLEING; + return InputAlphabet.IDLEING; } } @NonNull private InputAlphabet mouseDraggingAlphabet(@Nullable final NanoTimedEvent nextEvent) { if (nextEvent == null) { - return IDLEING; + return InputAlphabet.IDLEING; } else if (nextEvent != null && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_RELEASED) { return InputAlphabet.MOUSE_RELEASED; } else if (nextEvent != null && nextEvent.getEvent() instanceof MouseEvent && nextEvent.getEvent().getEventType() == MouseEvent.MOUSE_DRAGGED) { - return MOUSE_DRAGGING; + return InputAlphabet.MOUSE_DRAGGING; } else { - return IDLEING; + return InputAlphabet.IDLEING; } } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml similarity index 100% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/mapper/mouse/fsm/MouseButtonEventFSM1.puml rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java new file mode 100644 index 00000000..2a9a1206 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java @@ -0,0 +1,64 @@ +package com.recom.tacview.engine.input.mapper.scroll; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.ScrollCommand; +import com.recom.tacview.engine.input.mapper.IsInputCommandMapper; +import javafx.scene.input.InputEvent; +import javafx.scene.input.ScrollEvent; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +import java.util.LinkedList; +import java.util.stream.Stream; + +@Slf4j +public class JavaFxMouseScrollCommandMapper implements IsInputCommandMapper { + + @NonNull + private final LinkedList> unprocessedScrollEvents = new LinkedList<>(); + + @NonNull + private final LinkedList mappedCommands = new LinkedList<>(); + + + @Override + @SuppressWarnings("unchecked") + public boolean mapEvents(@NonNull final Stream> timedMouseEventStream) { + timedMouseEventStream + .filter(event -> event.getEvent() instanceof ScrollEvent) + .map(event -> (NanoTimedEvent) event) + .filter(this::isMouseScrollEvent) + .forEach(unprocessedScrollEvents::add); + + return mapEventsToCommands(); + } + + private boolean mapEventsToCommands() { + unprocessedScrollEvents.stream() + .map(ScrollCommand::of) + .forEach(mappedCommands::add); + unprocessedScrollEvents.clear(); + + return !mappedCommands.isEmpty(); + } + + private boolean isMouseScrollEvent(@NonNull final NanoTimedEvent nanoTimedEvent) { + return nanoTimedEvent.getEvent().getEventType() == ScrollEvent.SCROLL; + } + + @NonNull + @Override + public LinkedList popCreatedCommands() { + final LinkedList scrollCommandsCopy = new LinkedList<>(mappedCommands); + mappedCommands.clear(); + + return scrollCommandsCopy; + } + + @Override + public void close() { + unprocessedScrollEvents.clear(); + mappedCommands.clear(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java index 269d9bb2..582d2681 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/module/EngineModule.java @@ -4,7 +4,7 @@ import com.recom.tacview.engine.entitycomponentsystem.component.ComponentType; import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; import com.recom.tacview.engine.entitycomponentsystem.environment.Environment; -import com.recom.tacview.engine.input.command.IsInputCommand; +import com.recom.tacview.engine.input.command.IsCommand; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -33,12 +33,12 @@ public void update(final long elapsedNanoTime) { environment.update(elapsedNanoTime); } - public void handleInputCommands(@NonNull final List inputEventQueue) { + public void handleInputCommands(@NonNull final List> inputEventQueue) { final List inputComponents = environment.getEntities().stream() .flatMap(entity -> entity.locateComponents(ComponentType.InputComponent).stream()) .toList(); - for (final IsInputCommand inputCommand : inputEventQueue) { + for (final IsCommand inputCommand : inputEventQueue) { for (final InputComponent inputComponent : inputComponents) { inputComponent.handleInputCommand(inputCommand); } diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 10ef9ce2..5fa91b55 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -1,10 +1,11 @@ package com.recom.commander.enginemodule.entity.component; import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; -import com.recom.tacview.engine.input.command.IsInputCommand; -import com.recom.tacview.engine.input.command.mouse.MouseButtonCommand; +import com.recom.tacview.engine.input.command.IsCommand; +import com.recom.tacview.engine.input.command.mousebutton.MouseButtonCommand; import javafx.event.Event; import javafx.scene.input.MouseEvent; +import javafx.scene.input.ScrollEvent; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -14,7 +15,7 @@ public class RECOMMapInputComponent extends InputComponent { @Override - public void handleInputCommand(@NonNull IsInputCommand inputCommand) { + public void handleInputCommand(@NonNull IsCommand inputCommand) { if (inputCommand instanceof MouseButtonCommand) { final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); @@ -22,11 +23,29 @@ public void handleInputCommand(@NonNull IsInputCommand inputCommand) { Event event = inputCommand.getNanoTimedEvent().getEvent(); if (event instanceof javafx.scene.input.MouseEvent) { final MouseEvent mouseEvent = (MouseEvent) event; - log.info("Input command received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mouseEvent.getButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + log.info("MouseCommand received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mouseEvent.getButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + } else if (event instanceof javafx.scene.input.ScrollEvent) { + final javafx.scene.input.ScrollEvent scrollEvent = (javafx.scene.input.ScrollEvent) event; + log.info("ScrollCommand received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollEvent), inputCommand.getNanoTimedEvent().getEvent().getEventType()); } else { - log.info("Input command received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); } } } + + @NonNull + private String mapToScrollDirection(@NonNull final ScrollEvent scrollEvent) { + if (scrollEvent.getDeltaX() < 0) { + return "RIGHT"; + } else if (scrollEvent.getDeltaX() > 0) { + return "LEFT"; + } else if (scrollEvent.getDeltaY() > 0) { + return "UP"; + } else if (scrollEvent.getDeltaY() < 0) { + return "DOWN"; + } else { + return "NONE"; + } + } } From 872ed0aef2133b2340ba0e87ea6e17d38950ed2f Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 23:38:03 +0100 Subject: [PATCH 18/23] tidy up --- .../entity/component/RECOMMapInputComponent.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 5fa91b55..5c1aa384 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -21,16 +21,13 @@ public void handleInputCommand(@NonNull IsCommand inputCommand) { log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); } else { Event event = inputCommand.getNanoTimedEvent().getEvent(); - if (event instanceof javafx.scene.input.MouseEvent) { - final MouseEvent mouseEvent = (MouseEvent) event; + if (event instanceof MouseEvent mouseEvent) { log.info("MouseCommand received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mouseEvent.getButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); - } else if (event instanceof javafx.scene.input.ScrollEvent) { - final javafx.scene.input.ScrollEvent scrollEvent = (javafx.scene.input.ScrollEvent) event; - log.info("ScrollCommand received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollEvent), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + } else if (event instanceof ScrollEvent scrollEvent) { + log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollEvent)); } else { - log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); } - } } @@ -48,4 +45,5 @@ private String mapToScrollDirection(@NonNull final ScrollEvent scrollEvent) { return "NONE"; } } + } From 8f231c7c96f30dcc218455140f521df31e873915 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 23:38:57 +0100 Subject: [PATCH 19/23] tidy up --- .../enginemodule/entity/component/RECOMMapInputComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 5c1aa384..1eef5d44 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -18,7 +18,7 @@ public class RECOMMapInputComponent extends InputComponent { public void handleInputCommand(@NonNull IsCommand inputCommand) { if (inputCommand instanceof MouseButtonCommand) { final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; - log.info("Mouse click command received: {} is doubleClick: {}", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); + log.info("MouseClickCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); } else { Event event = inputCommand.getNanoTimedEvent().getEvent(); if (event instanceof MouseEvent mouseEvent) { From 2ee459c6c0b90bf89da108949a20b4793827e0af Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Tue, 23 Jan 2024 23:43:16 +0100 Subject: [PATCH 20/23] fix generic types --- .../entitycomponentsystem/component/HandlesInputCommand.java | 2 +- .../entitycomponentsystem/component/InputComponent.java | 2 +- .../entity/component/RECOMMapInputComponent.java | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java index e4b8e508..3277ff7b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/HandlesInputCommand.java @@ -5,6 +5,6 @@ public interface HandlesInputCommand { - void handleInputCommand(@NonNull final IsCommand inputCommand); + void handleInputCommand(@NonNull final IsCommand inputCommand); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java index 28379ba9..6ea26f90 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/InputComponent.java @@ -10,6 +10,6 @@ public InputComponent() { } @Override - public abstract void handleInputCommand(@NonNull final IsCommand inputCommand); + public abstract void handleInputCommand(@NonNull final IsCommand inputCommand); } diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 1eef5d44..e195fccb 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -15,9 +15,8 @@ public class RECOMMapInputComponent extends InputComponent { @Override - public void handleInputCommand(@NonNull IsCommand inputCommand) { - if (inputCommand instanceof MouseButtonCommand) { - final MouseButtonCommand mouseButtonCommand = (MouseButtonCommand) inputCommand; + public void handleInputCommand(@NonNull IsCommand inputCommand) { + if (inputCommand instanceof MouseButtonCommand mouseButtonCommand) { log.info("MouseClickCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); } else { Event event = inputCommand.getNanoTimedEvent().getEvent(); From cc3431b2f61b69c853b86833b2076a7ddd37a0ec Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Wed, 24 Jan 2024 23:19:44 +0100 Subject: [PATCH 21/23] add KeyboardCommand / -Event Handling --- .../com/recom/tacview/engine/TacViewer.java | 2 + .../command/keyboard/KeyboardCommand.java | 29 ++++++++ .../command/{ => scroll}/ScrollCommand.java | 3 +- .../keyboard/JavaFxKeyboardCommandMapper.java | 67 ++++++++++++++++++ .../keyboard/KeyboardCommandGenerator.java | 70 +++++++++++++++++++ .../mousebutton/fsm/MouseButtonEventFSM1.puml | 2 +- .../JavaFxMouseScrollCommandMapper.java | 2 +- .../component/RECOMMapInputComponent.java | 22 +++--- 8 files changed, 183 insertions(+), 14 deletions(-) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/keyboard/KeyboardCommand.java rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/{ => scroll}/ScrollCommand.java (88%) create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/JavaFxKeyboardCommandMapper.java create mode 100644 libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/KeyboardCommandGenerator.java diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 4a491600..7fc80896 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -3,6 +3,7 @@ import com.recom.tacview.engine.graphics.ScreenComposer; import com.recom.tacview.engine.input.GenericFXInputEventListener; import com.recom.tacview.engine.input.InputManager; +import com.recom.tacview.engine.input.mapper.keyboard.JavaFxKeyboardCommandMapper; import com.recom.tacview.engine.input.mapper.mousebutton.JavaFxMouseButtonCommandMapper; import com.recom.tacview.engine.input.mapper.scroll.JavaFxMouseScrollCommandMapper; import com.recom.tacview.engine.module.EngineModule; @@ -78,6 +79,7 @@ public TacViewer( this.setEventHandler(InputEvent.ANY, this.genericFXInputEventListener); this.inputManager.registerCommandMapper(new JavaFxMouseButtonCommandMapper()); this.inputManager.registerCommandMapper(new JavaFxMouseScrollCommandMapper()); + this.inputManager.registerCommandMapper(new JavaFxKeyboardCommandMapper()); } @NonNull diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/keyboard/KeyboardCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/keyboard/KeyboardCommand.java new file mode 100644 index 00000000..8cd42535 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/keyboard/KeyboardCommand.java @@ -0,0 +1,29 @@ +package com.recom.tacview.engine.input.command.keyboard; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.IsCommand; +import javafx.scene.input.KeyEvent; +import lombok.Getter; +import lombok.NonNull; + +@Getter +public class KeyboardCommand implements IsCommand { + + @NonNull + private final NanoTimedEvent nanoTimedEvent; + + + @NonNull + public static KeyboardCommand of(@NonNull final NanoTimedEvent nanoTimedEvent) { + return new KeyboardCommand(nanoTimedEvent); + } + + public KeyboardCommand(@NonNull final NanoTimedEvent nanoTimedEvent) { + this.nanoTimedEvent = nanoTimedEvent; + } + + public long getNanos() { + return nanoTimedEvent.getNanos(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/scroll/ScrollCommand.java similarity index 88% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/scroll/ScrollCommand.java index 6caa4223..06238c9e 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/ScrollCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/command/scroll/ScrollCommand.java @@ -1,6 +1,7 @@ -package com.recom.tacview.engine.input.command; +package com.recom.tacview.engine.input.command.scroll; import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.IsCommand; import javafx.scene.input.ScrollEvent; import lombok.Getter; import lombok.NonNull; diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/JavaFxKeyboardCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/JavaFxKeyboardCommandMapper.java new file mode 100644 index 00000000..9d3c44ba --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/JavaFxKeyboardCommandMapper.java @@ -0,0 +1,67 @@ +package com.recom.tacview.engine.input.mapper.keyboard; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.IsCommand; +import com.recom.tacview.engine.input.command.keyboard.KeyboardCommand; +import com.recom.tacview.engine.input.mapper.IsInputCommandMapper; +import javafx.scene.input.InputEvent; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseEvent; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +import java.util.Comparator; +import java.util.LinkedList; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Slf4j +public class JavaFxKeyboardCommandMapper implements IsInputCommandMapper { + + @NonNull + private final LinkedList> unprocessedKeypressEvents = new LinkedList<>(); + @NonNull + private final KeyboardCommandGenerator keyboardCommandGenerator = new KeyboardCommandGenerator(); + + + @Override + @SuppressWarnings("unchecked") + public boolean mapEvents(@NonNull final Stream> timedMouseEventStream) { + timedMouseEventStream + .filter(event -> event.getEvent() instanceof KeyEvent) + .map(event -> (NanoTimedEvent) event) + .filter(this::isObservedKeyEvent) + .forEach(unprocessedKeypressEvents::add); + + return runKeypresGenerator(); + } + + private boolean isObservedKeyEvent(@NonNull final NanoTimedEvent nanoTimedEvent) { + return nanoTimedEvent.getEvent().getEventType() == KeyEvent.KEY_PRESSED + || nanoTimedEvent.getEvent().getEventType() == KeyEvent.KEY_RELEASED; + } + + private boolean runKeypresGenerator() { + while (!unprocessedKeypressEvents.isEmpty()) { + keyboardCommandGenerator.updateKeyStates(unprocessedKeypressEvents.poll()); + } + keyboardCommandGenerator.generate(); + + return keyboardCommandGenerator.hasBufferedCommands(); + } + + @NonNull + @Override + public LinkedList popCreatedCommands() { + return keyboardCommandGenerator.popBufferedCommands() + .sorted(Comparator.comparing(IsCommand::getNanos)) + .collect(Collectors.toCollection(LinkedList::new)); + } + + @Override + public void close() { + keyboardCommandGenerator.clear(); + unprocessedKeypressEvents.clear(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/KeyboardCommandGenerator.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/KeyboardCommandGenerator.java new file mode 100644 index 00000000..1646cc52 --- /dev/null +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/keyboard/KeyboardCommandGenerator.java @@ -0,0 +1,70 @@ +package com.recom.tacview.engine.input.mapper.keyboard; + +import com.recom.tacview.engine.input.NanoTimedEvent; +import com.recom.tacview.engine.input.command.keyboard.KeyboardCommand; +import javafx.event.EventType; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.stream.Stream; + +import static javafx.scene.input.KeyEvent.KEY_PRESSED; +import static javafx.scene.input.KeyEvent.KEY_RELEASED; + +@Slf4j +public class KeyboardCommandGenerator { + + @NonNull + private final HashMap> pressedKeyEventsBuffer = new HashMap<>(); + + @NonNull + private final LinkedList bufferedCommands = new LinkedList<>(); + + @NonNull + private final HashSet ignoredKeyCodes = new HashSet<>(); + + public KeyboardCommandGenerator() { + ignoredKeyCodes.add(KeyCode.WINDOWS); + } + + public void generate() { + pressedKeyEventsBuffer.forEach((keyCode, nanoTimedEvent) -> { + bufferedCommands.add(KeyboardCommand.of(nanoTimedEvent)); + }); + } + + public void updateKeyStates(@NonNull final NanoTimedEvent nextKeyEventNanoTimedKeyEvent) { + final EventType eventType = nextKeyEventNanoTimedKeyEvent.getEvent().getEventType(); + final KeyCode keyCode = nextKeyEventNanoTimedKeyEvent.getEvent().getCode(); + if (ignoredKeyCodes.contains(keyCode)) { + // do nothing + } else if (eventType == KEY_PRESSED) { + pressedKeyEventsBuffer.put(nextKeyEventNanoTimedKeyEvent.getEvent().getCode(), nextKeyEventNanoTimedKeyEvent); + } else if (eventType == KEY_RELEASED) { + pressedKeyEventsBuffer.remove(nextKeyEventNanoTimedKeyEvent.getEvent().getCode()); + } + } + + public boolean hasBufferedCommands() { + return !bufferedCommands.isEmpty(); + } + + @NonNull + public Stream popBufferedCommands() { + final LinkedList bufferedCommandsCopy = new LinkedList<>(bufferedCommands); + bufferedCommands.clear(); + + return bufferedCommandsCopy.stream(); + } + + public void clear() { + pressedKeyEventsBuffer.clear(); + bufferedCommands.clear(); + } + +} diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml index e4087c26..e97b6928 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/mousebutton/fsm/MouseButtonEventFSM1.puml @@ -2,7 +2,7 @@ header RECOM Tacviewer title Mouse Button Event FSM v1.0 -caption Each mouse button has its own state machine +caption (i) Each mouse button has its own state machine footer RECOM.one diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java index 2a9a1206..b4d7dfee 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/input/mapper/scroll/JavaFxMouseScrollCommandMapper.java @@ -1,7 +1,7 @@ package com.recom.tacview.engine.input.mapper.scroll; import com.recom.tacview.engine.input.NanoTimedEvent; -import com.recom.tacview.engine.input.command.ScrollCommand; +import com.recom.tacview.engine.input.command.scroll.ScrollCommand; import com.recom.tacview.engine.input.mapper.IsInputCommandMapper; import javafx.scene.input.InputEvent; import javafx.scene.input.ScrollEvent; diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index e195fccb..4d93bd17 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -2,9 +2,10 @@ import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; import com.recom.tacview.engine.input.command.IsCommand; +import com.recom.tacview.engine.input.command.keyboard.KeyboardCommand; import com.recom.tacview.engine.input.command.mousebutton.MouseButtonCommand; -import javafx.event.Event; -import javafx.scene.input.MouseEvent; +import com.recom.tacview.engine.input.command.mousebutton.MouseDragCommand; +import com.recom.tacview.engine.input.command.scroll.ScrollCommand; import javafx.scene.input.ScrollEvent; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -17,16 +18,15 @@ public class RECOMMapInputComponent extends InputComponent { @Override public void handleInputCommand(@NonNull IsCommand inputCommand) { if (inputCommand instanceof MouseButtonCommand mouseButtonCommand) { - log.info("MouseClickCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); + log.info("MouseButtonCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); + } else if (inputCommand instanceof MouseDragCommand mouseDragCommand) { + log.info("MouseDragCommand received: {} ({})", mouseDragCommand.getMouseButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + } else if (inputCommand instanceof ScrollCommand scrollCommand) { + log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollCommand.getNanoTimedEvent().getEvent())); + } else if (inputCommand instanceof KeyboardCommand keyboardCommand) { + log.info("KeyboardCommand received: {} ({})", keyboardCommand.getNanoTimedEvent().getEvent().getEventType(), keyboardCommand.getNanoTimedEvent().getEvent().getCode()); } else { - Event event = inputCommand.getNanoTimedEvent().getEvent(); - if (event instanceof MouseEvent mouseEvent) { - log.info("MouseCommand received: {} ({}) -> {}", inputCommand.getClass().getSimpleName(), mouseEvent.getButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); - } else if (event instanceof ScrollEvent scrollEvent) { - log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollEvent)); - } else { - log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); - } + log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); } } From 5cd74f7f23914d6e3731ca59c02f6ba9913f1d41 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sun, 28 Jan 2024 17:03:04 +0100 Subject: [PATCH 22/23] enable mouse cursor panning --- TODO.md | 8 +-- ...ommand.java => SwappableCanvasBuffer.java} | 4 +- .../com/recom/tacview/engine/TacViewer.java | 6 ++- .../component/RenderableComponent.java | 1 + .../entitycomponentsystem/entity/Entity.java | 2 + .../engine/graphics/ScreenComposer.java | 4 +- .../renderpipeline/RenderPipeline.java | 7 +-- .../mergeable/BufferedMergeableTemplate.java | 2 +- .../mergeable/MergeableComponentLayer.java | 14 ++++- .../RECOMMapEntityConfiguration.java | 2 + .../entity/component/RECOMMapComponent.java | 1 - .../component/RECOMMapInputComponent.java | 54 +++++++++++++++---- 12 files changed, 77 insertions(+), 28 deletions(-) rename libs/tacviewfx/src/main/java/com/recom/tacview/engine/{CanvasBufferSwapCommand.java => SwappableCanvasBuffer.java} (96%) diff --git a/TODO.md b/TODO.md index ff16c999..36d3d286 100644 --- a/TODO.md +++ b/TODO.md @@ -8,13 +8,13 @@ * InputCommands (<-) * MouseClick (/) * MouseDrag (/) - * MouseWheel (<-) - * Keyboard - * PhysicsCore holds position in TransformComponent or Object + * MouseWheel (/) + * Keyboard (/) + * PhysicsCore holds position in TransformComponent or Object (<-) * Transform is modified when moved! -* * NULLImplementations -> Optionals ... +* * dynamic changeable render properties! * optimize Layers so that they must not be reinstantiated every time on update. Reuse layers and remove/extend entities on update * diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/CanvasBufferSwapCommand.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/SwappableCanvasBuffer.java similarity index 96% rename from libs/tacviewfx/src/main/java/com/recom/tacview/engine/CanvasBufferSwapCommand.java rename to libs/tacviewfx/src/main/java/com/recom/tacview/engine/SwappableCanvasBuffer.java index 542e67b6..5a9bd52b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/CanvasBufferSwapCommand.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/SwappableCanvasBuffer.java @@ -10,7 +10,7 @@ import java.nio.IntBuffer; -public class CanvasBufferSwapCommand { +public class SwappableCanvasBuffer { @NonNull private final Canvas canvas; @@ -28,7 +28,7 @@ public class CanvasBufferSwapCommand { public int lastBackBufferIndex = -1; - public CanvasBufferSwapCommand( + public SwappableCanvasBuffer( @NonNull final Canvas canvas, @NonNull final RendererProperties rendererProperties, @NonNull final ScreenComposer screenComposer diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java index 7fc80896..297a0bd5 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/TacViewer.java @@ -39,7 +39,7 @@ public class TacViewer extends Canvas { @NonNull - private final CanvasBufferSwapCommand canvasBuffer; + private final SwappableCanvasBuffer canvasBuffer; @NonNull private final AnimationTimer animationTimerLoop; @@ -66,7 +66,9 @@ public TacViewer( this.genericFXInputEventListener = genericFXInputEventListener; this.inputManager = inputManager; - this.canvasBuffer = new CanvasBufferSwapCommand(this, rendererProperties, screenComposer); +// this.setScaleX(2); +// this.setScaleY(2); + this.canvasBuffer = new SwappableCanvasBuffer(this, rendererProperties, screenComposer); this.profiler = new TacViewerProfiler(profilerProvider); this.profiler.startProfiling(); diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/RenderableComponent.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/RenderableComponent.java index 64bddb37..d4a690cb 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/RenderableComponent.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/component/RenderableComponent.java @@ -53,4 +53,5 @@ public void propagateDirtyStateToParent() { public void prepareBuffer() { } + } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java index dfc2b4ec..ad092314 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/entitycomponentsystem/entity/Entity.java @@ -29,6 +29,7 @@ public class Entity implements IsEntity { @Override public void addComponent(@NonNull final IsComponent component) { components.add(component); + component.setEntity(this); components.sort(Comparator.comparing(IsComponent::getComponentProcessingOrder)); reIndexComponents(); } @@ -50,6 +51,7 @@ public void reIndexComponents() { @Override public void removeComponent(@NonNull final IsComponent component) { components.remove(component); + component.setEntity(NullEntity.INSTANCE); reIndexComponents(); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java index 3eb6f616..944f5819 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/ScreenComposer.java @@ -39,7 +39,7 @@ public int compose(@NonNull final Environment environment) { } else { pixelRingBuffer.next(); pixelRingBuffer.getPixelBuffer().clearBuffer(); - renderLayerPipelineInParallel(environment.getRenderPipeline()); + renderLayersInParallel(environment.getRenderPipeline()); environment.getRenderPipeline().getLayers().forEach(layer -> { layer.mergeBufferWith(pixelRingBuffer.getPixelBuffer(), 0, 0); layer.dispose(); @@ -51,7 +51,7 @@ public int compose(@NonNull final Environment environment) { } } - private void renderLayerPipelineInParallel(@NonNull final IsRenderPipeline renderPipeline) { + private void renderLayersInParallel(@NonNull final IsRenderPipeline renderPipeline) { final CountDownLatch latch = new CountDownLatch(renderPipeline.getLayers().size()); for (final MergeableComponentLayer mergeableLayer : renderPipeline.getLayers()) { renderExecutorService.execute(() -> { diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/renderpipeline/RenderPipeline.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/renderpipeline/RenderPipeline.java index 2beb6afb..01a8230b 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/renderpipeline/RenderPipeline.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/graphics/renderpipeline/RenderPipeline.java @@ -40,18 +40,19 @@ public void updateLayers() { @NonNull private List createMergeableComponentLayers() { - return getRenderableComponentsFromEnvironment().entrySet().stream() + return provideRenderableComponentsFromRegisteredEntities().entrySet().stream() .map(entrySet -> new MergeableComponentLayer(environment, entrySet.getKey(), entrySet.getValue())) .toList(); } @NonNull - private Map> getRenderableComponentsFromEnvironment() { + private Map> provideRenderableComponentsFromRegisteredEntities() { if (isDirty()) { renderableComponentList.clear(); renderableComponentList.putAll(environment.getEntities().stream() .flatMap(entity -> entity.locateComponents(ComponentType.RenderableComponent).stream()) - .collect(Collectors.groupingBy(RenderableComponent::getZIndex))); + .collect(Collectors.groupingBy(RenderableComponent::getZIndex)) + ); setDirty(true); } diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java index 78ff2200..52f7bead 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/BufferedMergeableTemplate.java @@ -69,7 +69,7 @@ public void mergeBufferWith( @Override public void prepareBuffer() { - + this.pixelBuffer.clearBuffer(); } @Override diff --git a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/MergeableComponentLayer.java b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/MergeableComponentLayer.java index 505714ea..cf41a972 100644 --- a/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/MergeableComponentLayer.java +++ b/libs/tacviewfx/src/main/java/com/recom/tacview/engine/renderables/mergeable/MergeableComponentLayer.java @@ -1,5 +1,7 @@ package com.recom.tacview.engine.renderables.mergeable; +import com.recom.tacview.engine.entitycomponentsystem.component.ComponentType; +import com.recom.tacview.engine.entitycomponentsystem.component.PhysicCoreComponent; import com.recom.tacview.engine.entitycomponentsystem.component.RenderableComponent; import com.recom.tacview.engine.entitycomponentsystem.environment.IsEnvironment; import lombok.Getter; @@ -7,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.List; +import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -48,12 +51,19 @@ public void prepareBuffer() { for (final RenderableComponent component : components) { int offsetX = 0; int offsetY = 0; + + final Optional maybePhysicCoreComponent = component.getEntity().locateComponent(ComponentType.PhysicsCoreComponent); + if (maybePhysicCoreComponent.isPresent()) { + offsetX = (int) maybePhysicCoreComponent.get().getPositionX(); + offsetY = (int) maybePhysicCoreComponent.get().getPositionY(); + } + environment.getRenderProvider().provide().render(component.getPixelBuffer(), this.getPixelBuffer(), offsetX, offsetY); } - // @TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // @TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // @TODO da müssen jetzt camera position und entity/physic_component_core position mit rein - // @TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // @TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> } private void prepareComponentBufferInParallel(@NonNull final List renderableComponents) { diff --git a/services/recom-commander/src/main/java/com/recom/commander/configuration/RECOMMapEntityConfiguration.java b/services/recom-commander/src/main/java/com/recom/commander/configuration/RECOMMapEntityConfiguration.java index 3107fd4e..5fac65a7 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/configuration/RECOMMapEntityConfiguration.java +++ b/services/recom-commander/src/main/java/com/recom/commander/configuration/RECOMMapEntityConfiguration.java @@ -4,6 +4,7 @@ import com.recom.commander.enginemodule.entity.component.RECOMMapComponent; import com.recom.commander.enginemodule.entity.component.RECOMMapInputComponent; import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; +import com.recom.tacview.engine.entitycomponentsystem.component.PhysicCoreComponent; import lombok.NonNull; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -18,6 +19,7 @@ public RECOMMapEntity getRECOMMapEntity( final RECOMMapEntity recomMapEntity = new RECOMMapEntity(); recomMapEntity.addComponent(recomMapComponent); recomMapEntity.addComponent(new RECOMMapInputComponent()); + recomMapEntity.addComponent(new PhysicCoreComponent()); return recomMapEntity; } diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapComponent.java index b4a9e6bb..0936d3a2 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapComponent.java @@ -77,7 +77,6 @@ private TakeNoticeRunnable onReloadMapTopographyDataReac final PixelBuffer pixelBuffer = new PixelBuffer(dimension, pixelBufferArray); this.pixelBuffer = pixelBuffer; - log.debug("Set pixel buffer in {}", getClass().getSimpleName()); propagateDirtyStateToParent(); }; } diff --git a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java index 4d93bd17..409b4662 100644 --- a/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java +++ b/services/recom-commander/src/main/java/com/recom/commander/enginemodule/entity/component/RECOMMapInputComponent.java @@ -1,11 +1,15 @@ package com.recom.commander.enginemodule.entity.component; +import com.recom.tacview.engine.entitycomponentsystem.component.ComponentType; import com.recom.tacview.engine.entitycomponentsystem.component.InputComponent; +import com.recom.tacview.engine.entitycomponentsystem.component.PhysicCoreComponent; +import com.recom.tacview.engine.entitycomponentsystem.component.RenderableComponent; import com.recom.tacview.engine.input.command.IsCommand; import com.recom.tacview.engine.input.command.keyboard.KeyboardCommand; import com.recom.tacview.engine.input.command.mousebutton.MouseButtonCommand; import com.recom.tacview.engine.input.command.mousebutton.MouseDragCommand; import com.recom.tacview.engine.input.command.scroll.ScrollCommand; +import javafx.scene.input.KeyCode; import javafx.scene.input.ScrollEvent; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -16,17 +20,45 @@ public class RECOMMapInputComponent extends InputComponent { @Override - public void handleInputCommand(@NonNull IsCommand inputCommand) { - if (inputCommand instanceof MouseButtonCommand mouseButtonCommand) { - log.info("MouseButtonCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); - } else if (inputCommand instanceof MouseDragCommand mouseDragCommand) { - log.info("MouseDragCommand received: {} ({})", mouseDragCommand.getMouseButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); - } else if (inputCommand instanceof ScrollCommand scrollCommand) { - log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollCommand.getNanoTimedEvent().getEvent())); - } else if (inputCommand instanceof KeyboardCommand keyboardCommand) { - log.info("KeyboardCommand received: {} ({})", keyboardCommand.getNanoTimedEvent().getEvent().getEventType(), keyboardCommand.getNanoTimedEvent().getEvent().getCode()); - } else { - log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + public void handleInputCommand(@NonNull final IsCommand inputCommand) { + switch (inputCommand) { + case KeyboardCommand keyboardCommand -> { + this.getEntity().locateComponent(ComponentType.PhysicsCoreComponent).ifPresent(physicsCoreComponent -> { + if (keyboardCommand.getNanoTimedEvent().getEvent().getCode().equals(KeyCode.LEFT)) { + physicsCoreComponent.setPositionX(physicsCoreComponent.getPositionX() + 5f); + this.getEntity().locateComponent(ComponentType.RenderableComponent).ifPresent(RenderableComponent::propagateDirtyStateToParent); + } else if (keyboardCommand.getNanoTimedEvent().getEvent().getCode().equals(KeyCode.RIGHT)) { + physicsCoreComponent.setPositionX(physicsCoreComponent.getPositionX() - 5f); + this.getEntity().locateComponent(ComponentType.RenderableComponent).ifPresent(RenderableComponent::propagateDirtyStateToParent); + } else if (keyboardCommand.getNanoTimedEvent().getEvent().getCode().equals(KeyCode.UP)) { + physicsCoreComponent.setPositionY(physicsCoreComponent.getPositionY() + 5f); + this.getEntity().locateComponent(ComponentType.RenderableComponent).ifPresent(RenderableComponent::propagateDirtyStateToParent); + } else if (keyboardCommand.getNanoTimedEvent().getEvent().getCode().equals(KeyCode.DOWN)) { + physicsCoreComponent.setPositionY(physicsCoreComponent.getPositionY() - 5f); + this.getEntity().locateComponent(ComponentType.RenderableComponent).ifPresent(RenderableComponent::propagateDirtyStateToParent); + } + }); + } + case ScrollCommand scrollCommand -> { + // log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollCommand.getNanoTimedEvent().getEvent())); + // code to zoom in/out + } + default -> logInputCommand(inputCommand); + } + } + + private void logInputCommand(@NonNull final IsCommand inputCommand) { + switch (inputCommand) { + case MouseButtonCommand mouseButtonCommand -> + log.info("MouseButtonCommand received: {} (doubleClick: {})", mouseButtonCommand.getMouseButton(), mouseButtonCommand.isDoubleClick()); + case MouseDragCommand mouseDragCommand -> + log.info("MouseDragCommand received: {} ({})", mouseDragCommand.getMouseButton(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); + case ScrollCommand scrollCommand -> + log.info("ScrollCommand received: {} ({})", inputCommand.getClass().getSimpleName(), mapToScrollDirection(scrollCommand.getNanoTimedEvent().getEvent())); + case KeyboardCommand keyboardCommand -> + log.info("KeyboardCommand received: {} ({})", keyboardCommand.getNanoTimedEvent().getEvent().getEventType(), keyboardCommand.getNanoTimedEvent().getEvent().getCode()); + default -> + log.info("GenericInputCommand received: {} -> {}", inputCommand.getClass().getSimpleName(), inputCommand.getNanoTimedEvent().getEvent().getEventType()); } } From 2525901562313501b479349c3a5b758259ee99f7 Mon Sep 17 00:00:00 2001 From: Sven Carrillo Castillo Date: Sun, 28 Jan 2024 17:04:04 +0100 Subject: [PATCH 23/23] update todo --- TODO.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/TODO.md b/TODO.md index 36d3d286..b686e8b3 100644 --- a/TODO.md +++ b/TODO.md @@ -2,16 +2,9 @@ # 1 * new InputComponent interacting with MapComponent - * panning - * zooming + * panning (/) + * zooming (<-) * - * InputCommands (<-) - * MouseClick (/) - * MouseDrag (/) - * MouseWheel (/) - * Keyboard (/) - * PhysicsCore holds position in TransformComponent or Object (<-) - * Transform is modified when moved! * NULLImplementations -> Optionals ... *