From 10206fe5a4432ff37f9371c75e429f47d35e995d Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 11:37:11 +0200 Subject: [PATCH 001/447] Formatting files with scalafmt --- .../dev/atedeg/ecscalademo/ECSCanvas.scala | 80 +++++++++---------- .../atedeg/ecscalademo/SimulationStatus.scala | 4 +- .../dev/atedeg/ecscalademo/MathTest.scala | 16 ++-- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala index cd9916ae..cbbbffa7 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala @@ -1,40 +1,40 @@ -package dev.atedeg.ecscalademo - -import scalafx.scene.paint.Color -import scalafx.scene.shape.ArcType -import scalafx.scene.canvas.{ Canvas, GraphicsContext } - -trait ECSCanvas { - def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit - def drawLine(from: Point, to: Point, color: Color, lineWidth: Double): Unit - def clear(): Unit -} - -object ScalaFXCanvas { - def apply(canvas: Canvas): ECSCanvas = new ScalaFXCanvasImpl(canvas) - - private class ScalaFXCanvasImpl(canvas: Canvas) extends ECSCanvas { - private var graphicsContext: GraphicsContext = canvas.graphicsContext2D - - override def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit = { - graphicsContext.beginPath() - graphicsContext.arc(coordinates.x, coordinates.y, radius, radius, 0, 360) - graphicsContext.setFill(color) - graphicsContext.setStroke(Color.Black) - graphicsContext.lineWidth = lineWidth - graphicsContext.fill() - graphicsContext.stroke() - } - - override def drawLine(from: Point, to: Point, color: Color, lineWidth: Double): Unit = { - graphicsContext.beginPath() - graphicsContext.moveTo(from.x, from.y) - graphicsContext.lineTo(to.x, to.y) - graphicsContext.lineWidth = lineWidth - graphicsContext.setStroke(color) - graphicsContext.stroke() - } - - override def clear(): Unit = graphicsContext.clearRect(0, 0, canvas.getWidth, canvas.getHeight) - } -} +package dev.atedeg.ecscalademo + +import scalafx.scene.paint.Color +import scalafx.scene.shape.ArcType +import scalafx.scene.canvas.{ Canvas, GraphicsContext } + +trait ECSCanvas { + def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit + def drawLine(from: Point, to: Point, color: Color, lineWidth: Double): Unit + def clear(): Unit +} + +object ScalaFXCanvas { + def apply(canvas: Canvas): ECSCanvas = new ScalaFXCanvasImpl(canvas) + + private class ScalaFXCanvasImpl(canvas: Canvas) extends ECSCanvas { + private var graphicsContext: GraphicsContext = canvas.graphicsContext2D + + override def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit = { + graphicsContext.beginPath() + graphicsContext.arc(coordinates.x, coordinates.y, radius, radius, 0, 360) + graphicsContext.setFill(color) + graphicsContext.setStroke(Color.Black) + graphicsContext.lineWidth = lineWidth + graphicsContext.fill() + graphicsContext.stroke() + } + + override def drawLine(from: Point, to: Point, color: Color, lineWidth: Double): Unit = { + graphicsContext.beginPath() + graphicsContext.moveTo(from.x, from.y) + graphicsContext.lineTo(to.x, to.y) + graphicsContext.lineWidth = lineWidth + graphicsContext.setStroke(color) + graphicsContext.stroke() + } + + override def clear(): Unit = graphicsContext.clearRect(0, 0, canvas.getWidth, canvas.getHeight) + } +} diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index 1c0e6b83..ea826cb8 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -1,5 +1,7 @@ package dev.atedeg.ecscalademo +import dev.atedeg.ecscala.Entity + object MouseState { var coordinates = Point(0, 0) var clicked = false @@ -9,5 +11,5 @@ object MouseState { object PlayState { var playing = false - var selectedBall = Option.empty + var selectedBall: Option[Entity] = Option.empty } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala index 198234bf..394a22d2 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala @@ -28,17 +28,17 @@ class MathTest extends AnyWordSpec with Matchers { "return the correct result" in { Vector(1, 1) + Vector(2, 2) shouldBe Vector(3, 3) } - "subtracting another vector" should { - "return the correct result" in { - Vector(1, 1) - Vector(2, 2) shouldBe Vector(-1, -1) + "subtracting another vector" should { + "return the correct result" in { + Vector(1, 1) - Vector(2, 2) shouldBe Vector(-1, -1) + } } - } - "computing the dot product" should { - "return the correct result" in { - Vector(1, 2) dot Vector(3, 4) shouldBe 11 + "computing the dot product" should { + "return the correct result" in { + Vector(1, 2) dot Vector(3, 4) shouldBe 11 + } } } - } "inverted" should { "return the opposite vector" in { -Vector(1, 1) shouldBe Vector(-1, -1) From 8fcc3468265ac80a4b91bf6e2ca797d446c15a1a Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 11:37:34 +0200 Subject: [PATCH 002/447] Formatting files with scalafmt --- .../ecscalademo/controller/MainViewController.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 33c1484e..fd391c13 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -1,15 +1,15 @@ package dev.atedeg.ecscalademo.controller import dev.atedeg.ecscala.World -import dev.atedeg.ecscalademo.{ECSCanvas, MouseState, PlayState, Point, ScalaFXCanvas} -import javafx.fxml.{FXML, Initializable} +import dev.atedeg.ecscalademo.{ ECSCanvas, MouseState, PlayState, Point, ScalaFXCanvas } +import javafx.fxml.{ FXML, Initializable } import javafx.scene.control.Label as JfxLabel import javafx.scene.control.Button as JfxButton import javafx.scene.layout as jfx import javafx.scene.canvas.Canvas as JfxCanvas import javafx.scene.layout.Pane as JfxPane -import scalafx.scene.control.{Button, Label} -import scalafx.scene.canvas.{Canvas, GraphicsContext} +import scalafx.scene.control.{ Button, Label } +import scalafx.scene.canvas.{ Canvas, GraphicsContext } import scalafx.scene.paint.Color import scalafx.scene.layout.Pane import javafx.scene.input.MouseEvent From c168bd9188ec6a123f9188e92827f3a0a626af89 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 11:38:02 +0200 Subject: [PATCH 003/447] Add DragBallSystem --- .../ecscalademo/systems/DragBallSystem.scala | 17 +++++++ .../ecscalademo/fixture/WorldFixture.scala | 8 ++++ .../systems/DragBallSystemFixture.scala | 8 ++++ .../systems/DragBallSystemTest.scala | 45 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala new file mode 100644 index 00000000..027eb7d3 --- /dev/null +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -0,0 +1,17 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscala.* +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Position } + +class DragBallSystem extends EmptySystem { + + override def shouldRun: Boolean = !PlayState.playing && PlayState.selectedBall.isDefined && MouseState.clicked + + override def update(): Unit = { + PlayState.selectedBall match { + case Some(entity) => entity.addComponent(Position(MouseState.coordinates)) + case _ => () + } + } +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala new file mode 100644 index 00000000..0548c533 --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala @@ -0,0 +1,8 @@ +package dev.atedeg.ecscalademo.fixture + +import dev.atedeg.ecscala.{ Entity, World } + +trait WorldFixture { + lazy val world: World = World() + lazy val entity: Entity = world.createEntity() +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala new file mode 100644 index 00000000..4268271e --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala @@ -0,0 +1,8 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.Entity +import dev.atedeg.ecscalademo.fixture.WorldFixture + +trait DragBallSystemFixture extends WorldFixture { + lazy val dragBallSystem: DragBallSystem = DragBallSystem() +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala new file mode 100644 index 00000000..5ebd8e71 --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -0,0 +1,45 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.Entity +import dev.atedeg.ecscala.util.types +import dev.atedeg.ecscalademo.fixture.WorldFixture +import org.scalatest.wordspec.AnyWordSpec +import org.scalatest.matchers.should.Matchers +import dev.atedeg.ecscalademo.{ MouseState, PlayState } + +class DragBallSystemTest extends AnyWordSpec with Matchers { + + "A drag ball system" when { + "the game is running and the mouse is clicked" should { + "not run" in new DragBallSystemFixture { + PlayState.playing = true + MouseState.down = true + MouseState.clicked = true + dragBallSystem.shouldRun shouldBe false + + } + } + "the game is running and the mouse is not clicked" should { + "not run" in new DragBallSystemFixture { + PlayState.playing = true + MouseState.up = true + MouseState.clicked = false + dragBallSystem.shouldRun shouldBe false + } + } + "the game is not running and the mouse is clicked" should { + "run" in new DragBallSystemFixture { + PlayState.playing = false + PlayState.selectedBall = Some(entity) + MouseState.down = true + MouseState.clicked = true + dragBallSystem.shouldRun shouldBe true + } + "update the selected entity's position" in new DragBallSystemFixture { + PlayState.playing = false + PlayState.selectedBall = Some(entity) + } + } + //TODO cover other case test + } +} From c8f77bf3637370a1dce2bee1c459a92c6f4d6945 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 13:51:10 +0200 Subject: [PATCH 004/447] Add delta time and world reference to empty system --- core/src/main/scala/dev/atedeg/ecscala/System.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/dev/atedeg/ecscala/System.scala b/core/src/main/scala/dev/atedeg/ecscala/System.scala index 2f7f01bd..d36ab2ed 100644 --- a/core/src/main/scala/dev/atedeg/ecscala/System.scala +++ b/core/src/main/scala/dev/atedeg/ecscala/System.scala @@ -104,19 +104,22 @@ trait ExcludingSystem[LIncluded <: CList, LExcluded <: CList](using override protected def getView(world: World): View[LIncluded] = world.getView(using cltIncl, cltExcl) } +/** + * A [[System]] that not iterate over any [[Component]]. + */ trait EmptySystem extends System[CNil] { - def update(): Unit + def update(deltaTime: DeltaTime, world: World): Unit override final def update(entity: Entity, components: CNil)(deltaTime: DeltaTime, world: World, view: View[CNil]) = throw new IllegalStateException("An EmptySystem's update method should never be called.") - override final def before(deltaTime: DeltaTime, world: World, view: View[CNil]): Unit = update() + override final def before(deltaTime: DeltaTime, world: World, view: View[CNil]): Unit = update(deltaTime, world) override final def after(deltaTime: DeltaTime, world: World, view: View[CNil]): Unit = () } object EmptySystem { - def apply(f: () => Unit): EmptySystem = new EmptySystem { - override def update(): Unit = f() + def apply(f: (DeltaTime, World) => Unit): EmptySystem = new EmptySystem { + override def update(deltaTime: DeltaTime, world: World): Unit = f(deltaTime, world) } } From e65f16e5e06774e6113074d65de3a85e2e4617f7 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 17:58:58 +0200 Subject: [PATCH 005/447] Remove fixture and inseted inside test class --- .../ecscalademo/systems/DragBallSystemFixture.scala | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala deleted file mode 100644 index 4268271e..00000000 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemFixture.scala +++ /dev/null @@ -1,8 +0,0 @@ -package dev.atedeg.ecscalademo.systems - -import dev.atedeg.ecscala.Entity -import dev.atedeg.ecscalademo.fixture.WorldFixture - -trait DragBallSystemFixture extends WorldFixture { - lazy val dragBallSystem: DragBallSystem = DragBallSystem() -} From 5c9357180807b6adbde77f1b946ad309e1fd829e Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 17:59:49 +0200 Subject: [PATCH 006/447] Add a starting state --- .../scala/dev/atedeg/ecscalademo/SimulationStatus.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index ea826cb8..8b166c59 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -13,3 +13,9 @@ object PlayState { var playing = false var selectedBall: Option[Entity] = Option.empty } + +object StartingState { + val startingRadius: Double = 20.0 + val startingColor: Color = Color(255, 255, 0) + val startingMass: Double = 1 +} From d340f9e5466395aaf7e75490a95a9e563da98580 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 18:00:38 +0200 Subject: [PATCH 007/447] Update method sign according to new EmptySystem API --- .../scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala | 2 +- .../dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala index 027eb7d3..dc77662e 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -8,7 +8,7 @@ class DragBallSystem extends EmptySystem { override def shouldRun: Boolean = !PlayState.playing && PlayState.selectedBall.isDefined && MouseState.clicked - override def update(): Unit = { + override def update(deltaTime: DeltaTime, world: World): Unit = { PlayState.selectedBall match { case Some(entity) => entity.addComponent(Position(MouseState.coordinates)) case _ => () diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index 5ebd8e71..b495e51c 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -9,6 +9,10 @@ import dev.atedeg.ecscalademo.{ MouseState, PlayState } class DragBallSystemTest extends AnyWordSpec with Matchers { + trait DragBallSystemFixture extends WorldFixture { + lazy val dragBallSystem: DragBallSystem = DragBallSystem() + } + "A drag ball system" when { "the game is running and the mouse is clicked" should { "not run" in new DragBallSystemFixture { From f34fef21f7370e2c031dd896cac021f00efbe3e7 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 18:00:52 +0200 Subject: [PATCH 008/447] Add BallCreationSystem --- .../systems/BallCreationSystem.scala | 40 +++++++++++ .../systems/BallCreationSystemTest.scala | 72 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala new file mode 100644 index 00000000..f2120f1e --- /dev/null +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -0,0 +1,40 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscala.* +import dev.atedeg.ecscala.dsl.ECScalaDSL +import dev.atedeg.ecscalademo.{ + Circle, + Color, + Mass, + MouseState, + PlayState, + Point, + Position, + StartingState, + Vector, + Velocity, +} + +class BallCreationSystem extends EmptySystem with ECScalaDSL { + + override def shouldRun: Boolean = MouseState.clicked && !PlayState.playing + + override def update(deltaTime: DeltaTime, world: World): Unit = { + val canBeCreated = world.getView[Position &: Circle &: CNil] map (_._2) forall { cl => + val Position(point) &: Circle(radius, _) &: CNil = cl + !isOverlapped(point, radius) + } + if (canBeCreated) { + world hasAn entity withComponents { + Position(MouseState.coordinates) &: + Circle(StartingState.startingRadius, StartingState.startingColor) &: + Velocity(Vector(0, 0)) &: + Mass(StartingState.startingMass) + } + } + } + + private def isOverlapped(point: Point, radius: Double): Boolean = + (point - MouseState.coordinates).norm < (radius + StartingState.startingRadius) +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala new file mode 100644 index 00000000..9e73864f --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -0,0 +1,72 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscala.{ Entity, World } +import dev.atedeg.ecscalademo.fixture.WorldFixture +import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } +import org.scalatest.wordspec.AnyWordSpec +import org.scalatest.matchers.should.Matchers + +class BallCreationSystemTest extends AnyWordSpec with Matchers { + + trait BallCreationSystemFixture extends WorldFixture { + lazy val creationSystem: BallCreationSystem = BallCreationSystem() + } + + "A BallCreationSystem" when { + "the mouse is clicked and game not run" should { + "be executed" in new BallCreationSystemFixture { + enableSystemCondition + creationSystem.shouldRun shouldBe true + } + } + "the mouse is not clicked and game not run" should { + "not be executed" in new BallCreationSystemFixture { + disableSystemCondition + creationSystem.shouldRun shouldBe false + } + } + "enabled" should { + "create a ball in a free position" in new BallCreationSystemFixture { + enableSystemCondition + simulateCreateBall(world, entity, creationSystem, Point(0, 0), Point(100, 100)) + world.entitiesCount shouldBe 2 + } + "not create a ball over another one" in new BallCreationSystemFixture { + enableSystemCondition + simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(10, 10)) + world.entitiesCount shouldBe 1 + } + "not create a ball when the mouse is inside other ball" in new BallCreationSystemFixture { + enableSystemCondition + simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(15, 15)) + world.entitiesCount shouldBe 1 + } + } + } + + private def enableSystemCondition: Unit = { + PlayState.playing = false + MouseState.clicked = true + } + + private def disableSystemCondition: Unit = { + PlayState.playing = false + MouseState.clicked = false + } + + private def simulateCreateBall( + world: World, + existingEntity: Entity, + system: BallCreationSystem, + existingPosition: Point, + mousePosition: Point, + ): Unit = { + existingEntity.addComponent(Position(existingPosition)) + existingEntity.addComponent(Circle(StartingState.startingRadius, StartingState.startingColor)) + world.update(10) + MouseState.coordinates = mousePosition + world.addSystem(system) + world.update(10) + } +} From 94b29ab1623f907225983f0a1825a32a8f0ef506 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 18:33:21 +0200 Subject: [PATCH 009/447] Add BallCreationRenderingSystem --- .../systems/BallCreationRenderingSystem.scala | 19 ++++++++++++ .../BallCreationRenderingSystemTest.scala | 31 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala new file mode 100644 index 00000000..e08c4778 --- /dev/null +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -0,0 +1,19 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.* +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.* +import scalafx.scene.paint.Color as SfxColor + +import scala.language.implicitConversions + +class BallCreationRenderingSystem(canvas: ECSCanvas) extends EmptySystem { + + given Conversion[Color, SfxColor] with + def apply(color: Color): SfxColor = SfxColor(color.r, color.g, color.b, 1) + + override def shouldRun: Boolean = !PlayState.playing + + override def update(deltaTime: DeltaTime, world: World): Unit = + canvas.drawCircle(MouseState.coordinates, StartingState.startingRadius, StartingState.startingColor, 1) +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala new file mode 100644 index 00000000..abf45a7c --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -0,0 +1,31 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscalademo.{ PlayState, ScalaFXCanvas } +import dev.atedeg.ecscalademo.fixture.WorldFixture +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec +import scalafx.scene.canvas.Canvas +import javafx.scene.canvas.Canvas as JfxCanvas + +class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers { + + trait BallCreationRenderingSystemFixture extends WorldFixture { + lazy val system = BallCreationRenderingSystem(ScalaFXCanvas(new Canvas(new JfxCanvas()))) + } + + "A RenderingCreationBallSystem" when { + "the game is run" should { + "enabled" in new BallCreationRenderingSystemFixture { + enableSystemCondition + system.shouldRun shouldBe true + } + "disabled" in new BallCreationRenderingSystemFixture { + disableSystemCondition + system.shouldRun shouldBe false + } + } + } + + private def enableSystemCondition: Unit = PlayState.playing = false + private def disableSystemCondition: Unit = PlayState.playing = true +} From 9e07e250eb6ce3ffa884f8e5ffe6e704c0819fba Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 19:10:49 +0200 Subject: [PATCH 010/447] Add BallSelectionSystem --- .../systems/BallSelectionSystem.scala | 23 +++++++ .../systems/BallSelectionSystemTest.scala | 69 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala create mode 100644 demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala new file mode 100644 index 00000000..eb7ca782 --- /dev/null +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -0,0 +1,23 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscala.* +import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } + +class BallSelectionSystem extends EmptySystem { + + override def shouldRun: Boolean = !PlayState.playing && MouseState.down + + override def update(deltaTime: DeltaTime, world: World): Unit = { + val entitySelected: Option[Entity] = world.getView[Position &: Circle &: CNil] find { e => + val Position(point) &: Circle(radius, _) &: CNil = e._2 + isOverlapped(point, radius) + } map (_._1) + + if (entitySelected.isEmpty) then PlayState.selectedBall = None + else PlayState.selectedBall = Some(entitySelected.get) + } + + private def isOverlapped(point: Point, radius: Double): Boolean = + (MouseState.coordinates - point).norm < (radius + StartingState.startingRadius) +} diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala new file mode 100644 index 00000000..e3fefb11 --- /dev/null +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -0,0 +1,69 @@ +package dev.atedeg.ecscalademo.systems + +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } +import dev.atedeg.ecscalademo.fixture.WorldFixture +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec + +class BallSelectionSystemTest extends AnyWordSpec with Matchers { + + trait BallSelectionSystemFixture extends WorldFixture { + lazy val system = BallSelectionSystem() + } + + "A BallSelectionSystem" when { + "the game is paused and the mouse is clicked" should { + "be enabled" in new BallSelectionSystemFixture { + enableSystemCondition + system.shouldRun shouldBe true + } + } + "the game is paused and the mouse is not clicked" should { + "not be enabled" in new BallSelectionSystemFixture { + disableSystemCondition + system.shouldRun shouldBe false + } + } + "the game is running" should { + "not enabled" in new BallSelectionSystemFixture { + PlayState.playing = true + system.shouldRun shouldBe false + } + } + "a ball is selected" should { + "set the ball as current selected" in new BallSelectionSystemFixture { + enableSystemCondition + val entity1 = world.createEntity() + val entity2 = world.createEntity() + entity1.addComponent(Position(Point(10, 10))) + entity1.addComponent(Circle(20, StartingState.startingColor)) + + entity2.addComponent(Position(Point(70, 70))) + entity2.addComponent(Circle(20, StartingState.startingColor)) + + world.addSystem(system) + PlayState.selectedBall shouldBe None + MouseState.coordinates = Point(10, 10) + world.update(10) + + PlayState.selectedBall shouldBe Some(entity1) + + MouseState.coordinates = Point(65, 65) + world.update(10) + + PlayState.selectedBall shouldBe Some(entity2) + } + } + } + + private def enableSystemCondition: Unit = { + PlayState.playing = false + MouseState.down = true + } + + private def disableSystemCondition: Unit = { + PlayState.playing = false + MouseState.down = false + } +} From 4862e55f1a54b81d27cff8db426c37fb1cd02226 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Fri, 24 Sep 2021 19:23:56 +0200 Subject: [PATCH 011/447] Fix Empty system API --- core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala | 2 +- .../atedeg/ecscalademo/systems/BallSelectionSystemTest.scala | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala b/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala index 8ac25db3..4495505a 100644 --- a/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala +++ b/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala @@ -139,7 +139,7 @@ class SystemTest extends AnyWordSpec with Matchers { "An EmptySystem" should { "execute its update" in new ViewFixture { var success = false - world.addSystem(EmptySystem(() => success = true)) + world.addSystem(EmptySystem((dt, w) => success = true)) world.update(10) success shouldBe true } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index e3fefb11..d2dcdd35 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -34,6 +34,8 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { "a ball is selected" should { "set the ball as current selected" in new BallSelectionSystemFixture { enableSystemCondition + PlayState.selectedBall = None + val entity1 = world.createEntity() val entity2 = world.createEntity() entity1.addComponent(Position(Point(10, 10))) From 936f84af4acef2d6405d2ba806d8e0ebd264a2ad Mon Sep 17 00:00:00 2001 From: ndido98 Date: Fri, 24 Sep 2021 23:22:57 +0200 Subject: [PATCH 012/447] Add mockito --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 2132a98f..f60fad96 100644 --- a/build.sbt +++ b/build.sbt @@ -183,6 +183,7 @@ lazy val demo = project assembly / assemblyJarName := "ECScalaDemo.jar", githubWorkflowArtifactUpload := false, libraryDependencies ++= scalaTest, + libraryDependencies += "org.scalatestplus" %% "mockito-3-12" % "3.2.10.0" % "test", libraryDependencies += "org.scalafx" %% "scalafx" % "16.0.0-R24", libraryDependencies ++= javaFXModules.map(m => "org.openjfx" % s"javafx-$m" % "16" classifier osName), ) From 36cf028eef6e65f527e4a64da7c552ab96663e2e Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 08:53:08 +0200 Subject: [PATCH 013/447] Add private keyword to constructor. Add alpha channel to 0.5 --- .../ecscalademo/systems/BallCreationRenderingSystem.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala index e08c4778..a5c9d936 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -7,10 +7,10 @@ import scalafx.scene.paint.Color as SfxColor import scala.language.implicitConversions -class BallCreationRenderingSystem(canvas: ECSCanvas) extends EmptySystem { +class BallCreationRenderingSystem(private val canvas: ECSCanvas) extends EmptySystem { given Conversion[Color, SfxColor] with - def apply(color: Color): SfxColor = SfxColor(color.r, color.g, color.b, 1) + def apply(color: Color): SfxColor = SfxColor(color.r, color.g, color.b, 0.5) override def shouldRun: Boolean = !PlayState.playing From 528acb7456ea6ed00a5cab051c8c3e9246968287 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 09:04:57 +0200 Subject: [PATCH 014/447] Add scaladoc to the systems --- .../ecscalademo/systems/BallCreationRenderingSystem.scala | 5 +++++ .../dev/atedeg/ecscalademo/systems/BallCreationSystem.scala | 4 ++++ .../dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala | 4 ++++ .../dev/atedeg/ecscalademo/systems/DragBallSystem.scala | 3 +++ 4 files changed, 16 insertions(+) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala index a5c9d936..d676e14c 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -7,6 +7,11 @@ import scalafx.scene.paint.Color as SfxColor import scala.language.implicitConversions +/** + * This [[System]] is used to render the ball that is about to be added to the [[World]]. + * @param canvas + * the canvas to draw in. + */ class BallCreationRenderingSystem(private val canvas: ECSCanvas) extends EmptySystem { given Conversion[Color, SfxColor] with diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index f2120f1e..38a7bc08 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -16,6 +16,10 @@ import dev.atedeg.ecscalademo.{ Velocity, } +/** + * This [[System]] is used to create a new ball into the [[World]]. If the mouse pointer is in the area of another ball, + * no ball will be added. + */ class BallCreationSystem extends EmptySystem with ECScalaDSL { override def shouldRun: Boolean = MouseState.clicked && !PlayState.playing diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index eb7ca782..d5ee4d52 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -4,6 +4,10 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.* import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } +/** + * This [[System]] is used to identify the selected ball. If a ball were selected, the [[PlayState.selectedBall]] + * contains the [[Entity]] associated to the selected ball. + */ class BallSelectionSystem extends EmptySystem { override def shouldRun: Boolean = !PlayState.playing && MouseState.down diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala index dc77662e..1a6b864f 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -4,6 +4,9 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.* import dev.atedeg.ecscalademo.{ MouseState, PlayState, Position } +/** + * This [[System]] is used to update selected ball's position according to the mouse pointer. + */ class DragBallSystem extends EmptySystem { override def shouldRun: Boolean = !PlayState.playing && PlayState.selectedBall.isDefined && MouseState.clicked From e0a198f8b5e1da4bdb54c0cbc8b7afbfad8014a2 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 16:21:55 +0200 Subject: [PATCH 015/447] Add brace to enable/disable condition method --- .../systems/BallCreationRenderingSystemTest.scala | 8 ++++---- .../systems/BallCreationSystemTest.scala | 14 +++++++------- .../systems/BallSelectionSystemTest.scala | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index abf45a7c..1f9c3d94 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -16,16 +16,16 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers { "A RenderingCreationBallSystem" when { "the game is run" should { "enabled" in new BallCreationRenderingSystemFixture { - enableSystemCondition + enableSystemCondition() system.shouldRun shouldBe true } "disabled" in new BallCreationRenderingSystemFixture { - disableSystemCondition + disableSystemCondition() system.shouldRun shouldBe false } } } - private def enableSystemCondition: Unit = PlayState.playing = false - private def disableSystemCondition: Unit = PlayState.playing = true + private def enableSystemCondition(): Unit = PlayState.playing = false + private def disableSystemCondition(): Unit = PlayState.playing = true } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index 9e73864f..fcc90804 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -16,41 +16,41 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { "A BallCreationSystem" when { "the mouse is clicked and game not run" should { "be executed" in new BallCreationSystemFixture { - enableSystemCondition + enableSystemCondition() creationSystem.shouldRun shouldBe true } } "the mouse is not clicked and game not run" should { "not be executed" in new BallCreationSystemFixture { - disableSystemCondition + disableSystemCondition() creationSystem.shouldRun shouldBe false } } "enabled" should { "create a ball in a free position" in new BallCreationSystemFixture { - enableSystemCondition + enableSystemCondition() simulateCreateBall(world, entity, creationSystem, Point(0, 0), Point(100, 100)) world.entitiesCount shouldBe 2 } "not create a ball over another one" in new BallCreationSystemFixture { - enableSystemCondition + enableSystemCondition() simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(10, 10)) world.entitiesCount shouldBe 1 } "not create a ball when the mouse is inside other ball" in new BallCreationSystemFixture { - enableSystemCondition + enableSystemCondition() simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(15, 15)) world.entitiesCount shouldBe 1 } } } - private def enableSystemCondition: Unit = { + private def enableSystemCondition(): Unit = { PlayState.playing = false MouseState.clicked = true } - private def disableSystemCondition: Unit = { + private def disableSystemCondition(): Unit = { PlayState.playing = false MouseState.clicked = false } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index d2dcdd35..a445397d 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -15,25 +15,25 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { "A BallSelectionSystem" when { "the game is paused and the mouse is clicked" should { "be enabled" in new BallSelectionSystemFixture { - enableSystemCondition + enableSystemCondition() system.shouldRun shouldBe true } } "the game is paused and the mouse is not clicked" should { "not be enabled" in new BallSelectionSystemFixture { - disableSystemCondition + disableSystemCondition() system.shouldRun shouldBe false } } "the game is running" should { - "not enabled" in new BallSelectionSystemFixture { + "not be enabled" in new BallSelectionSystemFixture { PlayState.playing = true system.shouldRun shouldBe false } } "a ball is selected" should { "set the ball as current selected" in new BallSelectionSystemFixture { - enableSystemCondition + enableSystemCondition() PlayState.selectedBall = None val entity1 = world.createEntity() @@ -59,12 +59,12 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { } } - private def enableSystemCondition: Unit = { + private def enableSystemCondition(): Unit = { PlayState.playing = false MouseState.down = true } - private def disableSystemCondition: Unit = { + private def disableSystemCondition(): Unit = { PlayState.playing = false MouseState.down = false } From d0b3302d66a6dde778c00e61b40277e0f0f092f4 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 16:23:35 +0200 Subject: [PATCH 016/447] Add more test to test update the position of selected entity --- .../systems/DragBallSystemTest.scala | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index b495e51c..4c25a88c 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -1,11 +1,14 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.Entity +import dev.atedeg.ecscalademo.Position import dev.atedeg.ecscala.util.types +import dev.atedeg.ecscalademo import dev.atedeg.ecscalademo.fixture.WorldFixture import org.scalatest.wordspec.AnyWordSpec import org.scalatest.matchers.should.Matchers -import dev.atedeg.ecscalademo.{ MouseState, PlayState } +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point } class DragBallSystemTest extends AnyWordSpec with Matchers { @@ -44,6 +47,25 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { PlayState.selectedBall = Some(entity) } } - //TODO cover other case test + "enabled" should { + "update the selectes entity's position" in new DragBallSystemFixture { + entity.addComponent(Position(Point(0, 0))) + entity.getComponent[Position] match { + case Some(position) => position + case _ => fail("A component should beee defined") + } shouldBe Position(Point(0, 0)) + + PlayState.selectedBall = Some(entity) + MouseState.coordinates = Point(10, 10) + + world.addSystem(dragBallSystem) + world.update(10) + + entity.getComponent[Position] match { + case Some(position) => position + case _ => fail("A component should been defined") + } shouldBe Position(Point(10, 10)) + } + } } } From f4141547b9fac98136eeb9796aab09f00ba79b80 Mon Sep 17 00:00:00 2001 From: ndido98 Date: Thu, 23 Sep 2021 19:06:34 +0200 Subject: [PATCH 017/447] Add implicit conversions from tuple to point/vector --- .../main/scala/dev/atedeg/ecscalademo/Math.scala | 4 ++++ .../scala/dev/atedeg/ecscalademo/MathTest.scala | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala index f391958b..4aa48121 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala @@ -6,6 +6,8 @@ case class Point(x: Double, y: Double) { def -(point: Point) = Vector(x - point.x, y - point.y) } +given Conversion[(Double, Double), Point] = tuple => Point(tuple._1, tuple._2) + case class Vector(x: Double, y: Double) { def +(vector: Vector) = Vector(x + vector.x, y + vector.y) def -(vector: Vector) = Vector(x - vector.x, y - vector.y) @@ -18,6 +20,8 @@ case class Vector(x: Double, y: Double) { def normalized = this / norm } +given Conversion[(Double, Double), Vector] = tuple => Vector(tuple._1, tuple._2) + extension (scalar: Double) { def *(vector: Vector) = vector * scalar } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala index 394a22d2..12a624c1 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala @@ -80,4 +80,17 @@ class MathTest extends AnyWordSpec with Matchers { 0.clamped(10, 20) shouldBe 10 } } + + "A (Double, Double) tuple" can { + import scala.language.implicitConversions + import dev.atedeg.ecscalademo.given + "be converted to a vector" in { + val vector: Vector = (10.0, 20.0) + vector shouldBe Vector(10, 20) + } + "be converted to a point" in { + val point: Point = (10.0, 20.0) + point shouldBe Point(10, 20) + } + } } From f85fc122557daa7333af82fa0187b1f0652755a0 Mon Sep 17 00:00:00 2001 From: ndido98 Date: Thu, 23 Sep 2021 19:28:44 +0200 Subject: [PATCH 018/447] Add clamped overload to support two-element tuples as bounds --- demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala | 3 ++- demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala index 4aa48121..4548c421 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/Math.scala @@ -28,6 +28,7 @@ extension (scalar: Double) { extension [T](element: T)(using ord: Ordering[T]) { - def clamped(lowerBound: T, upperBound: T) = + def clamped(lowerBound: T, upperBound: T): T = if ord.gt(element, upperBound) then upperBound else if ord.lt(element, lowerBound) then lowerBound else element + def clamped(bounds: (T, T)): T = clamped(bounds._1, bounds._2) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala index 12a624c1..be238bbe 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/MathTest.scala @@ -75,9 +75,9 @@ class MathTest extends AnyWordSpec with Matchers { "A number" can { "be clamped between a minimum and a maximum" in { - 5.clamped(1, 10) shouldBe 5 - 10.clamped(2, 5) shouldBe 5 - 0.clamped(10, 20) shouldBe 10 + 5 clamped (1, 10) shouldBe 5 + 10 clamped (2, 5) shouldBe 5 + 0 clamped (10, 20) shouldBe 10 } } From a08b7b08a29544dd99dcbf8aa7f95b91f8c07d32 Mon Sep 17 00:00:00 2001 From: ndido98 Date: Thu, 23 Sep 2021 19:29:22 +0200 Subject: [PATCH 019/447] Fix fixture path --- .../dev/atedeg/ecscalademo/Components.scala | 16 ++++++++++++++-- .../{fixture => fixtures}/WorldFixture.scala | 2 +- .../BallCreationRenderingSystemTest.scala | 2 +- .../systems/BallCreationSystemTest.scala | 2 +- .../systems/BallSelectionSystemTest.scala | 2 +- .../ecscalademo/systems/DragBallSystemTest.scala | 2 +- 6 files changed, 19 insertions(+), 7 deletions(-) rename demo/src/test/scala/dev/atedeg/ecscalademo/{fixture => fixtures}/WorldFixture.scala (79%) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala index 83efb491..c4940a57 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala @@ -8,7 +8,19 @@ case class Color(r: Int, g: Int, b: Int) { require(b >= 0 && b <= 255) } -case class Position(position: Point) extends Component -case class Velocity(velocity: Vector) extends Component +case class Position(position: Point) extends Component { + def x: Double = position.x + def y: Double = position.y +} + +given Conversion[Position, Point] = _.position + +case class Velocity(velocity: Vector) extends Component { + def x: Double = velocity.x + def y: Double = velocity.y +} + +given Conversion[Velocity, Vector] = _.velocity + case class Circle(radius: Double, color: Color) extends Component case class Mass(mass: Double) extends Component diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WorldFixture.scala similarity index 79% rename from demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala rename to demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WorldFixture.scala index 0548c533..e98ea448 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixture/WorldFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WorldFixture.scala @@ -1,4 +1,4 @@ -package dev.atedeg.ecscalademo.fixture +package dev.atedeg.ecscalademo.fixtures import dev.atedeg.ecscala.{ Entity, World } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index 1f9c3d94..b93b3e3c 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -1,7 +1,7 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ PlayState, ScalaFXCanvas } -import dev.atedeg.ecscalademo.fixture.WorldFixture import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import scalafx.scene.canvas.Canvas diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index fcc90804..05e7adae 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -2,7 +2,7 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.{ Entity, World } -import dev.atedeg.ecscalademo.fixture.WorldFixture +import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } import org.scalatest.wordspec.AnyWordSpec import org.scalatest.matchers.should.Matchers diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index a445397d..5b1625d2 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -1,8 +1,8 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } -import dev.atedeg.ecscalademo.fixture.WorldFixture import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index 4c25a88c..8fe7f790 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -5,7 +5,7 @@ import dev.atedeg.ecscala.Entity import dev.atedeg.ecscalademo.Position import dev.atedeg.ecscala.util.types import dev.atedeg.ecscalademo -import dev.atedeg.ecscalademo.fixture.WorldFixture +import dev.atedeg.ecscalademo.fixtures.WorldFixture import org.scalatest.wordspec.AnyWordSpec import org.scalatest.matchers.should.Matchers import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point } From ae89d5015f344d3567e4e48f234ba1dc7dd4bf1b Mon Sep 17 00:00:00 2001 From: Linda Vitali Date: Thu, 23 Sep 2021 18:04:21 +0200 Subject: [PATCH 020/447] Update color class --- .../main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala index cbbbffa7..d72842b6 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/ECSCanvas.scala @@ -1,9 +1,11 @@ package dev.atedeg.ecscalademo -import scalafx.scene.paint.Color +import scalafx.scene.paint.Color as ColorFx import scalafx.scene.shape.ArcType import scalafx.scene.canvas.{ Canvas, GraphicsContext } +import dev.atedeg.ecscalademo.Color + trait ECSCanvas { def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit def drawLine(from: Point, to: Point, color: Color, lineWidth: Double): Unit @@ -19,8 +21,8 @@ object ScalaFXCanvas { override def drawCircle(coordinates: Point, radius: Double, color: Color, lineWidth: Double): Unit = { graphicsContext.beginPath() graphicsContext.arc(coordinates.x, coordinates.y, radius, radius, 0, 360) - graphicsContext.setFill(color) - graphicsContext.setStroke(Color.Black) + graphicsContext.setFill(ColorFx.rgb(color.r, color.g, color.b)) + graphicsContext.setStroke(ColorFx.Black) graphicsContext.lineWidth = lineWidth graphicsContext.fill() graphicsContext.stroke() @@ -31,7 +33,7 @@ object ScalaFXCanvas { graphicsContext.moveTo(from.x, from.y) graphicsContext.lineTo(to.x, to.y) graphicsContext.lineWidth = lineWidth - graphicsContext.setStroke(color) + graphicsContext.setStroke(ColorFx.rgb(color.r, color.g, color.b)) graphicsContext.stroke() } From b3693743c08ae740bd18c289c4aa6df95cabb069 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 17:14:57 +0200 Subject: [PATCH 021/447] Use implicit for Tuple to Point conversion --- .../ecscalademo/systems/BallCreationSystemTest.scala | 6 +++--- .../ecscalademo/systems/BallSelectionSystemTest.scala | 10 ++++++---- .../ecscalademo/systems/DragBallSystemTest.scala | 8 +++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index 05e7adae..63891cf3 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -29,17 +29,17 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { "enabled" should { "create a ball in a free position" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(0, 0), Point(100, 100)) + simulateCreateBall(world, entity, creationSystem, Point(0.0, 0.0), Point(100.0, 100.0)) world.entitiesCount shouldBe 2 } "not create a ball over another one" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(10, 10)) + simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0)) world.entitiesCount shouldBe 1 } "not create a ball when the mouse is inside other ball" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(10, 10), Point(15, 15)) + simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0)) world.entitiesCount shouldBe 1 } } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index 5b1625d2..c3243f46 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -1,6 +1,8 @@ package dev.atedeg.ecscalademo.systems +import scala.language.implicitConversions import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } import org.scalatest.matchers.should.Matchers @@ -38,20 +40,20 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { val entity1 = world.createEntity() val entity2 = world.createEntity() - entity1.addComponent(Position(Point(10, 10))) + entity1.addComponent(Position(10.0, 10.0)) entity1.addComponent(Circle(20, StartingState.startingColor)) - entity2.addComponent(Position(Point(70, 70))) + entity2.addComponent(Position(70.0, 70.0)) entity2.addComponent(Circle(20, StartingState.startingColor)) world.addSystem(system) PlayState.selectedBall shouldBe None - MouseState.coordinates = Point(10, 10) + MouseState.coordinates = Point(10.0, 10.0) world.update(10) PlayState.selectedBall shouldBe Some(entity1) - MouseState.coordinates = Point(65, 65) + MouseState.coordinates = Point(65.0, 65.0) world.update(10) PlayState.selectedBall shouldBe Some(entity2) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index 8fe7f790..e62524f4 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -1,5 +1,6 @@ package dev.atedeg.ecscalademo.systems +import scala.language.implicitConversions import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.Entity import dev.atedeg.ecscalademo.Position @@ -9,6 +10,7 @@ import dev.atedeg.ecscalademo.fixtures.WorldFixture import org.scalatest.wordspec.AnyWordSpec import org.scalatest.matchers.should.Matchers import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point } +import dev.atedeg.ecscalademo.given class DragBallSystemTest extends AnyWordSpec with Matchers { @@ -49,14 +51,14 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { } "enabled" should { "update the selectes entity's position" in new DragBallSystemFixture { - entity.addComponent(Position(Point(0, 0))) + entity.addComponent(Position(0.0, 0.0)) entity.getComponent[Position] match { case Some(position) => position case _ => fail("A component should beee defined") } shouldBe Position(Point(0, 0)) PlayState.selectedBall = Some(entity) - MouseState.coordinates = Point(10, 10) + MouseState.coordinates = Point(10.0, 10.0) world.addSystem(dragBallSystem) world.update(10) @@ -64,7 +66,7 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { entity.getComponent[Position] match { case Some(position) => position case _ => fail("A component should been defined") - } shouldBe Position(Point(10, 10)) + } shouldBe Position(10.0, 10.0) } } } From cf6e6396f1c14f4c6d4fab091591885427a3e467 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 17:43:11 +0200 Subject: [PATCH 022/447] Removed no more necessary conversion --- .../ecscalademo/systems/BallCreationRenderingSystem.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala index d676e14c..6bb3de92 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -14,9 +14,6 @@ import scala.language.implicitConversions */ class BallCreationRenderingSystem(private val canvas: ECSCanvas) extends EmptySystem { - given Conversion[Color, SfxColor] with - def apply(color: Color): SfxColor = SfxColor(color.r, color.g, color.b, 0.5) - override def shouldRun: Boolean = !PlayState.playing override def update(deltaTime: DeltaTime, world: World): Unit = From f364c9de880ddf8f4a04f57c85ca0e60000c6e95 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 17:43:38 +0200 Subject: [PATCH 023/447] Add test to check the drawCircle method with mock --- .../BallCreationRenderingSystemTest.scala | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index b93b3e3c..72c3df65 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -1,16 +1,21 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.fixtures.WorldFixture -import dev.atedeg.ecscalademo.{ PlayState, ScalaFXCanvas } +import dev.atedeg.ecscalademo.{ ECSCanvas, PlayState, ScalaFXCanvas } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import scalafx.scene.canvas.Canvas import javafx.scene.canvas.Canvas as JfxCanvas +import org.mockito.ArgumentMatchers.{ any, anyDouble, anyObject } +import org.scalatestplus.mockito.MockitoSugar +import org.mockito.Mockito.* -class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers { +class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with MockitoSugar { trait BallCreationRenderingSystemFixture extends WorldFixture { - lazy val system = BallCreationRenderingSystem(ScalaFXCanvas(new Canvas(new JfxCanvas()))) + val canvasMock = mock[ECSCanvas] + lazy val system = BallCreationRenderingSystem(canvasMock) } "A RenderingCreationBallSystem" when { @@ -19,6 +24,12 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers { enableSystemCondition() system.shouldRun shouldBe true } + "render the ball" in new BallCreationRenderingSystemFixture { + PlayState.playing = false + world.addSystem(system) + world.update(10) + verify(canvasMock).drawCircle(any(), anyDouble(), any(), anyDouble()) + } "disabled" in new BallCreationRenderingSystemFixture { disableSystemCondition() system.shouldRun shouldBe false From 5442fae1b12b8f8e98ba7322ec1a2f8c0e8d0bf9 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 17:48:12 +0200 Subject: [PATCH 024/447] Refactor import --- .../ecscalademo/systems/BallCreationRenderingSystemTest.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index 72c3df65..e35b13ba 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -7,9 +7,9 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import scalafx.scene.canvas.Canvas import javafx.scene.canvas.Canvas as JfxCanvas -import org.mockito.ArgumentMatchers.{ any, anyDouble, anyObject } +import org.mockito.ArgumentMatchers.{ any, anyDouble } import org.scalatestplus.mockito.MockitoSugar -import org.mockito.Mockito.* +import org.mockito.Mockito.verify class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with MockitoSugar { From 9f081ab028a51466148b9eac64f7bb64de79953a Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sat, 25 Sep 2021 18:08:13 +0200 Subject: [PATCH 025/447] Optimize import --- .../ecscalademo/systems/BallCreationSystem.scala | 15 ++------------- .../ecscalademo/systems/BallSelectionSystem.scala | 4 ++-- .../ecscalademo/systems/DragBallSystem.scala | 2 +- .../systems/BallCreationRenderingSystemTest.scala | 10 +++++----- .../systems/BallCreationSystemTest.scala | 4 ++-- .../systems/BallSelectionSystemTest.scala | 9 +++++---- .../ecscalademo/systems/DragBallSystemTest.scala | 14 ++++++-------- 7 files changed, 23 insertions(+), 35 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index 38a7bc08..2dae907c 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -1,20 +1,9 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.* import dev.atedeg.ecscala.dsl.ECScalaDSL -import dev.atedeg.ecscalademo.{ - Circle, - Color, - Mass, - MouseState, - PlayState, - Point, - Position, - StartingState, - Vector, - Velocity, -} +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.* /** * This [[System]] is used to create a new ball into the [[World]]. If the mouse pointer is in the area of another ball, diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index d5ee4d52..63ec087a 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -1,8 +1,8 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.* -import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.* /** * This [[System]] is used to identify the selected ball. If a ball were selected, the [[PlayState.selectedBall]] diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala index 1a6b864f..c7ce3451 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -1,7 +1,7 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.* +import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.{ MouseState, PlayState, Position } /** diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index e35b13ba..19b86df9 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -1,15 +1,15 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscala.util.types import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ ECSCanvas, PlayState, ScalaFXCanvas } -import org.scalatest.matchers.should.Matchers -import org.scalatest.wordspec.AnyWordSpec -import scalafx.scene.canvas.Canvas import javafx.scene.canvas.Canvas as JfxCanvas import org.mockito.ArgumentMatchers.{ any, anyDouble } -import org.scalatestplus.mockito.MockitoSugar import org.mockito.Mockito.verify +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec +import org.scalatestplus.mockito.MockitoSugar +import scalafx.scene.canvas.Canvas class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with MockitoSugar { diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index 63891cf3..b96eb020 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -3,9 +3,9 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.{ Entity, World } import dev.atedeg.ecscalademo.fixtures.WorldFixture -import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } -import org.scalatest.wordspec.AnyWordSpec +import dev.atedeg.ecscalademo.* import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec class BallCreationSystemTest extends AnyWordSpec with Matchers { diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index c3243f46..fe638ac1 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -1,13 +1,14 @@ package dev.atedeg.ecscalademo.systems -import scala.language.implicitConversions -import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.given +import dev.atedeg.ecscala.util.types +import dev.atedeg.ecscalademo import dev.atedeg.ecscalademo.fixtures.WorldFixture -import dev.atedeg.ecscalademo.{ Circle, MouseState, PlayState, Point, Position, StartingState } +import dev.atedeg.ecscalademo.* import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec +import scala.language.implicitConversions + class BallSelectionSystemTest extends AnyWordSpec with Matchers { trait BallSelectionSystemFixture extends WorldFixture { diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index e62524f4..afb9a8b0 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -1,16 +1,14 @@ package dev.atedeg.ecscalademo.systems -import scala.language.implicitConversions -import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.Entity -import dev.atedeg.ecscalademo.Position -import dev.atedeg.ecscala.util.types -import dev.atedeg.ecscalademo +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.WorldFixture -import org.scalatest.wordspec.AnyWordSpec +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Position } import org.scalatest.matchers.should.Matchers -import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point } -import dev.atedeg.ecscalademo.given +import org.scalatest.wordspec.AnyWordSpec + +import scala.language.implicitConversions class DragBallSystemTest extends AnyWordSpec with Matchers { From aa9acb989a783f3dcb8811e98cd172a190ee9d9f Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:41:43 +0200 Subject: [PATCH 026/447] Restore missing given --- .../ecscalademo/systems/BallCreationRenderingSystemTest.scala | 2 +- .../atedeg/ecscalademo/systems/BallSelectionSystemTest.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index 19b86df9..c0ffdd87 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -1,6 +1,6 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types +import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ ECSCanvas, PlayState, ScalaFXCanvas } import javafx.scene.canvas.Canvas as JfxCanvas diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index fe638ac1..a214a743 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -1,7 +1,7 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.util.types -import dev.atedeg.ecscalademo +import dev.atedeg.ecscala.util.types.given +import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.* import org.scalatest.matchers.should.Matchers From 04e5fefa75d059ae39eec641522e27795d6a146b Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:42:47 +0200 Subject: [PATCH 027/447] Update core/src/main/scala/dev/atedeg/ecscala/System.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- core/src/main/scala/dev/atedeg/ecscala/System.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/dev/atedeg/ecscala/System.scala b/core/src/main/scala/dev/atedeg/ecscala/System.scala index d36ab2ed..07b9e5bd 100644 --- a/core/src/main/scala/dev/atedeg/ecscala/System.scala +++ b/core/src/main/scala/dev/atedeg/ecscala/System.scala @@ -105,7 +105,7 @@ trait ExcludingSystem[LIncluded <: CList, LExcluded <: CList](using } /** - * A [[System]] that not iterate over any [[Component]]. + * A [[System]] that does not iterate over any [[Component]]. */ trait EmptySystem extends System[CNil] { def update(deltaTime: DeltaTime, world: World): Unit From a93c0d09bfe4b91485dd42601a0799c1e1bdd375 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:43:19 +0200 Subject: [PATCH 028/447] Update core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala b/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala index 4495505a..e59a482f 100644 --- a/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala +++ b/core/src/test/scala/dev/atedeg/ecscala/SystemTest.scala @@ -139,7 +139,7 @@ class SystemTest extends AnyWordSpec with Matchers { "An EmptySystem" should { "execute its update" in new ViewFixture { var success = false - world.addSystem(EmptySystem((dt, w) => success = true)) + world.addSystem(EmptySystem((_, _) => success = true)) world.update(10) success shouldBe true } From 96b73bc30f65f38f7d59c7e8e6bd8e29358d9170 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:47:32 +0200 Subject: [PATCH 029/447] Update demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index b96eb020..71551b01 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -20,7 +20,7 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { creationSystem.shouldRun shouldBe true } } - "the mouse is not clicked and game not run" should { + "the mouse is not clicked and game is not running" should { "not be executed" in new BallCreationSystemFixture { disableSystemCondition() creationSystem.shouldRun shouldBe false From 4d01f31f5d077cf970c6721529b3f3d5b1f70a84 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:47:45 +0200 Subject: [PATCH 030/447] Update demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index 71551b01..c813a9c0 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -37,7 +37,7 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0)) world.entitiesCount shouldBe 1 } - "not create a ball when the mouse is inside other ball" in new BallCreationSystemFixture { + "not create a ball when the mouse is inside another ball" in new BallCreationSystemFixture { enableSystemCondition() simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0)) world.entitiesCount shouldBe 1 From 42325e2073c7de6f5f5d741db85a528114ab725d Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:47:56 +0200 Subject: [PATCH 031/447] Update demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../atedeg/ecscalademo/systems/BallSelectionSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index a214a743..332d15c2 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -35,7 +35,7 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { } } "a ball is selected" should { - "set the ball as current selected" in new BallSelectionSystemFixture { + "set the ball as currently selected" in new BallSelectionSystemFixture { enableSystemCondition() PlayState.selectedBall = None From aa302792cc8c1a087eebb4b1d578d1d47e8e96ec Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:51:34 +0200 Subject: [PATCH 032/447] Remove useless assertion --- .../dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index afb9a8b0..cf0ef6b4 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -50,10 +50,6 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { "enabled" should { "update the selectes entity's position" in new DragBallSystemFixture { entity.addComponent(Position(0.0, 0.0)) - entity.getComponent[Position] match { - case Some(position) => position - case _ => fail("A component should beee defined") - } shouldBe Position(Point(0, 0)) PlayState.selectedBall = Some(entity) MouseState.coordinates = Point(10.0, 10.0) From 252149614589cf7cdf485fb51de1818f5acb337b Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:08:01 +0200 Subject: [PATCH 033/447] Use method instead property --- .../ecscalademo/systems/BallCreationRenderingSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index c0ffdd87..c14522e8 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -25,7 +25,7 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc system.shouldRun shouldBe true } "render the ball" in new BallCreationRenderingSystemFixture { - PlayState.playing = false + enableSystemCondition() world.addSystem(system) world.update(10) verify(canvasMock).drawCircle(any(), anyDouble(), any(), anyDouble()) From 92f28521ba2f2cf597b71293ce292206d03640bf Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:11:33 +0200 Subject: [PATCH 034/447] Improve test readability --- .../systems/BallCreationRenderingSystemTest.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index c14522e8..f5a82540 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -19,8 +19,8 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc } "A RenderingCreationBallSystem" when { - "the game is run" should { - "enabled" in new BallCreationRenderingSystemFixture { + "the game is not running" should { + "be enabled" in new BallCreationRenderingSystemFixture { enableSystemCondition() system.shouldRun shouldBe true } @@ -30,7 +30,9 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc world.update(10) verify(canvasMock).drawCircle(any(), anyDouble(), any(), anyDouble()) } - "disabled" in new BallCreationRenderingSystemFixture { + } + "the game is running" should { + "be disabled" in new BallCreationRenderingSystemFixture { disableSystemCondition() system.shouldRun shouldBe false } From 4f18723e258767d35b2ef698210de24de9caa8ab Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:17:34 +0200 Subject: [PATCH 035/447] Add scaladoc to EmptySystem --- core/src/main/scala/dev/atedeg/ecscala/System.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/scala/dev/atedeg/ecscala/System.scala b/core/src/main/scala/dev/atedeg/ecscala/System.scala index 07b9e5bd..5fb379eb 100644 --- a/core/src/main/scala/dev/atedeg/ecscala/System.scala +++ b/core/src/main/scala/dev/atedeg/ecscala/System.scala @@ -119,6 +119,13 @@ trait EmptySystem extends System[CNil] { object EmptySystem { + /** + * Create an [[EmptySystem]] from a lambda that specity the behaviuor of this [[System]]. + * @param f + * the behaviuor of the [[EmptySystem]] that takes [[DeltaTime]] and the [[World]] and return Unit. + * @return + * the [[EmptySystem]] + */ def apply(f: (DeltaTime, World) => Unit): EmptySystem = new EmptySystem { override def update(deltaTime: DeltaTime, world: World): Unit = f(deltaTime, world) } From 1cbf18d7dba24e25cd0bfffbaeb10cdfde20e8b6 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:22:33 +0200 Subject: [PATCH 036/447] Remove implicit conversion --- demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala index c4940a57..7f288497 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/Components.scala @@ -9,18 +9,16 @@ case class Color(r: Int, g: Int, b: Int) { } case class Position(position: Point) extends Component { + def this(x: Double, y: Double) = this(Point(x, y)) def x: Double = position.x def y: Double = position.y } -given Conversion[Position, Point] = _.position - case class Velocity(velocity: Vector) extends Component { + def this(x: Double, y: Double) = this(Vector(x, y)) def x: Double = velocity.x def y: Double = velocity.y } -given Conversion[Velocity, Vector] = _.velocity - case class Circle(radius: Double, color: Color) extends Component case class Mass(mass: Double) extends Component From 08b6ce704aaaadc9bb6ce4006a69091d5c484fb3 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:23:02 +0200 Subject: [PATCH 037/447] Add starting velocity in StartingState --- .../main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala | 1 + .../dev/atedeg/ecscalademo/systems/BallCreationSystem.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index 8b166c59..edfd8a7e 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -18,4 +18,5 @@ object StartingState { val startingRadius: Double = 20.0 val startingColor: Color = Color(255, 255, 0) val startingMass: Double = 1 + val startingVelocity: Vector = Vector(0.0, 0.0) } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index 2dae907c..98196164 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -22,7 +22,7 @@ class BallCreationSystem extends EmptySystem with ECScalaDSL { world hasAn entity withComponents { Position(MouseState.coordinates) &: Circle(StartingState.startingRadius, StartingState.startingColor) &: - Velocity(Vector(0, 0)) &: + Velocity(StartingState.startingVelocity) &: Mass(StartingState.startingMass) } } From c09f1d2550ac5d6199d9b7ff14d28362cc8b989c Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:25:27 +0200 Subject: [PATCH 038/447] Remove empty test --- .../atedeg/ecscalademo/systems/DragBallSystemTest.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index cf0ef6b4..70eb5511 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -16,7 +16,7 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { lazy val dragBallSystem: DragBallSystem = DragBallSystem() } - "A drag ball system" when { + "A DragBallSystem" when { "the game is running and the mouse is clicked" should { "not run" in new DragBallSystemFixture { PlayState.playing = true @@ -42,12 +42,6 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { MouseState.clicked = true dragBallSystem.shouldRun shouldBe true } - "update the selected entity's position" in new DragBallSystemFixture { - PlayState.playing = false - PlayState.selectedBall = Some(entity) - } - } - "enabled" should { "update the selectes entity's position" in new DragBallSystemFixture { entity.addComponent(Position(0.0, 0.0)) From 39167e832e454ff8e45b60ddc45832098bb98891 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:56:29 +0200 Subject: [PATCH 039/447] Update demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index 63ec087a..8332537e 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -13,7 +13,7 @@ class BallSelectionSystem extends EmptySystem { override def shouldRun: Boolean = !PlayState.playing && MouseState.down override def update(deltaTime: DeltaTime, world: World): Unit = { - val entitySelected: Option[Entity] = world.getView[Position &: Circle &: CNil] find { e => + val selectedEntity: Option[Entity] = world.getView[Position &: Circle &: CNil] find { e => val Position(point) &: Circle(radius, _) &: CNil = e._2 isOverlapped(point, radius) } map (_._1) From 106f0ce29c4e911f501cfdf074cf9fc719eb01bd Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:56:45 +0200 Subject: [PATCH 040/447] Update demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../dev/atedeg/ecscalademo/systems/BallCreationSystem.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index 98196164..e3309de2 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -6,7 +6,7 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.* /** - * This [[System]] is used to create a new ball into the [[World]]. If the mouse pointer is in the area of another ball, + * This [[System]] is used to add a new ball into the [[World]]. If the mouse pointer is in the area of another ball, * no ball will be added. */ class BallCreationSystem extends EmptySystem with ECScalaDSL { From ee33cdd5be353d94a19cf5ae50b561ab32c3bbc5 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 08:57:26 +0200 Subject: [PATCH 041/447] Update demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala index c7ce3451..a028e129 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -5,7 +5,7 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.{ MouseState, PlayState, Position } /** - * This [[System]] is used to update selected ball's position according to the mouse pointer. + * This [[System]] is used to update the selected ball's [[Position]] according to the mouse pointer. */ class DragBallSystem extends EmptySystem { From b067130dd998ed9f5bf410b125f4b9336d7aae08 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 09:12:12 +0200 Subject: [PATCH 042/447] Update demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala Co-authored-by: Giacomo Cavalieri <20598369+giacomocavalieri@users.noreply.github.com> --- .../dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index c813a9c0..f5d58ea5 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -14,7 +14,7 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { } "A BallCreationSystem" when { - "the mouse is clicked and game not run" should { + "the mouse is clicked and the game is not running" should { "be executed" in new BallCreationSystemFixture { enableSystemCondition() creationSystem.shouldRun shouldBe true From 875de5e4311efc522c6ae7d98401616cb83a34ed Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 10:10:35 +0200 Subject: [PATCH 043/447] Set to false tests' parallel execution --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f60fad96..037f88dc 100644 --- a/build.sbt +++ b/build.sbt @@ -179,7 +179,7 @@ lazy val demo = project .dependsOn(core) .settings( publish / skip := true, - test / skip := true, + Test / parallelExecution := false, assembly / assemblyJarName := "ECScalaDemo.jar", githubWorkflowArtifactUpload := false, libraryDependencies ++= scalaTest, From 28602a642a040c6e9edd61a05d49206b0cc35cd8 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 10:15:02 +0200 Subject: [PATCH 044/447] Use squaredNorm in order to avoid square root --- .../dev/atedeg/ecscalademo/systems/BallCreationSystem.scala | 6 +++--- .../atedeg/ecscalademo/systems/BallSelectionSystem.scala | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index e3309de2..e35557d4 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -6,8 +6,8 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.* /** - * This [[System]] is used to add a new ball into the [[World]]. If the mouse pointer is in the area of another ball, - * no ball will be added. + * This [[System]] is used to add a new ball into the [[World]]. If the mouse pointer is in the area of another ball, no + * ball will be added. */ class BallCreationSystem extends EmptySystem with ECScalaDSL { @@ -29,5 +29,5 @@ class BallCreationSystem extends EmptySystem with ECScalaDSL { } private def isOverlapped(point: Point, radius: Double): Boolean = - (point - MouseState.coordinates).norm < (radius + StartingState.startingRadius) + (point - MouseState.coordinates).squaredNorm < Math.pow(radius + StartingState.startingRadius, 2) } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index 8332537e..71f75b71 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -23,5 +23,5 @@ class BallSelectionSystem extends EmptySystem { } private def isOverlapped(point: Point, radius: Double): Boolean = - (MouseState.coordinates - point).norm < (radius + StartingState.startingRadius) + (MouseState.coordinates - point).squaredNorm < Math.pow(radius + StartingState.startingRadius, 2) } From 0705ccd55b485dd41f9f7717395c1cd7b20ca165 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 11:24:17 +0200 Subject: [PATCH 045/447] Update ci plugin. Add condition on codecov publish. Add demo fatjar --- .github/workflows/ci.yml | 16 +++++++++----- .github/workflows/clean.yml | 2 +- build.sbt | 43 ++++++++++++++++++++++--------------- project/plugins.sbt | 2 +- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58ec283e..765c5e34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: fetch-depth: 0 - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + uses: olafurpg/setup-scala@v13 with: java-version: ${{ matrix.java }} @@ -53,15 +53,17 @@ jobs: run: sbt ++${{ matrix.scala }} githubWorkflowCheck - name: Lint check with scalafmt - run: sbt ++${{ matrix.scala }} scalafmtCheck + run: sbt ++${{ matrix.scala }} scalafmtCheckAll - name: Tests - run: sbt ++${{ matrix.scala }} 'core / test' + run: sbt ++${{ matrix.scala }} test - name: Generate JaCoCo report + if: ${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' run: sbt ++${{ matrix.scala }} 'core / jacoco' - name: Publish coverage to codecov + if: ${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -101,7 +103,7 @@ jobs: fetch-depth: 0 - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + uses: olafurpg/setup-scala@v13 with: java-version: ${{ matrix.java }} @@ -134,6 +136,9 @@ jobs: args: '-output-format=pdf -file-line-error -synctex=1 -halt-on-error -interaction=nonstopmode -shell-escape' working_directory: doc + - name: Create FatJar for the demo + run: sbt ++${{ matrix.scala }} 'demo / assembly' + - name: Release to Sonatype env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} @@ -152,4 +157,5 @@ jobs: files: | core/target/scala-3.0.1/*.jar core/target/scala-3.0.1/*.pom - doc/ecscala-report.pdf \ No newline at end of file + demo/target/scala-3.0.1/ECScalaDemo.jar + doc/ecscala-report.pdf diff --git a/.github/workflows/clean.yml b/.github/workflows/clean.yml index b535fcc1..547aaa43 100644 --- a/.github/workflows/clean.yml +++ b/.github/workflows/clean.yml @@ -56,4 +56,4 @@ jobs: printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size ghapi -X DELETE $REPO/actions/artifacts/$id done - done \ No newline at end of file + done diff --git a/build.sbt b/build.sbt index 037f88dc..93b9e471 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,5 @@ import sbtghactions.GenerativePlugin.autoImport.WorkflowStep +import sbtghactions.UseRef import xerial.sbt.Sonatype.autoImport.sonatypeRepository val scala3Version = "3.0.1" @@ -45,16 +46,26 @@ ThisBuild / githubWorkflowTargetTags ++= Seq("v*") ThisBuild / githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))) ThisBuild / githubWorkflowBuild := Seq( - WorkflowStep.Sbt(List("scalafmtCheck"), name = Some("Lint check with scalafmt")), - WorkflowStep.Sbt(List("core / test"), name = Some("Tests")), + WorkflowStep.Sbt( + List("scalafmtCheckAll"), + name = Some("Lint check with scalafmt"), + ), + WorkflowStep.Sbt( + List("test"), + name = Some("Tests"), + ), WorkflowStep.Sbt( List("core / jacoco"), + cond = Some( + "${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", + ), name = Some("Generate JaCoCo report"), ), WorkflowStep.Use( - "codecov", - "codecov-action", - "v2", + UseRef.Public("codecov", "codecov-action", "v2"), + cond = Some( + "${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", + ), name = Some("Publish coverage to codecov"), params = Map( "token" -> "${{ secrets.CODECOV_TOKEN }}", @@ -63,9 +74,7 @@ ThisBuild / githubWorkflowBuild := Seq( ), ), WorkflowStep.Use( - "xu-cheng", - "latex-action", - "v2", + UseRef.Public("xu-cheng", "latex-action", "v2"), name = Some("Build LaTeX report"), params = Map( "root_file" -> "ecscala-report.tex", @@ -77,9 +86,7 @@ ThisBuild / githubWorkflowBuild := Seq( ThisBuild / githubWorkflowPublish := Seq( WorkflowStep.Use( - "xu-cheng", - "latex-action", - "v2", + UseRef.Public("xu-cheng", "latex-action", "v2"), name = Some("Build LaTeX report"), params = Map( "root_file" -> "ecscala-report.tex", @@ -87,6 +94,10 @@ ThisBuild / githubWorkflowPublish := Seq( "working_directory" -> "doc", ), ), + WorkflowStep.Sbt( + List("demo / assembly"), + name = Some("Create FatJar for the demo"), + ), WorkflowStep.Sbt( List("ci-release"), name = Some("Release to Sonatype"), @@ -99,15 +110,13 @@ ThisBuild / githubWorkflowPublish := Seq( ), ), WorkflowStep.Use( - "marvinpinto", - "action-automatic-releases", - "latest", + UseRef.Public("marvinpinto", "action-automatic-releases", "latest"), name = Some("Release to Github Releases"), params = Map( "repo_token" -> "${{ secrets.GITHUB_TOKEN }}", "prerelease" -> "${{ env.IS_SNAPSHOT }}", "title" -> """Release - Version ${{ env.VERSION }}""", - "files" -> s"core/target/scala-$scala3Version/*.jar\ncore/target/scala-$scala3Version/*.pom\ndoc/ecscala-report.pdf", + "files" -> s"core/target/scala-$scala3Version/*.jar\ncore/target/scala-$scala3Version/*.pom\ndemo/target/scala-$scala3Version/ECScalaDemo.jar\ndoc/ecscala-report.pdf", ), ), ) @@ -119,7 +128,7 @@ val scalaTest = Seq( lazy val root = project .in(file(".")) - .aggregate(core, benchmarks) + .aggregate(core, benchmarks, demo) .settings( sonatypeCredentialHost := "s01.oss.sonatype.org", sonatypeRepository := "https://s01.oss.sonatype.org/service/local", @@ -151,7 +160,7 @@ lazy val benchmarks = project .enablePlugins(JmhPlugin) .settings( publish / skip := true, - test / skip := true, + Test / skip := true, githubWorkflowArtifactUpload := false, ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 5695624a..5a796d74 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.3.0") -addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.9.5") +addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.13.0") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") From 44c4c49724254a8f81dead63f9712efff0b0359b Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 12:19:02 +0200 Subject: [PATCH 046/447] Fix typo in variable --- .../dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index 71f75b71..ca89f7ab 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -18,8 +18,8 @@ class BallSelectionSystem extends EmptySystem { isOverlapped(point, radius) } map (_._1) - if (entitySelected.isEmpty) then PlayState.selectedBall = None - else PlayState.selectedBall = Some(entitySelected.get) + if (selectedEntity.isEmpty) then PlayState.selectedBall = None + else PlayState.selectedBall = Some(selectedEntity.get) } private def isOverlapped(point: Point, radius: Double): Boolean = From a15d7f12ef689be7a3fa9bb4d6aca4f86868bfe4 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 12:39:14 +0200 Subject: [PATCH 047/447] Add flag for creation ball --- .../main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala | 1 + .../ecscalademo/systems/BallCreationRenderingSystem.scala | 2 +- .../dev/atedeg/ecscalademo/systems/BallCreationSystem.scala | 2 +- .../ecscalademo/systems/BallCreationRenderingSystemTest.scala | 4 ++-- .../atedeg/ecscalademo/systems/BallCreationSystemTest.scala | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index edfd8a7e..aa72f012 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -12,6 +12,7 @@ object MouseState { object PlayState { var playing = false var selectedBall: Option[Entity] = Option.empty + var addBallMode: Boolean = false } object StartingState { diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala index 6bb3de92..455162f2 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -14,7 +14,7 @@ import scala.language.implicitConversions */ class BallCreationRenderingSystem(private val canvas: ECSCanvas) extends EmptySystem { - override def shouldRun: Boolean = !PlayState.playing + override def shouldRun: Boolean = PlayState.addBallMode override def update(deltaTime: DeltaTime, world: World): Unit = canvas.drawCircle(MouseState.coordinates, StartingState.startingRadius, StartingState.startingColor, 1) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index e35557d4..327ce9b8 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -11,7 +11,7 @@ import dev.atedeg.ecscalademo.* */ class BallCreationSystem extends EmptySystem with ECScalaDSL { - override def shouldRun: Boolean = MouseState.clicked && !PlayState.playing + override def shouldRun: Boolean = MouseState.clicked && PlayState.addBallMode override def update(deltaTime: DeltaTime, world: World): Unit = { val canBeCreated = world.getView[Position &: Circle &: CNil] map (_._2) forall { cl => diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index f5a82540..d087ba6a 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -39,6 +39,6 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc } } - private def enableSystemCondition(): Unit = PlayState.playing = false - private def disableSystemCondition(): Unit = PlayState.playing = true + private def enableSystemCondition(): Unit = PlayState.addBallMode = true + private def disableSystemCondition(): Unit = PlayState.addBallMode = false } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index f5d58ea5..a3436c7f 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -46,12 +46,12 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { } private def enableSystemCondition(): Unit = { - PlayState.playing = false + PlayState.addBallMode = true MouseState.clicked = true } private def disableSystemCondition(): Unit = { - PlayState.playing = false + PlayState.addBallMode = true MouseState.clicked = false } From c6327dcd60f9263ef87f440542b591bbac29024d Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 16:05:47 +0200 Subject: [PATCH 048/447] Update effort --- process/sprint7.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/sprint7.csv b/process/sprint7.csv index 29aa50a4..539ab1f4 100644 --- a/process/sprint7.csv +++ b/process/sprint7.csv @@ -3,8 +3,8 @@ Product Backlog Item,Sprint Task,URL,Volunteer,Initial estimate of effort,1,2,3, As a framework user I want a working example of the framework,Handle balls collisions,,Nicolò Di Domenico,7,,,,,,, ,Update balls position,,Linda Vitali,1,,,,,,, ,Balls rendering,,Linda Vitali,1,,,,,,, -,Handle balls creation,,Nicolas Farabegoli,2,,,,,,, -,Handle balls drag and drop,,Nicolas Farabegoli,4,,,,,,, +,Handle balls creation,,Nicolas Farabegoli,2,2,2,2,2,0,0,0 +,Handle balls drag and drop,,Nicolas Farabegoli,4,4,4,4,2,0,0,0 ,Handle balls velocity editing,,Giacomo Cavalieri,4,,,,,,, ,Create demo UI,,Linda Vitali,1,,,,,,, As a framework user I would higly appreciate a handy DSL to perform these operations,Complete DSL for Systems,,Linda Vitali,1,,,,,,, From 0cc0069e72b348ed59b4d7b5b2c2b2b6c2d62e79 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Sun, 26 Sep 2021 16:35:42 +0200 Subject: [PATCH 049/447] Use DSL into tests class --- .../BallCreationRenderingSystemTest.scala | 4 +++- .../systems/BallCreationSystemTest.scala | 20 +++++++++++------- .../systems/BallSelectionSystemTest.scala | 21 +++++++++++-------- .../systems/DragBallSystemTest.scala | 18 +++++++++------- 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index d087ba6a..8e99ce50 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -1,5 +1,6 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.World import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.{ ECSCanvas, PlayState, ScalaFXCanvas } @@ -13,7 +14,8 @@ import scalafx.scene.canvas.Canvas class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with MockitoSugar { - trait BallCreationRenderingSystemFixture extends WorldFixture { + trait BallCreationRenderingSystemFixture { + val world = World() val canvasMock = mock[ECSCanvas] lazy val system = BallCreationRenderingSystem(canvasMock) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index a3436c7f..f36d20cd 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -1,15 +1,18 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscala.{ Entity, World } +import dev.atedeg.ecscala.{ CNil, Entity, World } import dev.atedeg.ecscalademo.fixtures.WorldFixture import dev.atedeg.ecscalademo.* import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class BallCreationSystemTest extends AnyWordSpec with Matchers { +class BallCreationSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { - trait BallCreationSystemFixture extends WorldFixture { + trait BallCreationSystemFixture { + val world = World() + val entity1 = world hasAn entity lazy val creationSystem: BallCreationSystem = BallCreationSystem() } @@ -29,17 +32,17 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { "enabled" should { "create a ball in a free position" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(0.0, 0.0), Point(100.0, 100.0)) + simulateCreateBall(world, entity1, creationSystem, Point(0.0, 0.0), Point(100.0, 100.0)) world.entitiesCount shouldBe 2 } "not create a ball over another one" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0)) + simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0)) world.entitiesCount shouldBe 1 } "not create a ball when the mouse is inside another ball" in new BallCreationSystemFixture { enableSystemCondition() - simulateCreateBall(world, entity, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0)) + simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0)) world.entitiesCount shouldBe 1 } } @@ -62,8 +65,9 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers { existingPosition: Point, mousePosition: Point, ): Unit = { - existingEntity.addComponent(Position(existingPosition)) - existingEntity.addComponent(Circle(StartingState.startingRadius, StartingState.startingColor)) + existingEntity withComponents { + Position(existingPosition) &: Circle(StartingState.startingRadius, StartingState.startingColor) &: CNil + } world.update(10) MouseState.coordinates = mousePosition world.addSystem(system) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index 332d15c2..8ae514d4 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -1,5 +1,7 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.World +import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.WorldFixture @@ -9,9 +11,10 @@ import org.scalatest.wordspec.AnyWordSpec import scala.language.implicitConversions -class BallSelectionSystemTest extends AnyWordSpec with Matchers { +class BallSelectionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { - trait BallSelectionSystemFixture extends WorldFixture { + trait BallSelectionSystemFixture { + val world = World() lazy val system = BallSelectionSystem() } @@ -39,15 +42,15 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers { enableSystemCondition() PlayState.selectedBall = None - val entity1 = world.createEntity() - val entity2 = world.createEntity() - entity1.addComponent(Position(10.0, 10.0)) - entity1.addComponent(Circle(20, StartingState.startingColor)) - - entity2.addComponent(Position(70.0, 70.0)) - entity2.addComponent(Circle(20, StartingState.startingColor)) + val entity1 = world hasAn entity withComponents { + Position(10.0, 10.0) &: Circle(20, StartingState.startingColor) + } + val entity2 = world hasAn entity withComponents { + Position(70.0, 70.0) &: Circle(20, StartingState.startingColor) + } world.addSystem(system) + PlayState.selectedBall shouldBe None MouseState.coordinates = Point(10.0, 10.0) world.update(10) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index 70eb5511..5f9cb394 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -1,6 +1,8 @@ package dev.atedeg.ecscalademo.systems -import dev.atedeg.ecscala.Entity +import dev.atedeg.ecscala.Deleted.entity +import dev.atedeg.ecscala.dsl.ECScalaDSL +import dev.atedeg.ecscala.{ Entity, World } import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.WorldFixture @@ -10,9 +12,11 @@ import org.scalatest.wordspec.AnyWordSpec import scala.language.implicitConversions -class DragBallSystemTest extends AnyWordSpec with Matchers { +class DragBallSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { - trait DragBallSystemFixture extends WorldFixture { + trait DragBallSystemFixture { + val world = World() + val entity1 = world hasAn entity lazy val dragBallSystem: DragBallSystem = DragBallSystem() } @@ -37,21 +41,21 @@ class DragBallSystemTest extends AnyWordSpec with Matchers { "the game is not running and the mouse is clicked" should { "run" in new DragBallSystemFixture { PlayState.playing = false - PlayState.selectedBall = Some(entity) + PlayState.selectedBall = Some(entity1) MouseState.down = true MouseState.clicked = true dragBallSystem.shouldRun shouldBe true } "update the selectes entity's position" in new DragBallSystemFixture { - entity.addComponent(Position(0.0, 0.0)) + entity1 withComponent Position(0.0, 0.0) - PlayState.selectedBall = Some(entity) + PlayState.selectedBall = Some(entity1) MouseState.coordinates = Point(10.0, 10.0) world.addSystem(dragBallSystem) world.update(10) - entity.getComponent[Position] match { + entity1.getComponent[Position] match { case Some(position) => position case _ => fail("A component should been defined") } shouldBe Position(10.0, 10.0) From 1620c12fd42cc77351a2b0e46959817bb33edcfa Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Mon, 27 Sep 2021 14:21:47 +0200 Subject: [PATCH 050/447] Remove unused button and refactor code --- demo/src/main/resources/MainView.fxml | 7 +------ .../controller/MainViewController.scala | 17 +++-------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/demo/src/main/resources/MainView.fxml b/demo/src/main/resources/MainView.fxml index f0054a78..a34b02a5 100644 --- a/demo/src/main/resources/MainView.fxml +++ b/demo/src/main/resources/MainView.fxml @@ -11,11 +11,6 @@ From 9bfbafd235533878ae487e5ad60f42925dee6d0e Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Tue, 28 Sep 2021 17:09:56 +0200 Subject: [PATCH 175/447] Disable reset button when game is running --- demo/src/main/resources/MainView.fxml | 2 +- .../controller/MainViewController.scala | 30 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/demo/src/main/resources/MainView.fxml b/demo/src/main/resources/MainView.fxml index 26ab8f9e..74f305f8 100644 --- a/demo/src/main/resources/MainView.fxml +++ b/demo/src/main/resources/MainView.fxml @@ -12,7 +12,7 @@ + + + + + + + + + + - - - - - - + + + + - - - - - - - - - - - + + + + + + + + + diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index e4b157ba..8555d084 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -1,6 +1,7 @@ package dev.atedeg.ecscalademo import dev.atedeg.ecscala.Entity +import scalafx.beans.property.DoubleProperty object MouseState { var coordinates = Point(0, 0) @@ -55,7 +56,7 @@ object StartingState { } object EnvironmentState { - val frictionCoefficient: Double = 0.05 - var wallRestitution: Double = 0.5 + val frictionCoefficient = DoubleProperty(0.05) + var wallRestitution = DoubleProperty(0.5) val gravity: Double = 9.81 } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index e312cfa1..8dcb71cb 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -1,12 +1,11 @@ package dev.atedeg.ecscalademo.controller import dev.atedeg.ecscala.World -import dev.atedeg.ecscalademo.{ ECSCanvas, MouseState, PlayState, Point, ScalaFXCanvas } -import dev.atedeg.ecscala.{ &:, CNil, World } -import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscalademo.{ Circle, Color, + ECSCanvas, + EnvironmentState, Mass, MouseState, PlayState, @@ -16,13 +15,16 @@ import dev.atedeg.ecscalademo.{ Vector, Velocity, } +import dev.atedeg.ecscala.{ &:, CNil, World } +import dev.atedeg.ecscala.dsl.ECScalaDSL import javafx.fxml.{ FXML, Initializable } import javafx.scene.control.Label as JfxLabel import javafx.scene.control.Button as JfxButton +import javafx.scene.control.Slider as JfxSlider import javafx.scene.layout as jfx import javafx.scene.canvas.Canvas as JfxCanvas import javafx.scene.layout.Pane as JfxPane -import scalafx.scene.control.{ Button, Label } +import scalafx.scene.control.{ Button, Label, Slider } import scalafx.scene.canvas.{ Canvas, GraphicsContext } import scalafx.scene.canvas.{ Canvas, GraphicsContext } import scalafx.scene.layout.Pane @@ -38,6 +40,8 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.StartingState.{ startingMass, startingPositions, startingRadius } import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer +import java.text.DecimalFormat + class MainViewController extends Initializable with ECScalaDSL { @FXML @@ -64,6 +68,22 @@ class MainViewController extends Initializable with ECScalaDSL { private var fpsDelegate: JfxLabel = _ private lazy val fps: Label = new Label(fpsDelegate) + @FXML + private var wrSliderDelegate: JfxSlider = _ + private lazy val wrSlider = new Slider(wrSliderDelegate) + + @FXML + private var fcSliderDelegate: JfxSlider = _ + private lazy val fcSlider = new Slider(fcSliderDelegate) + + @FXML + private var fcLabelDelegate: JfxLabel = _ + private lazy val fcLabel = new Label(fcLabelDelegate) + + @FXML + private var wrLabelDelegate: JfxLabel = _ + private lazy val wrLabel = new Label(wrLabelDelegate) + private lazy val ecsCanvas = ScalaFXCanvas(canvas) private val world: World = World() private var loop: GameLoop = _ @@ -90,7 +110,15 @@ class MainViewController extends Initializable with ECScalaDSL { changeVelBtn.disable = true } }) + fps.text.bindBidirectional(loop.fps, new NumberStringConverter("FPS: ")) + EnvironmentState.frictionCoefficient <== fcSlider.value + EnvironmentState.wallRestitution <== wrSlider.value + val decimalFormat = new DecimalFormat() + decimalFormat.setMaximumFractionDigits(2) + decimalFormat.setMinimumFractionDigits(2) + fcLabel.text.bindBidirectional(fcSlider.value, new NumberStringConverter(decimalFormat)) + wrLabel.text.bindBidirectional(wrSlider.value, new NumberStringConverter(decimalFormat)) loop.start } @@ -122,6 +150,8 @@ class MainViewController extends Initializable with ECScalaDSL { changeVelBtn.disable = isRunning addBallBtn.disable = isRunning addBallBtn.text = addBallButtonLabel + wrSlider.disable = isRunning + fcSlider.disable = isRunning if (!isRunning) { PlayState.velocityEditingMode = false PlayState.addBallMode = false diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala index 12164e2b..968b53b3 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala @@ -22,7 +22,7 @@ class FrictionSystem() extends System[Velocity &: CNil] { val Velocity(velocity) &: CNil = components if (velocity.norm > 0) { val frictionDirection = -1 * velocity.normalized - val friction = (frictionCoefficient * gravity) * frictionDirection + val friction = (frictionCoefficient.value * gravity) * frictionDirection val newVelocity = velocity + friction if (velocity dot newVelocity) < 0 then Velocity(0, 0) &: CNil else Velocity(newVelocity) &: CNil } else { diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala index f8e93435..935fcc02 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala @@ -38,8 +38,8 @@ class WallCollisionSystem(private val canvas: ECSCanvas) extends System[Position val collidesRight = x > canvas.width - radius val collidesTop = y < radius val collidesBottom = y > canvas.height - radius - lazy val mirroredHorizontalVelocity = -vx * EnvironmentState.wallRestitution - lazy val mirroredVerticalVelocity = -vy * EnvironmentState.wallRestitution + lazy val mirroredHorizontalVelocity = -vx * EnvironmentState.wallRestitution.value + lazy val mirroredVerticalVelocity = -vy * EnvironmentState.wallRestitution.value val newVelocity = Velocity( if (collidesLeft && vx < 0) || (collidesRight && vx > 0) then mirroredHorizontalVelocity else vx, if (collidesTop && vy < 0) || (collidesBottom && vy > 0) then mirroredVerticalVelocity else vy, diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala index a2358e92..567cc691 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala @@ -34,7 +34,7 @@ class WallCollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL } "change velocities to entities that collide with the canvas's borders" in new WallCollisionsFixture { PlayState.playing = true - EnvironmentState.wallRestitution = 1 + EnvironmentState.wallRestitution.value = 1 val canvas = mock[ECSCanvas] when(canvas.width) thenReturn 100.0 when(canvas.height) thenReturn 100.0 From c92faefe85d751e4a9432c63a5b30f7c32820f14 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Tue, 28 Sep 2021 22:36:34 +0200 Subject: [PATCH 182/447] Unselect a selected ball when play button is pressed --- .../dev/atedeg/ecscalademo/controller/MainViewController.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 8dcb71cb..2f0b5f15 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -145,6 +145,7 @@ class MainViewController extends Initializable with ECScalaDSL { def onPlayPauseClickHandler(): Unit = { PlayState.playing = !isRunning + PlayState.selectedBall = None isRunning = !isRunning playPauseBtn.text = if isRunning then pauseButtonLabel else playButtonLabel changeVelBtn.disable = isRunning From ffc5a243e5326b7fd7821d0eae6a413924e5976b Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 17:55:23 +0200 Subject: [PATCH 183/447] Convert object into trait with companion object --- .../atedeg/ecscalademo/SimulationStatus.scala | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala index 8555d084..138146ed 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/SimulationStatus.scala @@ -3,19 +3,28 @@ package dev.atedeg.ecscalademo import dev.atedeg.ecscala.Entity import scalafx.beans.property.DoubleProperty -object MouseState { +enum State { + case Pause, Play, AddBalls, SelectBall, ChangeVelocity, Dragging +} + +trait MouseState { var coordinates = Point(0, 0) var clicked = false var down = false var up = false } -object PlayState { - var playing = false +object MouseState { + def apply(): MouseState = new MouseState {} +} + +trait PlayState { + var gameState: State = State.Pause var selectedBall: Option[Entity] = Option.empty - var addBallMode: Boolean = false - var velocityEditingMode: Boolean = false - var isDragging = false +} + +object PlayState { + def apply(): PlayState = new PlayState {} } object StartingState { @@ -55,8 +64,12 @@ object StartingState { ) } -object EnvironmentState { +trait EnvironmentState { val frictionCoefficient = DoubleProperty(0.05) - var wallRestitution = DoubleProperty(0.5) + val wallRestitution = DoubleProperty(0.5) val gravity: Double = 9.81 } + +object EnvironmentState { + def apply(): EnvironmentState = new EnvironmentState {} +} From a3dca634e32296a209bf5367f849f7075a966fec Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 17:56:48 +0200 Subject: [PATCH 184/447] Use trait instead object for playstate, mousestate and environmentstate --- .../fixtures/CollisionsFixture.scala | 5 ++- .../ecscalademo/fixtures/SystemsFixture.scala | 7 +++- .../fixtures/VelocityFixture.scala | 9 ++-- .../fixtures/WallCollisionsFixture.scala | 4 +- .../BallCreationRenderingSystemTest.scala | 16 +++---- .../systems/BallCreationSystemTest.scala | 35 +++++++++------- .../systems/BallSelectionSystemTest.scala | 36 ++++++++-------- .../systems/CollisionSystemTest.scala | 6 +-- .../systems/DragBallSystemTest.scala | 42 +++++++++---------- .../systems/FrictionSystemTest.scala | 8 ++-- .../systems/MovementSystemTest.scala | 6 +-- .../systems/RenderSystemTest.scala | 5 ++- .../systems/VelocityArrowSystemTest.scala | 18 ++++---- .../systems/VelocityEditingSystemTest.scala | 31 ++++++++------ .../systems/WallCollisionSystemTest.scala | 12 +++--- 15 files changed, 130 insertions(+), 110 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/CollisionsFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/CollisionsFixture.scala index e17a1159..9d3c92bf 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/CollisionsFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/CollisionsFixture.scala @@ -3,7 +3,7 @@ package dev.atedeg.ecscalademo.fixtures import scala.language.implicitConversions import dev.atedeg.ecscala.World import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ Circle, Color, Mass, Position, Velocity } +import dev.atedeg.ecscalademo.{ Circle, Color, Mass, PlayState, Position, Velocity } import dev.atedeg.ecscalademo import dev.atedeg.ecscalademo.systems.{ CollisionSystem, RegionAssignmentSystem } import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer @@ -11,7 +11,8 @@ import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer trait CollisionsFixture { private val spacePartition = WritableSpacePartitionContainer() val world = World() + val playState = PlayState() world addSystem (new RegionAssignmentSystem(spacePartition)) - world addSystem (new CollisionSystem(spacePartition)) + world addSystem (new CollisionSystem(playState, spacePartition)) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/SystemsFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/SystemsFixture.scala index 0b72e521..b22f1873 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/SystemsFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/SystemsFixture.scala @@ -1,8 +1,11 @@ package dev.atedeg.ecscalademo.fixtures +import dev.atedeg.ecscalademo.{ EnvironmentState, PlayState } import dev.atedeg.ecscalademo.systems.* trait SystemsFixture { - lazy val movementSystem = new MovementSystem() - lazy val frictionSystem = new FrictionSystem() + val playState = PlayState() + val environmentState = EnvironmentState() + lazy val movementSystem = new MovementSystem(playState) + lazy val frictionSystem = new FrictionSystem(playState, environmentState) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala index abed0296..747328e0 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala @@ -1,16 +1,17 @@ package dev.atedeg.ecscalademo.fixtures -import scala.language.implicitConversions import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.World import dev.atedeg.ecscala.dsl.ECScalaDSL -import dev.atedeg.ecscalademo.given -import dev.atedeg.ecscalademo.{ Point, Position, Vector, Velocity } +import dev.atedeg.ecscalademo +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Position, Vector, Velocity } import dev.atedeg.ecscalademo.systems.VelocityEditingSystem trait VelocityFixture extends ECScalaDSL { val world = World() - val system = VelocityEditingSystem() + val playState = PlayState() + val mouseState = MouseState() + val system = VelocityEditingSystem(playState, mouseState) val entity1 = world hasAn entity withComponents { Position(0, 0) &: Velocity(0, 0) } world hasA system(system) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WallCollisionsFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WallCollisionsFixture.scala index fcdc18af..4d995dd0 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WallCollisionsFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/WallCollisionsFixture.scala @@ -4,11 +4,13 @@ import scala.language.implicitConversions import dev.atedeg.ecscala.World import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ Circle, Color, Mass, Position, Velocity } +import dev.atedeg.ecscalademo.{ Circle, Color, EnvironmentState, Mass, PlayState, Position, Velocity } import dev.atedeg.ecscalademo trait WallCollisionsFixture extends ECScalaDSL { val world = World() + val playState = PlayState() + val environmentState = EnvironmentState() val entities = for { x <- Seq(-1.0, 50.0, 101.0) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index 67e33a0b..7aec1a9b 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -2,7 +2,7 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.World import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ ECSCanvas, PlayState, ScalaFXCanvas } +import dev.atedeg.ecscalademo.{ ECSCanvas, MouseState, PlayState, ScalaFXCanvas, State } import javafx.scene.canvas.Canvas as JfxCanvas import org.mockito.ArgumentMatchers.{ any, anyDouble } import org.mockito.Mockito.verify @@ -16,17 +16,19 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc trait BallCreationRenderingSystemFixture { val world = World() val canvasMock = mock[ECSCanvas] - lazy val system = BallCreationRenderingSystem(canvasMock) + val playState = PlayState() + val mouseState = MouseState() + lazy val system = new BallCreationRenderingSystem(playState, mouseState, canvasMock) } "A RenderingCreationBallSystem" when { "the game is not running" should { "be enabled" in new BallCreationRenderingSystemFixture { - enableSystemCondition() + enableSystemCondition(playState) system.shouldRun shouldBe true } "render the ball" in new BallCreationRenderingSystemFixture { - enableSystemCondition() + enableSystemCondition(playState) world.addSystem(system) world.update(10) verify(canvasMock).drawCircle(any(), anyDouble(), any(), anyDouble()) @@ -34,12 +36,12 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc } "the game is running" should { "be disabled" in new BallCreationRenderingSystemFixture { - disableSystemCondition() + disableSystemCondition(playState) system.shouldRun shouldBe false } } } - private def enableSystemCondition(): Unit = PlayState.addBallMode = true - private def disableSystemCondition(): Unit = PlayState.addBallMode = false + private def enableSystemCondition(playState: PlayState): Unit = playState.gameState == State.AddBalls + private def disableSystemCondition(playState: PlayState): Unit = playState.gameState == State.AddBalls } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala index 25d22bed..879108f5 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationSystemTest.scala @@ -12,49 +12,51 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { trait BallCreationSystemFixture { val world = World() val entity1 = world hasAn entity - lazy val creationSystem: BallCreationSystem = BallCreationSystem() + val playState = PlayState() + val mouseState = MouseState() + lazy val creationSystem: BallCreationSystem = new BallCreationSystem(playState, mouseState) } "A BallCreationSystem" when { "the mouse is clicked and the game is not running" should { "be executed" in new BallCreationSystemFixture { - enableSystemCondition() + enableSystemCondition(playState, mouseState) creationSystem.shouldRun shouldBe true } } "the mouse is not clicked and game is not running" should { "not be executed" in new BallCreationSystemFixture { - disableSystemCondition() + disableSystemCondition(playState, mouseState) creationSystem.shouldRun shouldBe false } } "enabled" should { "create a ball in a free position" in new BallCreationSystemFixture { - enableSystemCondition() - simulateCreateBall(world, entity1, creationSystem, Point(0.0, 0.0), Point(100.0, 100.0)) + enableSystemCondition(playState, mouseState) + simulateCreateBall(world, entity1, creationSystem, Point(0.0, 0.0), Point(100.0, 100.0), mouseState) world.entitiesCount shouldBe 2 } "not create a ball over another one" in new BallCreationSystemFixture { - enableSystemCondition() - simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0)) + enableSystemCondition(playState, mouseState) + simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(10.0, 10.0), mouseState) world.entitiesCount shouldBe 1 } "not create a ball when the mouse is inside another ball" in new BallCreationSystemFixture { - enableSystemCondition() - simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0)) + enableSystemCondition(playState, mouseState) + simulateCreateBall(world, entity1, creationSystem, Point(10.0, 10.0), Point(15.0, 15.0), mouseState) world.entitiesCount shouldBe 1 } } } - private def enableSystemCondition(): Unit = { - PlayState.addBallMode = true - MouseState.clicked = true + private def enableSystemCondition(playState: PlayState, mouseState: MouseState): Unit = { + playState.gameState = State.AddBalls + mouseState.clicked = true } - private def disableSystemCondition(): Unit = { - PlayState.addBallMode = true - MouseState.clicked = false + private def disableSystemCondition(playState: PlayState, mouseState: MouseState): Unit = { + playState.gameState = State.Play + mouseState.clicked = false } private def simulateCreateBall( @@ -63,12 +65,13 @@ class BallCreationSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { system: BallCreationSystem, existingPosition: Point, mousePosition: Point, + mouseState: MouseState, ): Unit = { existingEntity withComponents { Position(existingPosition) &: Circle(StartingState.startingRadius, StartingState.startingColor) &: CNil } world.update(10) - MouseState.coordinates = mousePosition + mouseState.coordinates = mousePosition world.addSystem(system) world.update(10) } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index 74f5631a..96896142 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -13,32 +13,34 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL trait BallSelectionSystemFixture { val world = World() - lazy val system = BallSelectionSystem() + val playState = PlayState() + val mouseState = MouseState() + lazy val system = BallSelectionSystem(playState, mouseState) } "A BallSelectionSystem" when { "the game is paused and the mouse is clicked" should { "be enabled" in new BallSelectionSystemFixture { - enableSystemCondition() + enableSystemCondition(playState, mouseState) system.shouldRun shouldBe true } } "the game is paused and the mouse is not clicked" should { "not be enabled" in new BallSelectionSystemFixture { - disableSystemCondition() + disableSystemCondition(playState, mouseState) system.shouldRun shouldBe false } } "the game is running" should { "not be enabled" in new BallSelectionSystemFixture { - PlayState.playing = true + playState.gameState = State.Pause system.shouldRun shouldBe false } } "a ball is selected" should { "set the ball as currently selected" in new BallSelectionSystemFixture { - enableSystemCondition() - PlayState.selectedBall = None + enableSystemCondition(playState, mouseState) + playState.selectedBall = None val entity1 = world hasAn entity withComponents { Position(10.0, 10.0) &: Circle(20, StartingState.startingColor) @@ -49,27 +51,27 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL world.addSystem(system) - PlayState.selectedBall shouldBe None - MouseState.coordinates = Point(10.0, 10.0) + playState.selectedBall shouldBe None + mouseState.coordinates = Point(10.0, 10.0) world.update(10) - PlayState.selectedBall shouldBe Some(entity1) + playState.selectedBall shouldBe Some(entity1) - MouseState.coordinates = Point(65.0, 65.0) + mouseState.coordinates = Point(65.0, 65.0) world.update(10) - PlayState.selectedBall shouldBe Some(entity2) + playState.selectedBall shouldBe Some(entity2) } } } - private def enableSystemCondition(): Unit = { - PlayState.playing = false - MouseState.down = true + private def enableSystemCondition(playState: PlayState, mouseState: MouseState): Unit = { + playState.gameState = State.Play + mouseState.down = true } - private def disableSystemCondition(): Unit = { - PlayState.playing = false - MouseState.down = false + private def disableSystemCondition(playState: PlayState, mouseState: MouseState): Unit = { + playState.gameState = State.Pause + mouseState.down = false } } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/CollisionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/CollisionSystemTest.scala index e18c2b75..ce9d723e 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/CollisionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/CollisionSystemTest.scala @@ -9,7 +9,7 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.fixtures.CollisionsFixture import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer import dev.atedeg.ecscalademo.given -import dev.atedeg.ecscalademo.{ Circle, Color, Mass, PlayState, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ Circle, Color, Mass, PlayState, Position, State, Vector, Velocity } class CollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { @@ -23,7 +23,7 @@ class CollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { Position(5, 0) &: Velocity(0, 0) &: Circle(10, black) &: Mass(1) } - PlayState.playing = true + playState.gameState = State.Play world.update(1) val stuckPosition1 = stuckEntity1.getComponent[Position].get val stuckPosition2 = stuckEntity2.getComponent[Position].get @@ -43,7 +43,7 @@ class CollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { Position(40, 20) &: Velocity(0, 0) &: Circle(10, black) &: Mass(1) } - PlayState.playing = true + playState.gameState = State.Play world.update(1) val velocity1 = collidingEntity1.getComponent[Velocity].get val velocity2 = collidingEntity2.getComponent[Velocity].get diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala index 36e12eb4..f30b4efe 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/DragBallSystemTest.scala @@ -4,7 +4,7 @@ import dev.atedeg.ecscala.Deleted.entity import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscala.{ Entity, World } import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Position } +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Position, State } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -15,53 +15,51 @@ class DragBallSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { trait DragBallSystemFixture { val world = World() val entity1 = world hasAn entity - lazy val dragBallSystem: DragBallSystem = DragBallSystem() + val playState = PlayState() + val mouseState = MouseState() + lazy val dragBallSystem: DragBallSystem = new DragBallSystem(playState, mouseState) } "A DragBallSystem" when { "the change velocity is set" should { "not run" in new DragBallSystemFixture { - PlayState.selectedBall = Some(entity1) - PlayState.playing = false - MouseState.down = true - MouseState.clicked = true - PlayState.velocityEditingMode = true + playState.selectedBall = Some(entity1) + playState.gameState = State.ChangeVelocity + mouseState.down = true + mouseState.clicked = true dragBallSystem.shouldRun shouldBe false } } "the game is running and the mouse is clicked" should { "not run" in new DragBallSystemFixture { - PlayState.playing = true - MouseState.down = true - MouseState.clicked = true + playState.gameState = State.Play + mouseState.down = true + mouseState.clicked = true dragBallSystem.shouldRun shouldBe false } } "the game is running and the mouse is not clicked" should { "not run" in new DragBallSystemFixture { - PlayState.playing = true - MouseState.up = true - MouseState.clicked = false + playState.gameState = State.Play + mouseState.up = true + mouseState.clicked = false dragBallSystem.shouldRun shouldBe false } } "the game is not running and the mouse is clicked" should { "run" in new DragBallSystemFixture { - PlayState.playing = false - PlayState.selectedBall = Some(entity1) - PlayState.isDragging = true - PlayState.velocityEditingMode = false + playState.gameState = State.Dragging + playState.selectedBall = Some(entity1) + mouseState.clicked = true dragBallSystem.shouldRun shouldBe true } "update the selectes entity's position" in new DragBallSystemFixture { entity1 withComponent Position(0.0, 0.0) - PlayState.playing = false - PlayState.selectedBall = Some(entity1) - PlayState.isDragging = true - PlayState.velocityEditingMode = false - MouseState.coordinates = Point(10.0, 10.0) + playState.gameState = State.Dragging + playState.selectedBall = Some(entity1) + mouseState.coordinates = Point(10.0, 10.0) world.addSystem(dragBallSystem) world.update(10) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/FrictionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/FrictionSystemTest.scala index 1bc81c1c..879dbd55 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/FrictionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/FrictionSystemTest.scala @@ -3,7 +3,7 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.{ &:, CNil, View } import dev.atedeg.ecscala.dsl.ECScalaDSL import dev.atedeg.ecscalademo -import dev.atedeg.ecscalademo.{ PlayState, Point, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ PlayState, Point, Position, State, Vector, Velocity } import dev.atedeg.ecscalademo.fixtures.{ SystemsFixture, WorldFixture } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -16,7 +16,7 @@ class FrictionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { "A FrictionSystem" when { "the simulation is playing" should { "update a ball's Velocity considering the friction" in new WorldFixture with SystemsFixture { - PlayState.playing = true + playState.gameState = State.Play val initialVelocity = Velocity(300, 0) val ball = world hasAn entity withComponents { initialVelocity @@ -30,7 +30,7 @@ class FrictionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { vector.x should be < initialVelocity.velocity.x } "don't update the component's Velocity if its initial Velocity is 0" in new WorldFixture with SystemsFixture { - PlayState.playing = true + playState.gameState = State.Play val ball = world hasAn entity withComponent Velocity(0, 0) world hasA system(frictionSystem) @@ -43,7 +43,7 @@ class FrictionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { } "the simulation is not playing" should { "not update the components" in new WorldFixture with SystemsFixture { - PlayState.playing = false + playState.gameState = State.Pause val ball = world hasAn entity withComponent Velocity(300, 0) world hasA system(frictionSystem) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/MovementSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/MovementSystemTest.scala index 6c87fcf4..3f2f891c 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/MovementSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/MovementSystemTest.scala @@ -2,7 +2,7 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.{ &:, CNil, World } import dev.atedeg.ecscala.dsl.ECScalaDSL -import dev.atedeg.ecscalademo.{ PlayState, Point, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ PlayState, Point, Position, State, Vector, Velocity } import dev.atedeg.ecscalademo.fixtures.{ SystemsFixture, WorldFixture } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -12,7 +12,7 @@ class MovementSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { "A MovementSystem" should { "not run when the game isn't playing" in new WorldFixture with SystemsFixture { - PlayState.playing = false + playState.gameState = State.Pause val ball = world hasAn entity withComponents { Position(0, 0) &: Velocity(300, 0) } addSystemToWorld(world, movementSystem) @@ -22,7 +22,7 @@ class MovementSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { ) } "update an entity Position when the game is playing" in new WorldFixture with SystemsFixture { - PlayState.playing = true + playState.gameState = State.Play val ball = world hasAn entity withComponents { Position(0, 0) &: Velocity(300, 0) } addSystemToWorld(world, movementSystem) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/RenderSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/RenderSystemTest.scala index 62e96eb3..d558a521 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/RenderSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/RenderSystemTest.scala @@ -13,8 +13,9 @@ class RenderSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { "A RenderSystem" should { "call the drawCircle method with the correct parameters" in new WorldFixture { + val playState = PlayState() val canvas = mock[ECSCanvas] - val renderSystem = new RenderSystem(canvas) + val renderSystem = new RenderSystem(playState, canvas) val position = Position(0, 0) val circle = Circle(20, Color(255, 0, 0)) @@ -24,7 +25,7 @@ class RenderSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { world.update(10) verify(canvas).drawCircle(position.position, circle.radius, circle.color, 1) - PlayState.selectedBall = Some(ball) + playState.selectedBall = Some(ball) world.update(10) verify(canvas).drawCircle(position.position, circle.radius, circle.color, 3) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystemTest.scala index eabff9e9..11a5c827 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystemTest.scala @@ -12,31 +12,31 @@ import org.mockito.Mockito.{ times, verify } import org.mockito.ArgumentMatchers.{ any, anyDouble, eq as is } import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.VelocityFixture -import dev.atedeg.ecscalademo.{ Color, ECSCanvas, MouseState, PlayState, Point, Position, Velocity } +import dev.atedeg.ecscalademo.{ Color, ECSCanvas, MouseState, PlayState, Point, Position, State, Velocity } import dev.atedeg.ecscala.util.types.given class VelocityArrowSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { trait VelocityArrowFixture { lazy val world = World() + val playState = PlayState() + val mouseState = MouseState() lazy val entity1 = world hasAn entity withComponents { Position(0, 0) &: Velocity(10, 10) } lazy val canvas = mock[ECSCanvas] - lazy val arrowSystem = VelocityArrowSystem(canvas) + lazy val arrowSystem = new VelocityArrowSystem(playState, mouseState, canvas) } "A VelocityArrowSystem" should { "run if the game is paused, there is a selected ball and the game is in velocity editing mode" in new VelocityArrowFixture { arrowSystem.shouldRun shouldBe false - PlayState.selectedBall = Some(entity1) - PlayState.velocityEditingMode = true - PlayState.playing = false + playState.selectedBall = Some(entity1) + playState.gameState = State.ChangeVelocity arrowSystem.shouldRun shouldBe true } "draw an arrow in the canvas" in new VelocityArrowFixture { - PlayState.playing = false - PlayState.selectedBall = Some(entity1) - PlayState.velocityEditingMode = true - MouseState.coordinates = (10.0, 10.0) + playState.gameState = State.ChangeVelocity + playState.selectedBall = Some(entity1) + mouseState.coordinates = (10.0, 10.0) world hasA system(arrowSystem) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala index 83a41c9b..d427fa78 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala @@ -6,7 +6,7 @@ import scala.language.implicitConversions import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.given import dev.atedeg.ecscalademo.fixtures.VelocityFixture -import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Velocity } +import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, State, Velocity } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -15,21 +15,28 @@ class VelocityEditingSystemTest extends AnyWordSpec with Matchers with ECScalaDS "A VelocityEditingSystem" should { "run when the simulation is not running, there is a selected ball and the game is in velocity editing mode" in new VelocityFixture { system.shouldRun shouldBe false - PlayState.playing = false - PlayState.velocityEditingMode = true - PlayState.selectedBall = Some(entity1) + playState.gameState = State.ChangeVelocity + playState.selectedBall = Some(entity1) system.shouldRun shouldBe true } - "correctly update the velocity" in testNewExpectedVelocity(Point(1, 2), Velocity(2, 4)) - "limit the maximum velocity" in testNewExpectedVelocity(Point(3000, 0), Velocity(2000, 0)) + "correctly update the velocity" in new VelocityFixture { + testNewExpectedVelocity(playState, mouseState, Point(1, 2), Velocity(2, 4)) + } + "limit the maximum velocity" in new VelocityFixture { + testNewExpectedVelocity(playState, mouseState, Point(3000, 0), Velocity(2000, 0)) + } } - private def testNewExpectedVelocity(mouseCoordinates: Point, expectedVelocity: Velocity): Unit = new VelocityFixture { - PlayState.playing = false - PlayState.selectedBall = Some(entity1) - MouseState.clicked = true - PlayState.velocityEditingMode = true - MouseState.coordinates = mouseCoordinates + private def testNewExpectedVelocity( + pState: PlayState, + mState: MouseState, + mouseCoordinates: Point, + expectedVelocity: Velocity, + ): Unit = new VelocityFixture { + pState.gameState = State.ChangeVelocity + pState.selectedBall = Some(entity1) + mState.clicked = true + mState.coordinates = mouseCoordinates world.update(10) entity1.getComponent[Velocity].get shouldBe expectedVelocity } diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala index 567cc691..5ecdeb7d 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystemTest.scala @@ -10,7 +10,7 @@ import org.scalatestplus.mockito.MockitoSugar.mock import org.mockito.Mockito.when import dev.atedeg.ecscala.{ &:, CNil, World } import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ ECSCanvas, EnvironmentState, PlayState, Point, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ ECSCanvas, EnvironmentState, PlayState, Point, Position, State, Vector, Velocity } import dev.atedeg.ecscalademo.fixtures.WallCollisionsFixture import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer import scalafx.scene.paint.Color @@ -19,11 +19,11 @@ class WallCollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL "The WallCollisionSystem" should { "keep entities inside the canvas's borders" in new WallCollisionsFixture { - PlayState.playing = true + playState.gameState = State.Play val canvas = mock[ECSCanvas] when(canvas.width) thenReturn 100.0 when(canvas.height) thenReturn 100.0 - world addSystem (new WallCollisionSystem(canvas)) + world addSystem (new WallCollisionSystem(playState, environmentState, canvas)) world.update(1) val view = getView[Position &: Velocity &: CNil] from world forAll(view map (_._2)) { comps => @@ -33,12 +33,12 @@ class WallCollisionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL } } "change velocities to entities that collide with the canvas's borders" in new WallCollisionsFixture { - PlayState.playing = true - EnvironmentState.wallRestitution.value = 1 + playState.gameState = State.Play + environmentState.wallRestitution.value = 1 val canvas = mock[ECSCanvas] when(canvas.width) thenReturn 100.0 when(canvas.height) thenReturn 100.0 - world addSystem (new WallCollisionSystem(canvas)) + world addSystem (new WallCollisionSystem(playState, environmentState, canvas)) world.update(1) val view = getView[Position &: Velocity &: CNil] from world forAll(view map (_._2)) { comps => From 8c62b9a1a60837054d8eb02cb99ae44072e66671 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 17:57:45 +0200 Subject: [PATCH 185/447] Use state machine instead boolead conditions --- .../systems/BallCreationRenderingSystem.scala | 15 ++++++++----- .../systems/BallCreationSystem.scala | 10 +++++---- .../systems/BallSelectionSystem.scala | 15 ++++++++----- .../systems/ClearCanvasSystem.scala | 4 ++-- .../ecscalademo/systems/CollisionSystem.scala | 7 +++--- .../ecscalademo/systems/DragBallSystem.scala | 10 ++++----- .../ecscalademo/systems/FrictionSystem.scala | 7 +++--- .../ecscalademo/systems/MovementSystem.scala | 4 ++-- .../systems/RegionAssignmentSystem.scala | 2 +- .../ecscalademo/systems/RenderSystem.scala | 7 +++--- .../systems/VelocityArrowSystem.scala | 14 +++++++----- .../systems/VelocityEditingSystem.scala | 22 +++++++++---------- .../systems/WallCollisionSystem.scala | 13 +++++++---- 13 files changed, 75 insertions(+), 55 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala index cd94f427..6e42670b 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystem.scala @@ -5,17 +5,20 @@ import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.* import scalafx.scene.paint.Color as SfxColor -import scala.language.implicitConversions - /** * This [[System]] is used to render the ball that is about to be added to the [[World]]. * @param canvas * the canvas to draw in. */ -class BallCreationRenderingSystem(private val canvas: ECSCanvas) extends EmptySystem { +class BallCreationRenderingSystem( + private val playState: PlayState, + private val mouseState: MouseState, + private val canvas: ECSCanvas, +) extends EmptySystem { - override def shouldRun: Boolean = !PlayState.playing && PlayState.addBallMode + override def shouldRun: Boolean = playState.gameState == State.AddBalls - override def update(deltaTime: DeltaTime, world: World): Unit = - canvas.drawCircle(MouseState.coordinates, StartingState.startingRadius, StartingState.startingColor, 1) + override def update(deltaTime: DeltaTime, world: World): Unit = { + canvas.drawCircle(mouseState.coordinates, StartingState.startingRadius, StartingState.startingColor, 1) + } } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala index 57b8ec87..9da0d938 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallCreationSystem.scala @@ -9,18 +9,20 @@ import dev.atedeg.ecscalademo.* * This [[System]] is used to add a new ball into the [[World]]. If the mouse pointer is in the area of another ball, no * ball will be added. */ -class BallCreationSystem extends EmptySystem with ECScalaDSL { +class BallCreationSystem(private val playState: PlayState, private val mouseState: MouseState) + extends EmptySystem + with ECScalaDSL { - override def shouldRun: Boolean = MouseState.clicked && PlayState.addBallMode + override def shouldRun: Boolean = mouseState.clicked && playState.gameState == State.AddBalls override def update(deltaTime: DeltaTime, world: World): Unit = { val canBeCreated = world.getView[Position &: Circle &: CNil] map (_._2) forall { cl => val Position(point) &: Circle(radius, _) &: CNil = cl - !point.isOverlappedWith(MouseState.coordinates, radius, StartingState.startingRadius) + !point.isOverlappedWith(mouseState.coordinates, radius, StartingState.startingRadius) } if (canBeCreated) { world hasAn entity withComponents { - Position(MouseState.coordinates) &: + Position(mouseState.coordinates) &: Circle(StartingState.startingRadius, StartingState.startingColor) &: Velocity(StartingState.startingVelocity) &: Mass(StartingState.startingMass) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala index 5098fed0..d75b5211 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystem.scala @@ -8,18 +8,23 @@ import dev.atedeg.ecscalademo.* * This [[System]] is used to identify the selected ball. If a ball were selected, the [[PlayState.selectedBall]] * contains the [[Entity]] associated to the selected ball. */ -class BallSelectionSystem extends EmptySystem { +class BallSelectionSystem(private val playState: PlayState, private val mouseState: MouseState) extends EmptySystem { override def shouldRun: Boolean = - !PlayState.playing && MouseState.down && !PlayState.velocityEditingMode && !PlayState.addBallMode + (playState.gameState == State.Pause || playState.gameState == State.SelectBall) && mouseState.down override def update(deltaTime: DeltaTime, world: World): Unit = { val selectedEntity: Option[Entity] = world.getView[Position &: Circle &: CNil] find { e => val Position(point) &: Circle(radius, _) &: CNil = e._2 - MouseState.coordinates.isOverlappedWith(point, 0, radius) + mouseState.coordinates.isOverlappedWith(point, 0, radius) } map (_._1) - if (selectedEntity.isEmpty) then PlayState.selectedBall = None - else PlayState.selectedBall = Some(selectedEntity.get) + if (selectedEntity.isEmpty) { + playState.selectedBall = None + playState.gameState = State.Pause + } else { + playState.selectedBall = Some(selectedEntity.get) + playState.gameState = State.SelectBall + } } } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/ClearCanvasSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/ClearCanvasSystem.scala index 503915e2..a75cfd79 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/ClearCanvasSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/ClearCanvasSystem.scala @@ -2,8 +2,8 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.{ DeltaTime, EmptySystem, World } -import dev.atedeg.ecscalademo.ECSCanvas +import dev.atedeg.ecscalademo.{ ECSCanvas, State } -class ClearCanvasSystem(ecsCanvas: ECSCanvas) extends EmptySystem { +class ClearCanvasSystem(private val ecsCanvas: ECSCanvas) extends EmptySystem { override def update(deltaTime: DeltaTime, world: World): Unit = ecsCanvas.clear() } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/CollisionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/CollisionSystem.scala index c3fd3ba2..19a6b21c 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/CollisionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/CollisionSystem.scala @@ -6,10 +6,11 @@ import dev.atedeg.ecscala import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer import dev.atedeg.ecscalademo.given -import dev.atedeg.ecscalademo.{ Circle, Mass, PlayState, Point, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ Circle, Mass, PlayState, Point, Position, State, Vector, Velocity } -class CollisionSystem(private val regions: WritableSpacePartitionContainer) extends EmptySystem { - override def shouldRun: Boolean = PlayState.playing +class CollisionSystem(private val playState: PlayState, private val regions: WritableSpacePartitionContainer) + extends EmptySystem { + override def shouldRun: Boolean = playState.gameState == State.Play override def update(deltaTime: DeltaTime, world: World): Unit = { for { diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala index f4a5e2a1..044cd29e 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/DragBallSystem.scala @@ -9,20 +9,20 @@ import dev.atedeg.ecscalademo.{ PlayState, Position, StartingState, + State, } import dev.atedeg.ecscala.util.types.given /** * This [[System]] is used to update the selected ball's [[Position]] according to the mouse pointer. */ -class DragBallSystem extends EmptySystem { +class DragBallSystem(private val playState: PlayState, private val mouseState: MouseState) extends EmptySystem { - override def shouldRun: Boolean = - !PlayState.playing && PlayState.selectedBall.isDefined && PlayState.isDragging && !PlayState.velocityEditingMode + override def shouldRun: Boolean = playState.gameState == State.Dragging override def update(deltaTime: DeltaTime, world: World): Unit = { - PlayState.selectedBall match { - case Some(entity) => entity.addComponent(Position(MouseState.coordinates)) + playState.selectedBall match { + case Some(entity) => entity.addComponent(Position(mouseState.coordinates)) case _ => () } } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala index 968b53b3..6b8b9e12 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/FrictionSystem.scala @@ -11,9 +11,10 @@ import dev.atedeg.ecscalademo.* /** * The [[System]] that applies the friction to the balls that have a Velocity. */ -class FrictionSystem() extends System[Velocity &: CNil] { +class FrictionSystem(private val playState: PlayState, private val environmentState: EnvironmentState) + extends System[Velocity &: CNil] { - override def shouldRun: Boolean = PlayState.playing + override def shouldRun: Boolean = playState.gameState == State.Play override def update( entity: Entity, @@ -22,7 +23,7 @@ class FrictionSystem() extends System[Velocity &: CNil] { val Velocity(velocity) &: CNil = components if (velocity.norm > 0) { val frictionDirection = -1 * velocity.normalized - val friction = (frictionCoefficient.value * gravity) * frictionDirection + val friction = (environmentState.frictionCoefficient.value * environmentState.gravity) * frictionDirection val newVelocity = velocity + friction if (velocity dot newVelocity) < 0 then Velocity(0, 0) &: CNil else Velocity(newVelocity) &: CNil } else { diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/MovementSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/MovementSystem.scala index 93b800fc..87b1a3f4 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/MovementSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/MovementSystem.scala @@ -9,8 +9,8 @@ import dev.atedeg.ecscalademo.* /** * The [[System]] that updates the balls Positions given the updated Velocities */ -class MovementSystem extends System[Position &: Velocity &: CNil] { - override def shouldRun: Boolean = PlayState.playing +class MovementSystem(private val playState: PlayState) extends System[Position &: Velocity &: CNil] { + override def shouldRun: Boolean = playState.gameState == State.Play override def update(entity: Entity, components: Position &: Velocity &: CNil)( deltaTime: DeltaTime, diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RegionAssignmentSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RegionAssignmentSystem.scala index 702eab09..caa1b6e3 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RegionAssignmentSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RegionAssignmentSystem.scala @@ -4,7 +4,7 @@ import dev.atedeg.ecscala.{ &:, CNil, Deletable, DeltaTime, Entity, System, View import dev.atedeg.ecscala import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.util.WritableSpacePartitionContainer -import dev.atedeg.ecscalademo.{ Circle, Mass, Position, Velocity } +import dev.atedeg.ecscalademo.{ Circle, Mass, Position, State, Velocity } /** * This system populates the [[SpacePartitionContainer]] with all the required entities. This system is to be run before diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RenderSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RenderSystem.scala index 8eac1cc3..08c53131 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RenderSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/RenderSystem.scala @@ -2,14 +2,15 @@ package dev.atedeg.ecscalademo.systems import dev.atedeg.ecscala.* import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.{ Circle, Color, ECSCanvas, PlayState, Point, Position } +import dev.atedeg.ecscalademo.{ Circle, Color, ECSCanvas, PlayState, Point, Position, State } import dev.atedeg.ecscalademo.Vector /** * The [[System]] that renders the balls on their updated Positions. * @param ecsCanvas */ -class RenderSystem(ecsCanvas: ECSCanvas) extends System[Circle &: Position &: CNil] { +class RenderSystem(private val playState: PlayState, private val ecsCanvas: ECSCanvas) + extends System[Circle &: Position &: CNil] { private val selectedBallLineWidth = 3 private val regularBallLineWidth = 1 @@ -18,7 +19,7 @@ class RenderSystem(ecsCanvas: ECSCanvas) extends System[Circle &: Position &: CN world: World, view: View[Circle &: Position &: CNil], ): Deletable[Circle &: Position &: CNil] = { - val lineWidth = PlayState.selectedBall match { + val lineWidth = playState.selectedBall match { case Some(`entity`) => selectedBallLineWidth; case _ => regularBallLineWidth } val Circle(radius, color) &: Position(point) &: CNil = components diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystem.scala index 6b526128..f46e48b3 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityArrowSystem.scala @@ -5,16 +5,20 @@ import scala.language.implicitConversions import dev.atedeg.ecscala.{ DeltaTime, EmptySystem, World } import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscalademo.given -import dev.atedeg.ecscalademo.{ Color, ECSCanvas, MouseState, PlayState, Position } +import dev.atedeg.ecscalademo.{ Color, ECSCanvas, MouseState, PlayState, Position, State } -class VelocityArrowSystem(canvas: ECSCanvas) extends EmptySystem { +class VelocityArrowSystem( + private val playState: PlayState, + private val mouseState: MouseState, + private val canvas: ECSCanvas, +) extends EmptySystem { private val arrowColor = Color(255, 0, 0) private val arrowWidth = 2 - override def shouldRun = !PlayState.playing && PlayState.selectedBall.isDefined && PlayState.velocityEditingMode + override def shouldRun = playState.gameState == State.ChangeVelocity override def update(deltaTime: DeltaTime, world: World): Unit = { - val ballPosition = PlayState.selectedBall.get.getComponent[Position].get - canvas.drawLine(ballPosition, MouseState.coordinates, arrowColor, arrowWidth) + val ballPosition = playState.selectedBall.get.getComponent[Position].get + canvas.drawLine(ballPosition, mouseState.coordinates, arrowColor, arrowWidth) } } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystem.scala index a1c06d1f..9a18e142 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystem.scala @@ -4,24 +4,22 @@ import scala.language.implicitConversions import dev.atedeg.ecscalademo.given import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.{ DeltaTime, EmptySystem, World } -import dev.atedeg.ecscalademo.{ clamped, MouseState, PlayState, Position, Vector, Velocity } +import dev.atedeg.ecscalademo.{ clamped, MouseState, PlayState, Position, State, Vector, Velocity } -class VelocityEditingSystem extends EmptySystem { +class VelocityEditingSystem(private val playState: PlayState, private val mouseState: MouseState) extends EmptySystem { val minVelocityIntensity = 0 val maxVelocityIntensity = 1000 val intensityMultiplier = 2 - override def shouldRun = !PlayState.playing && PlayState.selectedBall.isDefined && PlayState.velocityEditingMode + override def shouldRun = playState.gameState == State.ChangeVelocity && mouseState.clicked override def update(deltaTime: DeltaTime, world: World): Unit = { - if (MouseState.clicked) { - val selectedBall = PlayState.selectedBall.get - val selectedBallPosition = selectedBall.getComponent[Position].get - val newVelocity = MouseState.coordinates - selectedBallPosition - val newDirection = newVelocity.normalized - val newIntensity = newVelocity.norm clamped (minVelocityIntensity, maxVelocityIntensity) - selectedBall.addComponent(Velocity(newDirection * newIntensity * intensityMultiplier)) - PlayState.velocityEditingMode = false - } + val selectedBall = playState.selectedBall.get + val selectedBallPosition = selectedBall.getComponent[Position].get + val newVelocity = mouseState.coordinates - selectedBallPosition + val newDirection = newVelocity.normalized + val newIntensity = newVelocity.norm clamped (minVelocityIntensity, maxVelocityIntensity) + selectedBall.addComponent(Velocity(newDirection * newIntensity * intensityMultiplier)) + playState.gameState = State.Pause } } diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala index 935fcc02..dd24b4f3 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/systems/WallCollisionSystem.scala @@ -12,6 +12,7 @@ import dev.atedeg.ecscalademo.{ PlayState, Point, Position, + State, Vector, Velocity, } @@ -24,9 +25,13 @@ import dev.atedeg.ecscalademo.given * @param canvas * the [[SpacePartitionContainer]] that will be read. */ -class WallCollisionSystem(private val canvas: ECSCanvas) extends System[Position &: Velocity &: Circle &: CNil] { +class WallCollisionSystem( + private val playState: PlayState, + private val environmentState: EnvironmentState, + private val canvas: ECSCanvas, +) extends System[Position &: Velocity &: Circle &: CNil] { - override def shouldRun: Boolean = PlayState.playing + override def shouldRun: Boolean = playState.gameState == State.Play override def update(entity: Entity, components: Position &: Velocity &: Circle &: CNil)( deltaTime: DeltaTime, @@ -38,8 +43,8 @@ class WallCollisionSystem(private val canvas: ECSCanvas) extends System[Position val collidesRight = x > canvas.width - radius val collidesTop = y < radius val collidesBottom = y > canvas.height - radius - lazy val mirroredHorizontalVelocity = -vx * EnvironmentState.wallRestitution.value - lazy val mirroredVerticalVelocity = -vy * EnvironmentState.wallRestitution.value + lazy val mirroredHorizontalVelocity = -vx * environmentState.wallRestitution.value + lazy val mirroredVerticalVelocity = -vy * environmentState.wallRestitution.value val newVelocity = Velocity( if (collidesLeft && vx < 0) || (collidesRight && vx > 0) then mirroredHorizontalVelocity else vx, if (collidesTop && vy < 0) || (collidesBottom && vy > 0) then mirroredVerticalVelocity else vy, From 225cec197518d18f9435e0a7b0d457924bb3db9b Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 17:58:23 +0200 Subject: [PATCH 186/447] Use state machine in handlers --- .../controller/MainViewController.scala | 146 ++++++++++-------- 1 file changed, 85 insertions(+), 61 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 2f0b5f15..95c9ef85 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -12,6 +12,7 @@ import dev.atedeg.ecscalademo.{ Point, Position, ScalaFXCanvas, + State, Vector, Velocity, } @@ -87,13 +88,14 @@ class MainViewController extends Initializable with ECScalaDSL { private lazy val ecsCanvas = ScalaFXCanvas(canvas) private val world: World = World() private var loop: GameLoop = _ + private var mouseState: MouseState = MouseState() + private var playState: PlayState = PlayState() + private var environmentState = EnvironmentState() private var isRunning = false private val addBallButtonLabel = "Add Ball" private val stopAddingButtonLabel = "Stop Adding" - private val playButtonLabel = "Play" - private val pauseButtonLabel = "Pause" override def initialize(url: URL, resourceBundle: ResourceBundle): Unit = { createEntitiesWithComponents() @@ -101,19 +103,14 @@ class MainViewController extends Initializable with ECScalaDSL { loop = GameLoop(dt => { world.update(dt) - MouseState.down = false - MouseState.up = false - // This check is made here because we cannot pass buttons to the systems - if (!PlayState.playing && PlayState.selectedBall.isDefined) { - changeVelBtn.disable = false - } else { - changeVelBtn.disable = true - } + mouseState.down = false + mouseState.up = false + refreshUiElements() }) fps.text.bindBidirectional(loop.fps, new NumberStringConverter("FPS: ")) - EnvironmentState.frictionCoefficient <== fcSlider.value - EnvironmentState.wallRestitution <== wrSlider.value + environmentState.frictionCoefficient <== fcSlider.value + environmentState.wallRestitution <== wrSlider.value val decimalFormat = new DecimalFormat() decimalFormat.setMaximumFractionDigits(2) decimalFormat.setMinimumFractionDigits(2) @@ -123,62 +120,89 @@ class MainViewController extends Initializable with ECScalaDSL { loop.start } - def onMouseMovedHandler(event: MouseEvent): Unit = { - MouseState.coordinates = Point(event.getX, event.getY) + private def refreshUiElements(): Unit = { + playState.gameState match { + case State.Play => { + playPauseBtn.text = "Pause" + addBallBtn.text = addBallButtonLabel + playPauseBtn.disable = false + addBallBtn.disable = true + changeVelBtn.disable = true + resetBtn.disable = true + } + case State.Pause => { + playPauseBtn.text = "Play" + addBallBtn.text = addBallButtonLabel + playPauseBtn.disable = false + addBallBtn.disable = false + changeVelBtn.disable = true + resetBtn.disable = false + } + case State.AddBalls => { + addBallBtn.text = stopAddingButtonLabel + playPauseBtn.disable = false + addBallBtn.disable = false + changeVelBtn.disable = true + resetBtn.disable = false + } + case State.ChangeVelocity => { + playPauseBtn.disable = false + addBallBtn.disable = true + changeVelBtn.disable = false + resetBtn.disable = false + } + case State.Dragging => { + playPauseBtn.disable = true + addBallBtn.disable = true + changeVelBtn.disable = true + resetBtn.disable = true + } + case State.SelectBall => { + playPauseBtn.disable = false + addBallBtn.disable = false + changeVelBtn.disable = false + resetBtn.disable = false + } + } } + def onMouseMovedHandler(event: MouseEvent): Unit = mouseState.coordinates = Point(event.getX, event.getY) + def onMousePressedHandler(event: MouseEvent): Unit = { - MouseState.down = true - MouseState.clicked = true + mouseState.down = true + mouseState.clicked = true } def onMouseReleasedHandler(event: MouseEvent): Unit = { - MouseState.up = true - MouseState.clicked = false - PlayState.isDragging = false + mouseState.up = true + mouseState.clicked = false + playState.gameState = if playState.gameState == State.Dragging then State.SelectBall else playState.gameState } def onDragDetectedHandler(event: MouseEvent): Unit = { - MouseState.coordinates = Point(event.getX, event.getY) - PlayState.isDragging = true + mouseState.coordinates = Point(event.getX, event.getY) + playState.gameState = if playState.gameState == State.AddBalls then playState.gameState else State.Dragging } def onPlayPauseClickHandler(): Unit = { - PlayState.playing = !isRunning - PlayState.selectedBall = None isRunning = !isRunning - playPauseBtn.text = if isRunning then pauseButtonLabel else playButtonLabel - changeVelBtn.disable = isRunning - addBallBtn.disable = isRunning - addBallBtn.text = addBallButtonLabel - wrSlider.disable = isRunning - fcSlider.disable = isRunning - if (!isRunning) { - PlayState.velocityEditingMode = false - PlayState.addBallMode = false - } - resetBtn.disable = isRunning + playState.gameState = if isRunning then State.Play else State.Pause } - def onAddBallButtonHandler(): Unit = { - PlayState.addBallMode = !PlayState.addBallMode - addBallBtn.text = if PlayState.addBallMode then stopAddingButtonLabel else addBallButtonLabel - PlayState.velocityEditingMode = false - changeVelBtn.disable = true - } + def onAddBallButtonHandler(): Unit = playState.gameState = + if playState.gameState == State.AddBalls then State.Pause else State.AddBalls - def onChangeVelocityButtonHandler(): Unit = { - PlayState.addBallMode = false - PlayState.velocityEditingMode = true - addBallBtn.disable = false - } + def onChangeVelocityButtonHandler(): Unit = playState.gameState = + if playState.gameState == State.SelectBall then State.ChangeVelocity else State.Pause def onResetClickHandler(): Unit = { - if (!PlayState.playing) { - PlayState.selectedBall = Option.empty - ecsCanvas.clear() - clearAll from world - createEntitiesWithComponents() + playState.gameState match { + case State.Play | State.Dragging => () + case _ => { + playState.selectedBall = None + clearAll from world + createEntitiesWithComponents() + } } } @@ -193,17 +217,17 @@ class MainViewController extends Initializable with ECScalaDSL { private def addSystemsToWorld() = { val container = WritableSpacePartitionContainer() world hasA system(ClearCanvasSystem(ecsCanvas)) - world hasA system(BallCreationSystem()) - world hasA system(BallCreationRenderingSystem(ecsCanvas)) - world hasA system(VelocityEditingSystem()) - world hasA system(VelocityArrowSystem(ecsCanvas)) - world hasA system(BallSelectionSystem()) - world hasA system(DragBallSystem()) + world hasA system(BallCreationSystem(playState, mouseState)) + world hasA system(BallCreationRenderingSystem(playState, mouseState, ecsCanvas)) + world hasA system(VelocityEditingSystem(playState, mouseState)) + world hasA system(VelocityArrowSystem(playState, mouseState, ecsCanvas)) + world hasA system(BallSelectionSystem(playState, mouseState)) + world hasA system(DragBallSystem(playState, mouseState)) + world hasA system(FrictionSystem(playState, environmentState)) + world hasA system(MovementSystem(playState)) world hasA system(RegionAssignmentSystem(container)) - world hasA system(FrictionSystem()) - world hasA system(MovementSystem()) - world hasA system(CollisionSystem(container)) - world hasA system(WallCollisionSystem(ecsCanvas)) - world hasA system(RenderSystem(ecsCanvas)) + world hasA system(CollisionSystem(playState, container)) + world hasA system(WallCollisionSystem(playState, environmentState, ecsCanvas)) + world hasA system(RenderSystem(playState, ecsCanvas)) } } From 62d54243d45c9e9666a1e51bbd66e41cef14ef9c Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 18:50:00 +0200 Subject: [PATCH 187/447] Refactor in method the buttons status accordin to FSM --- .../controller/MainViewController.scala | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 95c9ef85..2ec63284 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -125,47 +125,41 @@ class MainViewController extends Initializable with ECScalaDSL { case State.Play => { playPauseBtn.text = "Pause" addBallBtn.text = addBallButtonLabel - playPauseBtn.disable = false - addBallBtn.disable = true - changeVelBtn.disable = true - resetBtn.disable = true + setButtonState(false, true, true, true) } case State.Pause => { playPauseBtn.text = "Play" addBallBtn.text = addBallButtonLabel - playPauseBtn.disable = false - addBallBtn.disable = false - changeVelBtn.disable = true - resetBtn.disable = false + setButtonState(false, false, true, false) } case State.AddBalls => { addBallBtn.text = stopAddingButtonLabel - playPauseBtn.disable = false - addBallBtn.disable = false - changeVelBtn.disable = true - resetBtn.disable = false + setButtonState(false, false, true, false) } case State.ChangeVelocity => { - playPauseBtn.disable = false - addBallBtn.disable = true - changeVelBtn.disable = false - resetBtn.disable = false + setButtonState(false, true, false, false) } case State.Dragging => { - playPauseBtn.disable = true - addBallBtn.disable = true - changeVelBtn.disable = true - resetBtn.disable = true + setButtonState(true, true, true, true) } case State.SelectBall => { - playPauseBtn.disable = false - addBallBtn.disable = false - changeVelBtn.disable = false - resetBtn.disable = false + setButtonState(false, false, false, false) } } } + private def setButtonState( + isPlayPauseDisable: Boolean, + isAddBallDiasable: Boolean, + isChangeVelDisable: Boolean, + isResetDisable: Boolean, + ): Unit = { + playPauseBtn.disable = isPlayPauseDisable + addBallBtn.disable = isAddBallDiasable + changeVelBtn.disable = isChangeVelDisable + resetBtn.disable = isResetDisable + } + def onMouseMovedHandler(event: MouseEvent): Unit = mouseState.coordinates = Point(event.getX, event.getY) def onMousePressedHandler(event: MouseEvent): Unit = { From 33d8e8446fe34d1c7b221e79eafa11d7f2e2fae5 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 18:52:10 +0200 Subject: [PATCH 188/447] Fix BallSelectionSystem enable system condition --- .../atedeg/ecscalademo/systems/BallSelectionSystemTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala index 96896142..4d8fc5b8 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallSelectionSystemTest.scala @@ -66,7 +66,7 @@ class BallSelectionSystemTest extends AnyWordSpec with Matchers with ECScalaDSL } private def enableSystemCondition(playState: PlayState, mouseState: MouseState): Unit = { - playState.gameState = State.Play + playState.gameState = State.SelectBall mouseState.down = true } From 5d16893e03a5a38ef3522e7fd244e35e3cb36670 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 19:10:18 +0200 Subject: [PATCH 189/447] Fix velocity editing test --- .../systems/VelocityEditingSystemTest.scala | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala index d427fa78..9ec446c8 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/VelocityEditingSystemTest.scala @@ -1,33 +1,37 @@ package dev.atedeg.ecscalademo.systems +import dev.atedeg.ecscala.World import dev.atedeg.ecscala.dsl.ECScalaDSL import scala.language.implicitConversions import dev.atedeg.ecscala.util.types.given -import dev.atedeg.ecscalademo.given +import dev.atedeg.ecscalademo import dev.atedeg.ecscalademo.fixtures.VelocityFixture import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, State, Velocity } import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class VelocityEditingSystemTest extends AnyWordSpec with Matchers with ECScalaDSL { +class VelocityEditingSystemTest extends AnyWordSpec with Matchers { "A VelocityEditingSystem" should { "run when the simulation is not running, there is a selected ball and the game is in velocity editing mode" in new VelocityFixture { system.shouldRun shouldBe false playState.gameState = State.ChangeVelocity playState.selectedBall = Some(entity1) + mouseState.clicked = true system.shouldRun shouldBe true } "correctly update the velocity" in new VelocityFixture { - testNewExpectedVelocity(playState, mouseState, Point(1, 2), Velocity(2, 4)) + testNewExpectedVelocity(world, system, playState, mouseState, Point(1, 2), Velocity(2, 4)) } "limit the maximum velocity" in new VelocityFixture { - testNewExpectedVelocity(playState, mouseState, Point(3000, 0), Velocity(2000, 0)) + testNewExpectedVelocity(world, system, playState, mouseState, Point(3000, 0), Velocity(2000, 0)) } } private def testNewExpectedVelocity( + wrld: World, + sys: VelocityEditingSystem, pState: PlayState, mState: MouseState, mouseCoordinates: Point, @@ -37,7 +41,8 @@ class VelocityEditingSystemTest extends AnyWordSpec with Matchers with ECScalaDS pState.selectedBall = Some(entity1) mState.clicked = true mState.coordinates = mouseCoordinates - world.update(10) + sys.shouldRun shouldBe true + wrld.update(10) entity1.getComponent[Velocity].get shouldBe expectedVelocity } } From 6e7bd709908687fe9777036c22f864c5053ac21d Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 19:10:35 +0200 Subject: [PATCH 190/447] Fix typo in assignment --- .../systems/BallCreationRenderingSystemTest.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala index 7aec1a9b..ab1c82c7 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/systems/BallCreationRenderingSystemTest.scala @@ -24,6 +24,7 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc "A RenderingCreationBallSystem" when { "the game is not running" should { "be enabled" in new BallCreationRenderingSystemFixture { + system.shouldRun shouldBe false enableSystemCondition(playState) system.shouldRun shouldBe true } @@ -42,6 +43,6 @@ class BallCreationRenderingSystemTest extends AnyWordSpec with Matchers with Moc } } - private def enableSystemCondition(playState: PlayState): Unit = playState.gameState == State.AddBalls - private def disableSystemCondition(playState: PlayState): Unit = playState.gameState == State.AddBalls + private def enableSystemCondition(playState: PlayState): Unit = playState.gameState = State.AddBalls + private def disableSystemCondition(playState: PlayState): Unit = playState.gameState = State.Pause } From 1e0abfce595a08fd63c988c74f08ee85a0419170 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 19:12:18 +0200 Subject: [PATCH 191/447] Revert to parallel test mode --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 93b9e471..6da62252 100644 --- a/build.sbt +++ b/build.sbt @@ -188,7 +188,7 @@ lazy val demo = project .dependsOn(core) .settings( publish / skip := true, - Test / parallelExecution := false, + //Test / parallelExecution := false, assembly / assemblyJarName := "ECScalaDemo.jar", githubWorkflowArtifactUpload := false, libraryDependencies ++= scalaTest, From 3a8445a98becb556239c29e3e6b98510ea736b02 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 19:36:21 +0200 Subject: [PATCH 192/447] Remove Java 8 from CI --- .github/workflows/ci.yml | 8 ++++---- build.sbt | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 765c5e34..6b0c218a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: matrix: os: [ubuntu-latest] scala: [3.0.1] - java: [adopt@1.8, adopt@1.11, adopt@1.16] + java: [adopt@1.11, adopt@1.16] runs-on: ${{ matrix.os }} steps: - name: Checkout current branch (full) @@ -59,11 +59,11 @@ jobs: run: sbt ++${{ matrix.scala }} test - name: Generate JaCoCo report - if: ${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' + if: ${{ matrix.java }} == 'adopt@1.11' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' run: sbt ++${{ matrix.scala }} 'core / jacoco' - name: Publish coverage to codecov - if: ${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' + if: ${{ matrix.java }} == 'adopt@1.11' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request' uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -94,7 +94,7 @@ jobs: matrix: os: [ubuntu-latest] scala: [3.0.1] - java: [adopt@1.8] + java: [adopt@1.11] runs-on: ${{ matrix.os }} steps: - name: Checkout current branch (full) diff --git a/build.sbt b/build.sbt index 6da62252..a513d149 100644 --- a/build.sbt +++ b/build.sbt @@ -40,7 +40,7 @@ ThisBuild / developers := List( ) ThisBuild / githubWorkflowScalaVersions := Seq("3.0.1") -ThisBuild / githubWorkflowJavaVersions := Seq("adopt@1.8", "adopt@1.11", "adopt@1.16") +ThisBuild / githubWorkflowJavaVersions := Seq("adopt@1.11", "adopt@1.16") ThisBuild / githubWorkflowTargetBranches := Seq("master", "develop") ThisBuild / githubWorkflowTargetTags ++= Seq("v*") ThisBuild / githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))) @@ -57,14 +57,14 @@ ThisBuild / githubWorkflowBuild := Seq( WorkflowStep.Sbt( List("core / jacoco"), cond = Some( - "${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", + "${{ matrix.java }} == 'adopt@1.11' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", ), name = Some("Generate JaCoCo report"), ), WorkflowStep.Use( UseRef.Public("codecov", "codecov-action", "v2"), cond = Some( - "${{ matrix.java }} == 'adopt@1.8' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", + "${{ matrix.java }} == 'adopt@1.11' && ${{ matrix.scala }} == '3.0.1' && github.event_name != 'pull_request'", ), name = Some("Publish coverage to codecov"), params = Map( From cac0fd8dc100d02c2e870d8b967b854d7b42c16d Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 19:36:36 +0200 Subject: [PATCH 193/447] Add exlpicit parameter name --- .../controller/MainViewController.scala | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 2ec63284..08d14c30 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -125,25 +125,55 @@ class MainViewController extends Initializable with ECScalaDSL { case State.Play => { playPauseBtn.text = "Pause" addBallBtn.text = addBallButtonLabel - setButtonState(false, true, true, true) + setButtonState( + isPlayPauseDisable = false, + isAddBallDiasable = true, + isChangeVelDisable = true, + isResetDisable = true, + ) } case State.Pause => { playPauseBtn.text = "Play" addBallBtn.text = addBallButtonLabel - setButtonState(false, false, true, false) + setButtonState( + isPlayPauseDisable = false, + isAddBallDiasable = false, + isChangeVelDisable = true, + isResetDisable = false, + ) } case State.AddBalls => { addBallBtn.text = stopAddingButtonLabel - setButtonState(false, false, true, false) + setButtonState( + isPlayPauseDisable = false, + isAddBallDiasable = false, + isChangeVelDisable = true, + isResetDisable = false, + ) } case State.ChangeVelocity => { - setButtonState(false, true, false, false) + setButtonState( + isPlayPauseDisable = false, + isAddBallDiasable = true, + isChangeVelDisable = false, + isResetDisable = false, + ) } case State.Dragging => { - setButtonState(true, true, true, true) + setButtonState( + isPlayPauseDisable = true, + isAddBallDiasable = true, + isChangeVelDisable = true, + isResetDisable = true, + ) } case State.SelectBall => { - setButtonState(false, false, false, false) + setButtonState( + isPlayPauseDisable = false, + isAddBallDiasable = false, + isChangeVelDisable = false, + isResetDisable = false, + ) } } } From d2f8ef46fa09b5438296c88eadd463c7347c44fe Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 20:23:51 +0200 Subject: [PATCH 194/447] Remove comment --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index a513d149..90c20cee 100644 --- a/build.sbt +++ b/build.sbt @@ -188,7 +188,6 @@ lazy val demo = project .dependsOn(core) .settings( publish / skip := true, - //Test / parallelExecution := false, assembly / assemblyJarName := "ECScalaDemo.jar", githubWorkflowArtifactUpload := false, libraryDependencies ++= scalaTest, From 8b37f6abc9d7e42c58c52720e0f710d0f3331d62 Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 20:25:37 +0200 Subject: [PATCH 195/447] Remove unused import --- .../scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala index 747328e0..dfc8e152 100644 --- a/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala +++ b/demo/src/test/scala/dev/atedeg/ecscalademo/fixtures/VelocityFixture.scala @@ -3,7 +3,6 @@ package dev.atedeg.ecscalademo.fixtures import dev.atedeg.ecscala.util.types.given import dev.atedeg.ecscala.World import dev.atedeg.ecscala.dsl.ECScalaDSL -import dev.atedeg.ecscalademo import dev.atedeg.ecscalademo.{ MouseState, PlayState, Point, Position, Vector, Velocity } import dev.atedeg.ecscalademo.systems.VelocityEditingSystem From ad1cfb3331cc88622d74f9048fcc048fc7cbe4ab Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 21:23:52 +0200 Subject: [PATCH 196/447] Change variables name into a more self-explain ones --- .../controller/MainViewController.scala | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala index 08d14c30..2e2acdbe 100644 --- a/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala +++ b/demo/src/main/scala/dev/atedeg/ecscalademo/controller/MainViewController.scala @@ -70,20 +70,20 @@ class MainViewController extends Initializable with ECScalaDSL { private lazy val fps: Label = new Label(fpsDelegate) @FXML - private var wrSliderDelegate: JfxSlider = _ - private lazy val wrSlider = new Slider(wrSliderDelegate) + private var wallRestitutionSliderDelegate: JfxSlider = _ + private lazy val wallRestitutionSlider = new Slider(wallRestitutionSliderDelegate) @FXML - private var fcSliderDelegate: JfxSlider = _ - private lazy val fcSlider = new Slider(fcSliderDelegate) + private var frictionCoefficientSliderDelegate: JfxSlider = _ + private lazy val frictionCoefficientSlider = new Slider(frictionCoefficientSliderDelegate) @FXML - private var fcLabelDelegate: JfxLabel = _ - private lazy val fcLabel = new Label(fcLabelDelegate) + private var wallRestitutionLabelDelegate: JfxLabel = _ + private lazy val wallRestitutionLabel = new Label(wallRestitutionLabelDelegate) @FXML - private var wrLabelDelegate: JfxLabel = _ - private lazy val wrLabel = new Label(wrLabelDelegate) + private var frictionCoefficientLabelDelegate: JfxLabel = _ + private lazy val frictionCoefficientLabel = new Label(frictionCoefficientLabelDelegate) private lazy val ecsCanvas = ScalaFXCanvas(canvas) private val world: World = World() @@ -109,13 +109,14 @@ class MainViewController extends Initializable with ECScalaDSL { }) fps.text.bindBidirectional(loop.fps, new NumberStringConverter("FPS: ")) - environmentState.frictionCoefficient <== fcSlider.value - environmentState.wallRestitution <== wrSlider.value + environmentState.frictionCoefficient <== frictionCoefficientSlider.value + environmentState.wallRestitution <== wallRestitutionSlider.value val decimalFormat = new DecimalFormat() decimalFormat.setMaximumFractionDigits(2) decimalFormat.setMinimumFractionDigits(2) - fcLabel.text.bindBidirectional(fcSlider.value, new NumberStringConverter(decimalFormat)) - wrLabel.text.bindBidirectional(wrSlider.value, new NumberStringConverter(decimalFormat)) + frictionCoefficientLabel.text + .bindBidirectional(frictionCoefficientSlider.value, new NumberStringConverter(decimalFormat)) + wallRestitutionLabel.text.bindBidirectional(wallRestitutionSlider.value, new NumberStringConverter(decimalFormat)) loop.start } From 1cb91b65b73b03281bc4d867be037407f536f42f Mon Sep 17 00:00:00 2001 From: Nicolas Farabegoli Date: Thu, 30 Sep 2021 21:25:55 +0200 Subject: [PATCH 197/447] Set new ids according to new variables --- demo/src/main/resources/MainView.fxml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/src/main/resources/MainView.fxml b/demo/src/main/resources/MainView.fxml index cd3c3173..2280b42f 100644 --- a/demo/src/main/resources/MainView.fxml +++ b/demo/src/main/resources/MainView.fxml @@ -48,13 +48,13 @@