From 6f9ba6cf29f18473de7bb8c845b626134abb65d3 Mon Sep 17 00:00:00 2001 From: Martin Jakobsson Date: Mon, 22 Apr 2024 21:54:54 +0200 Subject: [PATCH] Refactor: Improved Channel code --- .../main/scala/hexacraft/util/events.scala | 8 +++++++ .../main/scala/hexacraft/game/GameScene.scala | 16 +++++++------ .../src/main/scala/hexacraft/game/Menus.scala | 4 ++++ .../scala/hexacraft/main/MainRouter.scala | 23 ++++++++----------- .../scala/hexacraft/game/GameSceneTest.scala | 16 +++++-------- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/common/src/main/scala/hexacraft/util/events.scala b/common/src/main/scala/hexacraft/util/events.scala index fce1f13a..fd0f20f1 100644 --- a/common/src/main/scala/hexacraft/util/events.scala +++ b/common/src/main/scala/hexacraft/util/events.scala @@ -2,6 +2,7 @@ package hexacraft.util import scala.collection.mutable import scala.collection.mutable.ArrayBuffer +import scala.reflect.ClassTag trait Tracker[E] { def notify(event: E): Unit @@ -85,4 +86,11 @@ object Channel { tx.rx = rx (tx, rx) } + + inline def wrap[E] = [T] => + (wrapFn: Sender[E] => T) => { + val (tx, rx) = Channel[E]() + val value = wrapFn(tx) + (value, rx) + } } diff --git a/game/src/main/scala/hexacraft/game/GameScene.scala b/game/src/main/scala/hexacraft/game/GameScene.scala index 6ada23d2..8785e229 100644 --- a/game/src/main/scala/hexacraft/game/GameScene.scala +++ b/game/src/main/scala/hexacraft/game/GameScene.scala @@ -34,7 +34,7 @@ object GameScene { blockLoader: BlockTextureLoader, initialWindowSize: WindowSize, audioSystem: AudioSystem - )(eventHandler: Channel.Sender[GameScene.Event]): GameScene = { + ): (GameScene, Channel.Receiver[GameScene.Event]) = { val blockSpecs = makeBlockSpecs() val blockTextureMapping = loadBlockTextures(blockSpecs, blockLoader) @@ -74,10 +74,12 @@ object GameScene { val walkSoundBuffer1 = audioSystem.loadSoundBuffer("sounds/walk1.ogg") val walkSoundBuffer2 = audioSystem.loadSoundBuffer("sounds/walk2.ogg") + val (tx, rx) = Channel[GameScene.Event]() + val s = new GameScene( net, audioSystem, - eventHandler, + tx, blockTextureIndices, crosshairShader, crosshairVAO, @@ -109,7 +111,7 @@ object GameScene { } net.runClient() - s + (s, rx) } private def makeBlockInHandRenderer( @@ -279,14 +281,14 @@ class GameScene private ( val (tx, rx) = Channel[PauseMenu.Event]() val pauseMenu = PauseMenu(tx) - rx.onEvent({ + rx.onEvent { case Unpause => overlays -= pauseMenu pauseMenu.unload() setPaused(false) case QuitGame => eventHandler.send(GameScene.Event.GameQuit) - }) + } overlays += pauseMenu setPaused(true) @@ -308,7 +310,7 @@ class GameScene private ( val (tx, rx) = Channel[InventoryBox.Event]() val inventoryScene = InventoryBox(player.inventory, blockTextureIndices)(tx) - rx.onEvent({ + rx.onEvent { case BoxClosed => overlays -= inventoryScene inventoryScene.unload() @@ -317,7 +319,7 @@ class GameScene private ( case InventoryUpdated(inv) => player.inventory = inv toolbar.onInventoryUpdated(inv) - }) + } overlays += inventoryScene isInPopup = true diff --git a/game/src/main/scala/hexacraft/game/Menus.scala b/game/src/main/scala/hexacraft/game/Menus.scala index 4d787eae..c6814a51 100644 --- a/game/src/main/scala/hexacraft/game/Menus.scala +++ b/game/src/main/scala/hexacraft/game/Menus.scala @@ -80,6 +80,10 @@ object Menus { case Host(worldInfo: WorldInfo) case GoBack } + + def create(saveFolder: File, fs: FileSystem): (HostWorldChooserMenu, Channel.Receiver[Event]) = { + Channel.wrap[Event](tx => new HostWorldChooserMenu(saveFolder, fs)(tx)) + } } class HostWorldChooserMenu(saveFolder: File, fs: FileSystem)(onEvent: Channel.Sender[HostWorldChooserMenu.Event]) diff --git a/game/src/main/scala/hexacraft/main/MainRouter.scala b/game/src/main/scala/hexacraft/main/MainRouter.scala index b32dbf08..f59a9b0e 100644 --- a/game/src/main/scala/hexacraft/main/MainRouter.scala +++ b/game/src/main/scala/hexacraft/main/MainRouter.scala @@ -1,6 +1,7 @@ package hexacraft.main import hexacraft.game.* +import hexacraft.game.Menus.JoinWorldChooserMenu import hexacraft.gui.Scene import hexacraft.infra.audio.AudioSystem import hexacraft.infra.fs.FileSystem @@ -34,8 +35,7 @@ class MainRouter( case SceneRoute.Main => import Menus.MainMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.MainMenu(multiplayerEnabled)(tx) + val (scene, rx) = Channel.wrap[Event](tx => Menus.MainMenu(multiplayerEnabled)(tx)) rx.onEvent { case Event.Play => route(SceneRoute.WorldChooser) @@ -49,8 +49,7 @@ class MainRouter( case SceneRoute.WorldChooser => import Menus.WorldChooserMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.WorldChooserMenu(saveFolder, fs)(tx) + val (scene, rx) = Channel.wrap[Event](tx => Menus.WorldChooserMenu(saveFolder, fs)(tx)) rx.onEvent { case Event.StartGame(saveDir, settings) => @@ -64,8 +63,7 @@ class MainRouter( case SceneRoute.NewWorld => import Menus.NewWorldMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.NewWorldMenu(saveFolder)(tx) + val (scene, rx) = Channel.wrap[Event](tx => Menus.NewWorldMenu(saveFolder)(tx)) rx.onEvent { case Event.StartGame(saveDir, settings) => @@ -78,8 +76,7 @@ class MainRouter( case SceneRoute.Multiplayer => import Menus.MultiplayerMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.MultiplayerMenu(tx) + val (scene, rx) = Channel.wrap[Event](tx => Menus.MultiplayerMenu(tx)) rx.onEvent { case Event.Join => route(SceneRoute.JoinWorld) @@ -92,8 +89,7 @@ class MainRouter( case SceneRoute.JoinWorld => import Menus.JoinWorldChooserMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.JoinWorldChooserMenu(tx) + val (scene, rx) = Channel.wrap[Event](tx => new Menus.JoinWorldChooserMenu(tx)) rx.onEvent { case Event.Join(address, port) => @@ -107,8 +103,7 @@ class MainRouter( case SceneRoute.HostWorld => import Menus.HostWorldChooserMenu.Event - val (tx, rx) = Channel[Event]() - val scene = Menus.HostWorldChooserMenu(saveFolder, fs)(tx) + val (scene, rx) = Menus.HostWorldChooserMenu.create(saveFolder, fs) rx.onEvent { case Event.Host(f) => @@ -133,8 +128,8 @@ class MainRouter( } val networkHandler = NetworkHandler(isHosting, isOnline, worldProvider, client) - val (tx, rx) = Channel[GameScene.Event]() - val scene = GameScene.create(networkHandler, kb, BlockTextureLoader.instance, window.windowSize, audioSystem)(tx) + val (scene, rx) = + GameScene.create(networkHandler, kb, BlockTextureLoader.instance, window.windowSize, audioSystem) rx.onEvent { case GameScene.Event.GameQuit => diff --git a/game/src/test/scala/hexacraft/game/GameSceneTest.scala b/game/src/test/scala/hexacraft/game/GameSceneTest.scala index 7af62421..2ad9e6d1 100644 --- a/game/src/test/scala/hexacraft/game/GameSceneTest.scala +++ b/game/src/test/scala/hexacraft/game/GameSceneTest.scala @@ -5,7 +5,7 @@ import hexacraft.gui.Event.{KeyEvent, MouseClickEvent} import hexacraft.infra.audio.AudioSystem import hexacraft.infra.gpu.OpenGL import hexacraft.infra.window.* -import hexacraft.util.{Channel, Tracker} +import hexacraft.util.Tracker import hexacraft.world.{CylinderSize, FakeWorldProvider} import munit.FunSuite @@ -27,8 +27,7 @@ class GameSceneTest extends FunSuite { val keyboard: GameKeyboard = _ => false val audioSystem = AudioSystem.createNull() - val (tx, _) = Channel[GameScene.Event]() - val gameScene1 = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem)(tx) + val (gameScene1, _) = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem) gameScene1.unload() // Start listening to OpenGL events @@ -36,7 +35,7 @@ class GameSceneTest extends FunSuite { OpenGL.trackEvents(tracker) // Load and unload the game again - val gameScene = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem)(tx) + val (gameScene, _) = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem) gameScene.unload() val shadersAdded = tracker.events.collect: @@ -60,9 +59,8 @@ class GameSceneTest extends FunSuite { val textureLoader = new FakeBlockTextureLoader val audioSystem = AudioSystem.createNull() - val (tx, rx) = Channel[GameScene.Event]() + val (gameScene, rx) = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem) val gameSceneTracker = Tracker.fromRx(rx) - val gameScene = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem)(tx) gameScene.handleEvent(Event.KeyEvent(KeyboardKey.Escape, 0, KeyAction.Press, KeyMods.none)) @@ -88,9 +86,8 @@ class GameSceneTest extends FunSuite { val textureLoader = new FakeBlockTextureLoader val audioSystem = AudioSystem.createNull() - val (tx, rx) = Channel[GameScene.Event]() + val (gameScene, rx) = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem) val gameSceneTracker = Tracker.fromRx(rx) - val gameScene = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem)(tx) gameScene.player.flying = false @@ -131,9 +128,8 @@ class GameSceneTest extends FunSuite { val textureLoader = new FakeBlockTextureLoader val audioSystem = AudioSystem.createNull() - val (tx, rx) = Channel[GameScene.Event]() + val (gameScene, rx) = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem) val gameSceneTracker = Tracker.fromRx(rx) - val gameScene = GameScene.create(networkHandler, keyboard, textureLoader, windowSize, audioSystem)(tx) gameScene.player.flying = false