diff --git a/forge/src/test/java/fr/thesmyler/terramap/TerramapTest.java b/forge/src/test/java/fr/thesmyler/terramap/TerramapTest.java index 06263044..b78eed0e 100644 --- a/forge/src/test/java/fr/thesmyler/terramap/TerramapTest.java +++ b/forge/src/test/java/fr/thesmyler/terramap/TerramapTest.java @@ -1,11 +1,11 @@ package fr.thesmyler.terramap; -import fr.thesmyler.smylibgui.SmyLibGuiTest; import fr.thesmyler.terramap.maps.raster.MapStylesLibrary; +import net.smyler.smylib.SmyLibTest; import org.apache.logging.log4j.LogManager; import org.junit.jupiter.api.BeforeEach; -public class TerramapTest extends SmyLibGuiTest { +public class TerramapTest extends SmyLibTest { @BeforeEach public void initTerramap() { diff --git a/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapControllerTest.java b/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapControllerTest.java index 366308f7..b6801f84 100644 --- a/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapControllerTest.java +++ b/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapControllerTest.java @@ -1,8 +1,9 @@ package fr.thesmyler.terramap.gui.widgets.map; -import net.smyler.smylib.gui.TestingWidgetContainer; +import net.smyler.smylib.game.TestGameClient; import fr.thesmyler.terramap.MapContext; import fr.thesmyler.terramap.TerramapTest; +import net.smyler.smylib.gui.screen.Screen; import net.smyler.smylib.math.Vec2dMutable; import net.smyler.terramap.util.geo.GeoPointImmutable; import org.junit.jupiter.api.BeforeEach; @@ -15,16 +16,19 @@ public class MapControllerTest extends TerramapTest { public static GeoPointImmutable PARIS = new GeoPointImmutable(2.350987d, 48.856667d); - private TestingWidgetContainer screen; + private Screen screen; private MapWidget map; private MapController controller; @BeforeEach public void setupMap() { - this.screen = new TestingWidgetContainer(60, 1280f, 720f); + TestGameClient client = this.getTestGameClient(); + client.setWindowDimensions(1280f, 720f); + client.setTargetFps(60); + this.screen = client.getCurrentScreen(); this.map = new MapWidget(-4f, -2f, 10, 141f, 83f, MapContext.MINIMAP, 2.0f); this.screen.addWidget(this.map); - this.controller = map.getController(); + this.controller = this.map.getController(); } diff --git a/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapWidgetTest.java b/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapWidgetTest.java index ae29ce12..a253eaf2 100644 --- a/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapWidgetTest.java +++ b/forge/src/test/java/fr/thesmyler/terramap/gui/widgets/map/MapWidgetTest.java @@ -1,13 +1,14 @@ package fr.thesmyler.terramap.gui.widgets.map; import com.google.gson.JsonPrimitive; -import net.smyler.smylib.gui.TestingWidgetContainer; +import net.smyler.smylib.game.TestGameClient; import fr.thesmyler.terramap.TerramapTest; import fr.thesmyler.terramap.gui.widgets.map.layer.OnlineRasterMapLayer; import fr.thesmyler.terramap.gui.widgets.map.layer.RasterMapLayer; import fr.thesmyler.terramap.maps.SavedLayerState; import fr.thesmyler.terramap.maps.SavedMapState; import fr.thesmyler.terramap.maps.raster.MapStylesLibrary; +import net.smyler.smylib.gui.screen.Screen; import net.smyler.smylib.math.Vec2dImmutable; import net.smyler.terramap.util.geo.GeoPointImmutable; import org.junit.jupiter.api.Test; @@ -15,6 +16,7 @@ import static fr.thesmyler.terramap.MapContext.FULLSCREEN; import static fr.thesmyler.terramap.gui.widgets.map.MapLayerRegistry.RASTER_LAYER_ID; import static net.smyler.terramap.util.geo.GeoPointImmutable.ORIGIN; +import static fr.thesmyler.terramap.Assertions.*; import static org.junit.jupiter.api.Assertions.*; class MapWidgetTest extends TerramapTest { @@ -23,9 +25,11 @@ class MapWidgetTest extends TerramapTest { @Test void canSaveMapWidgetToSavedMapState() throws InterruptedException { - TestingWidgetContainer screen = new TestingWidgetContainer(60, 500f, 500f); + TestGameClient client = this.getTestGameClient(); + client.setWindowDimensions(500f, 500f); + client.setTargetFps(60); MapWidget map = new MapWidget(0f, 0f, 0, 500f, 500f, FULLSCREEN, 1f); - screen.addWidget(map); + client.getCurrentScreen().addWidget(map); OnlineRasterMapLayer raster_osm = (OnlineRasterMapLayer) map.createLayer(RASTER_LAYER_ID); OnlineRasterMapLayer osm_fr_hot = (OnlineRasterMapLayer) map.createLayer(RASTER_LAYER_ID); raster_osm.setTiledMap(MapStylesLibrary.getBaseMaps().get("osm")); @@ -39,10 +43,10 @@ void canSaveMapWidgetToSavedMapState() throws InterruptedException { map.getController().setZoom(10, false); map.getController().setRotation(45f, false); - screen.doTick(); + client.doTick(); map.getController().moveLocationToCenter(PARIS, false); - screen.doTick(); + client.doTick(); SavedMapState saved = map.save(); @@ -71,9 +75,13 @@ void canSaveMapWidgetToSavedMapState() throws InterruptedException { @Test public void canRestoreMapState() throws InterruptedException { - TestingWidgetContainer screen = new TestingWidgetContainer(60, 500f, 500f); + TestGameClient client = this.getTestGameClient(); + client.setWindowDimensions(500f, 500f); + client.setTargetFps(60); + Screen screen = client.getCurrentScreen(); + MapWidget map = new MapWidget(0f, 0f, 0, 500f, 500f, FULLSCREEN, 1f); - screen.moveMouse(750, 750, 1000); + client.moveMouse(750, 750, 1000); screen.addWidget(map); // Let's start in some random state @@ -83,9 +91,9 @@ public void canRestoreMapState() throws InterruptedException { map.setLayerZ(rasterLayer, -1); map.getController().setZoomStaticLocation(PARIS); map.getController().setZoom(18, true); - screen.runFor(1000); + client.runFor(1000); map.getController().moveLocationToCenter(PARIS, true); - screen.runFor(1000); + client.runFor(1000); map.getController().setRotationStaticLocation(PARIS); map.getController().setRotation(45f, true); @@ -101,7 +109,7 @@ public void canRestoreMapState() throws InterruptedException { // And we try restoring... map.restore(state); - screen.doTick(); + client.doTick(); assertEquals(ORIGIN, map.getController().getCenterLocation().getImmutable()); assertEquals(0, map.getController().getZoom()); @@ -117,9 +125,14 @@ public void canRestoreMapState() throws InterruptedException { @Test public void canRestoreMapStateWithInvalidLayerId() throws InterruptedException { - TestingWidgetContainer screen = new TestingWidgetContainer(60, 500f, 500f); + TestGameClient client = this.getTestGameClient(); + client.setWindowDimensions(500f, 500f); + client.setTargetFps(60); + + Screen screen = client.getCurrentScreen(); + MapWidget map = new MapWidget(0f, 0f, 0, 500f, 500f, FULLSCREEN, 1f); - screen.moveMouse(750, 750, 1000); + client.moveMouse(750, 750, 1000); screen.addWidget(map); SavedMapState state = new SavedMapState(); @@ -128,7 +141,7 @@ public void canRestoreMapStateWithInvalidLayerId() throws InterruptedException { state.layers.add(layerState); map.restore(state); - screen.doTick(); + client.doTick(); } diff --git a/smylib/core/src/main/java/net/smyler/smylib/gui/screen/PopupScreen.java b/smylib/core/src/main/java/net/smyler/smylib/gui/screen/PopupScreen.java index bc442d96..cfb51378 100644 --- a/smylib/core/src/main/java/net/smyler/smylib/gui/screen/PopupScreen.java +++ b/smylib/core/src/main/java/net/smyler/smylib/gui/screen/PopupScreen.java @@ -15,7 +15,7 @@ public abstract class PopupScreen extends Screen { private final Popup popup; - public PopupScreen(Popup popup) { + PopupScreen(Popup popup) { super(BackgroundOption.NONE); this.popup = popup; this.addWidget(popup); diff --git a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/ColorPickerWidgetTest.java b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/ColorPickerWidgetTest.java index b25e8ad8..b2c6cb92 100644 --- a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/ColorPickerWidgetTest.java +++ b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/ColorPickerWidgetTest.java @@ -1,9 +1,9 @@ package net.smyler.smylib.gui.widgets; -import net.smyler.smylib.gui.TestingWidgetContainer; +import net.smyler.smylib.game.TestGameClient; import net.smyler.smylib.SmyLibTest; import net.smyler.smylib.game.Key; -import net.smyler.smylib.gui.widgets.ColorPickerWidget; +import net.smyler.smylib.gui.screen.Screen; import org.junit.jupiter.api.Test; import java.util.concurrent.atomic.AtomicBoolean; @@ -48,68 +48,62 @@ void canDealWithCustomOnTextChangedCallback() { @Test void canInputColors() throws InterruptedException { - //TODO repair ColorPickerWidgetTest - /* - TestingWidgetContainer container = new TestingWidgetContainer(30, 500f, 500f); + TestGameClient client = this.getTestGameClient(); + Screen container = client.getCurrentScreen(); ColorPickerWidget colorPicker = new ColorPickerWidget(0, 0, 0, BLACK, getGameClient().defaultFont()); container.addWidget(colorPicker); // Focus the widget and move cursor to the right - container.moveMouse(10f, 10f, 500); - container.click(0); + client.moveMouse(10f, 10f, 500); + client.click(0); for (int i = 0; i < 10; i++) { - container.pressKey((char)Key.KEY_RIGHT.code, Key.KEY_RIGHT); - container.doTick(); + client.pressKey((char)Key.KEY_RIGHT.code, Key.KEY_RIGHT); + client.doTick(); } - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); assertFalse(colorPicker.hasValidColor()); assertEquals("#000", colorPicker.getText()); - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); - container.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); - container.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); + client.pressKey((char) Key.KEY_BACK.code, Key.KEY_BACK); + client.doTick(); assertFalse(colorPicker.hasValidColor()); assertEquals("#", colorPicker.getText()); - container.pressKey('F', Key.KEY_F); - container.doTick(); - container.pressKey('F', Key.KEY_F); - container.doTick(); - container.pressKey('0', Key.KEY_0); - container.doTick(); - container.pressKey('0', Key.KEY_0); - container.doTick(); - container.pressKey('0', Key.KEY_0); - container.doTick(); - container.pressKey('0', Key.KEY_0); - container.doTick(); + client.pressKey('F', Key.KEY_F); + client.doTick(); + client.pressKey('F', Key.KEY_F); + client.doTick(); + client.pressKey('0', Key.KEY_0); + client.doTick(); + client.pressKey('0', Key.KEY_0); + client.doTick(); + client.pressKey('0', Key.KEY_0); + client.doTick(); + client.pressKey('0', Key.KEY_0); + client.doTick(); assertTrue(colorPicker.hasValidColor()); assertEquals(RED, colorPicker.getColor()); - container.pressKey('F', Key.KEY_F); - container.doTick(); - container.pressKey('F', Key.KEY_F); - container.doTick(); + client.pressKey('F', Key.KEY_F); + client.doTick(); + client.pressKey('F', Key.KEY_F); + client.doTick(); assertTrue(colorPicker.hasValidColor()); assertEquals(RED, colorPicker.getColor()); - */ - } - - @Test - void setOnColorChange() { } } \ No newline at end of file diff --git a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/buttons/TextButtonWidgetTest.java b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/buttons/TextButtonWidgetTest.java index c00a8369..80a117cc 100644 --- a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/buttons/TextButtonWidgetTest.java +++ b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/buttons/TextButtonWidgetTest.java @@ -2,7 +2,8 @@ import net.smyler.smylib.SmyLibTest; -import net.smyler.smylib.gui.TestingWidgetContainer; +import net.smyler.smylib.game.TestGameClient; +import net.smyler.smylib.gui.screen.Screen; import org.junit.jupiter.api.Test; import java.util.concurrent.atomic.AtomicInteger; @@ -15,43 +16,44 @@ public class TextButtonWidgetTest extends SmyLibTest { @Test public void testActivation() throws InterruptedException { AtomicInteger clickCounter = new AtomicInteger(); - TestingWidgetContainer screen = new TestingWidgetContainer(30, 400, 300); + TestGameClient client = this.getTestGameClient(); + Screen screen = this.getTestGameClient().getCurrentScreen(); TextButtonWidget button = new TextButtonWidget(10, 10, 0, 200, "Test button", clickCounter::incrementAndGet); screen.addWidget(button); assertNull(screen.getFocusedWidget()); - screen.moveMouse(30, 30, 500); - screen.click(0); - screen.doTick(); - screen.doTick(); // We are giving it a frame to lose focus + client.moveMouse(30, 30, 500); + client.click(0); + client.doTick(); + client.doTick(); // We are giving it a frame to lose focus assertEquals(1, clickCounter.get()); assertNull(screen.getFocusedWidget()); - screen.doubleClick(0); - screen.doTick(); - screen.doTick(); + client.doubleClick(0); + client.doTick(); + client.doTick(); assertEquals(3, clickCounter.get()); assertNull(screen.getFocusedWidget()); - screen.moveMouse(1, 1, 500); - screen.click(0); - screen.doTick(); - screen.doTick(); + client.moveMouse(1, 1, 500); + client.click(0); + client.doTick(); + client.doTick(); assertEquals(3, clickCounter.get()); assertNull(screen.getFocusedWidget()); - screen.moveMouse(30, 30, 500); - screen.click(0); - screen.doTick(); - screen.doTick(); + client.moveMouse(30, 30, 500); + client.click(0); + client.doTick(); + client.doTick(); assertEquals(4, clickCounter.get()); assertNull(screen.getFocusedWidget()); button.setEnabled(false); - screen.click(0); - screen.doTick(); - screen.doTick(); + client.click(0); + client.doTick(); + client.doTick(); assertEquals(4, clickCounter.get()); assertNull(screen.getFocusedWidget()); } diff --git a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/sliders/OptionSliderWidgetTest.java b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/sliders/OptionSliderWidgetTest.java index 33c08471..1cb43e9a 100644 --- a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/sliders/OptionSliderWidgetTest.java +++ b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/sliders/OptionSliderWidgetTest.java @@ -1,10 +1,6 @@ package net.smyler.smylib.gui.widgets.sliders; -import net.smyler.smylib.gui.TestingWidgetContainer; import net.smyler.smylib.SmyLibTest; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; public class OptionSliderWidgetTest extends SmyLibTest { diff --git a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/text/TextFieldWidgetTest.java b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/text/TextFieldWidgetTest.java index f823e5a7..f9592508 100644 --- a/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/text/TextFieldWidgetTest.java +++ b/smylib/core/src/test/java/net/smyler/smylib/gui/widgets/text/TextFieldWidgetTest.java @@ -1,14 +1,8 @@ package net.smyler.smylib.gui.widgets.text; -import net.smyler.smylib.gui.TestingWidgetContainer; import net.smyler.smylib.SmyLibTest; -import net.smyler.smylib.game.Key; -import net.smyler.smylib.gui.DummyFont; -import net.smyler.smylib.gui.widgets.text.TextFieldWidget; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - public class TextFieldWidgetTest extends SmyLibTest { @Test diff --git a/smylib/forge/src/main/java/net/smyler/smylib/game/WrappedMinecraft.java b/smylib/forge/src/main/java/net/smyler/smylib/game/WrappedMinecraft.java index a70dc7ee..106d2ce6 100644 --- a/smylib/forge/src/main/java/net/smyler/smylib/game/WrappedMinecraft.java +++ b/smylib/forge/src/main/java/net/smyler/smylib/game/WrappedMinecraft.java @@ -9,7 +9,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.smyler.smylib.gui.*; import net.smyler.smylib.gui.popups.Popup; -import net.smyler.smylib.gui.popups.PopupScreenImplementation; +import net.smyler.smylib.gui.screen.PopupScreenImplementation; import net.smyler.smylib.gui.screen.*; import net.smyler.smylib.gui.sprites.SpriteLibrary; diff --git a/smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupImplementationProxy.java b/smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupImplementationProxy.java new file mode 100644 index 00000000..6d7afeab --- /dev/null +++ b/smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupImplementationProxy.java @@ -0,0 +1,12 @@ +package net.smyler.smylib.gui.popups; + +/** + * The sole purpose of this class is to make package methods accessible. + */ +public final class PopupImplementationProxy { + + public static void setPopupPosition(Popup popup, float x, float y) { + popup.setPosition(x, y); + } + +} diff --git a/smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupScreenImplementation.java b/smylib/forge/src/main/java/net/smyler/smylib/gui/screen/PopupScreenImplementation.java similarity index 86% rename from smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupScreenImplementation.java rename to smylib/forge/src/main/java/net/smyler/smylib/gui/screen/PopupScreenImplementation.java index 2de17720..437d583d 100644 --- a/smylib/forge/src/main/java/net/smyler/smylib/gui/popups/PopupScreenImplementation.java +++ b/smylib/forge/src/main/java/net/smyler/smylib/gui/screen/PopupScreenImplementation.java @@ -1,12 +1,14 @@ -package net.smyler.smylib.gui.popups; +package net.smyler.smylib.gui.screen; import net.smyler.smylib.gui.containers.WidgetContainer; -import net.smyler.smylib.gui.screen.PopupScreen; +import net.smyler.smylib.gui.popups.Popup; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.smyler.smylib.gui.DrawContext; +import static net.smyler.smylib.gui.popups.PopupImplementationProxy.setPopupPosition; + public class PopupScreenImplementation extends PopupScreen { @@ -35,7 +37,8 @@ public void draw(DrawContext context, float x, float y, float mouseX, float mous public void onUpdate(float mouseX, float mouseY, WidgetContainer parent) { this.other.updateScreen(); Popup popup = this.getPopup(); - this.getPopup().setPosition( + setPopupPosition( + this.getPopup(), (this.getWidth() - popup.getWidth()) / 2, (this.getHeight() - popup.getHeight()) / 2 ); diff --git a/smylib/testing/src/main/java/net/smyler/smylib/SmyLibTest.java b/smylib/testing/src/main/java/net/smyler/smylib/SmyLibTest.java index 528fac5c..66811de0 100644 --- a/smylib/testing/src/main/java/net/smyler/smylib/SmyLibTest.java +++ b/smylib/testing/src/main/java/net/smyler/smylib/SmyLibTest.java @@ -1,8 +1,10 @@ package net.smyler.smylib; import net.smyler.smylib.game.*; +import net.smyler.smylib.gui.screen.Screen; import org.junit.jupiter.api.BeforeEach; +import static net.smyler.smylib.gui.screen.BackgroundOption.DEFAULT; import static org.apache.logging.log4j.LogManager.getLogger; /** @@ -12,15 +14,20 @@ */ public abstract class SmyLibTest { - private DummyGameClient game; + private TestGameClient game; @BeforeEach public void initSmyLibGui() { // We are doing it before each test, so we clear devices' states - this.game = new DummyGameClient(); + this.game = new TestGameClient(); SmyLib.initializeGameClient(this.game, getLogger("SmyLib unit test logger")); this.getMouse().setButtonCount(3); this.getMouse().setHasWheel(true); + this.game.displayScreen(new Screen(DEFAULT)); + } + + protected TestGameClient getTestGameClient() { + return this.game; } protected DummyMouse getMouse() { diff --git a/smylib/testing/src/main/java/net/smyler/smylib/game/DummyGameClient.java b/smylib/testing/src/main/java/net/smyler/smylib/game/DummyGameClient.java deleted file mode 100644 index 9748e996..00000000 --- a/smylib/testing/src/main/java/net/smyler/smylib/game/DummyGameClient.java +++ /dev/null @@ -1,143 +0,0 @@ -package net.smyler.smylib.game; - -import net.smyler.smylib.gui.DrawContext; -import net.smyler.smylib.gui.DummyDrawContext; -import net.smyler.smylib.gui.DummyFont; -import net.smyler.smylib.gui.Font; -import net.smyler.smylib.threading.DefaultThreadLocal; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import static java.lang.Math.round; - -public class DummyGameClient implements GameClient { - - private final DefaultThreadLocal width = new DefaultThreadLocal<>(() -> new AtomicInteger(Float.floatToIntBits(720f))); - private final DefaultThreadLocal height = new DefaultThreadLocal<>(() -> new AtomicInteger(Float.floatToIntBits(480f))); - private final DefaultThreadLocal scale = new DefaultThreadLocal<>(() -> new AtomicInteger(1)); - private final DefaultThreadLocal isMac = new DefaultThreadLocal<>(() -> new AtomicBoolean(false)); - private final MinecraftServerInfo serverInfo = new MinecraftServerInfo("Dummy Server", "example.com", "Message of the day.", false); - private final Mouse mouse = new DummyMouse(); - private final Keyboard keyboard = new DummyKeyboard(); - private final Clipboard clipboard = new DummyClipboard(); - private final SoundSystem soundSystem = new DummySoundSystem(); - private final Translator translator = new DummyTranslator(); - private final Font font = new DummyFont(1f, 1f); - private final DrawContext drawContext = new DummyDrawContext(); - - private final Path gameDirectory; - - public DummyGameClient() { - try { - this.gameDirectory = Files.createTempDirectory("smylibgui"); - Files.createDirectories(this.gameDirectory); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public float windowWidth() { - return Float.intBitsToFloat(this.width.get().get()); - } - - public void setWindowWidth(float width) { - this.width.get().set(Float.floatToIntBits(width)); - } - - @Override - public float windowHeight() { - return Float.intBitsToFloat(this.height.get().get()); - } - - public void setWindowHeight(float height) { - this.width.get().set(Float.floatToIntBits(height)); - } - - @Override - public int nativeWindowWidth() { - return round(this.windowWidth() * this.scaleFactor()); - } - - @Override - public int nativeWindowHeight() { - return round(this.windowHeight() * this.scaleFactor()); - } - - @Override - public int scaleFactor() { - return this.scale.get().get(); - } - - public void setScaleFactor(int scale) { - this.scale.get().set(scale); - } - - @Override - public boolean isMac() { - return this.isMac.get().get(); - } - - @Override - public Path gameDirectory() { - return this.gameDirectory; - } - - @Override - public MinecraftServerInfo currentServerInfo() { - return this.serverInfo; - } - - @Override - public Mouse mouse() { - return this.mouse; - } - - @Override - public Keyboard keyboard() { - return this.keyboard; - } - - @Override - public Clipboard clipboard() { - return this.clipboard; - } - - @Override - public SoundSystem soundSystem() { - return this.soundSystem; - } - - @Override - public Translator translator() { - return this.translator; - } - - @Override - public Font defaultFont() { - return this.font; - } - - @Override - public DrawContext guiDrawContext() { - return this.drawContext; - } - - @Override - public boolean isGlAvailabale() { - return false; - } - - public void setIsMac(boolean yesNo) { - this.isMac.get().set(yesNo); - } - - public MinecraftServerInfo setServerInfo(MinecraftServerInfo info) { - return this.serverInfo; - } - -} diff --git a/smylib/testing/src/main/java/net/smyler/smylib/game/TestGameClient.java b/smylib/testing/src/main/java/net/smyler/smylib/game/TestGameClient.java new file mode 100644 index 00000000..1835dccc --- /dev/null +++ b/smylib/testing/src/main/java/net/smyler/smylib/game/TestGameClient.java @@ -0,0 +1,400 @@ +package net.smyler.smylib.game; + +import net.smyler.smylib.gui.DrawContext; +import net.smyler.smylib.gui.DummyDrawContext; +import net.smyler.smylib.gui.DummyFont; +import net.smyler.smylib.gui.Font; +import net.smyler.smylib.gui.popups.Popup; +import net.smyler.smylib.gui.screen.PopupScreen; +import net.smyler.smylib.gui.screen.Screen; +import net.smyler.smylib.gui.sprites.SpriteLibrary; +import net.smyler.smylib.gui.screen.TestPopupScreen; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.PriorityQueue; +import java.util.Queue; + +import static java.lang.Math.*; +import static java.lang.System.currentTimeMillis; +import static java.lang.Thread.sleep; +import static net.smyler.smylib.gui.screen.TestScreenProxy.setScreenResolution; + +public class TestGameClient implements GameClient { + + private float width = 720f; + private float height = 480f; + private int scale = 1; + private boolean isMac = false; + private final MinecraftServerInfo serverInfo = new MinecraftServerInfo("Dummy Server", "example.com", "Message of the day.", false); + private final DummyMouse mouse = new DummyMouse(); + private final Keyboard keyboard = new DummyKeyboard(); + private final Clipboard clipboard = new DummyClipboard(); + private final SoundSystem soundSystem = new DummySoundSystem(); + private final Translator translator = new DummyTranslator(); + private final Font font = new DummyFont(1f, 1f); + private final DrawContext drawContext = new DummyDrawContext(); + private final SpriteLibrary spriteLibrary = new SpriteLibrary(); + + private final Path gameDirectory; + + private int targetFps; + private int frameTime; + private long screenTime = 0L; + private Screen currentScreen; + private final Queue mouseEvents = new PriorityQueue<>(); + private final Queue mouseWheelEvents = new PriorityQueue<>(); + private final Queue keyboardEvents = new PriorityQueue<>(); + private final float[] lastClickX = new float[3]; + private final float[] lastClickY = new float[3]; + private final long[] lastClickTime = new long[3]; + private int lastClickedButton = -1; + + public TestGameClient() { + try { + this.gameDirectory = Files.createTempDirectory("smylibgui"); + Files.createDirectories(this.gameDirectory); + this.setTargetFps(60); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public float windowWidth() { + return this.width; + } + + public void setWindowWidth(float width) { + this.setWindowDimensions(width, this.height); + } + + @Override + public float windowHeight() { + return this.height; + } + + public void setWindowHeight(float height) { + this.setWindowDimensions(this.width, height); + } + + public void setWindowDimensions(float width, float height) { + this.width = width; + this.height = height; + setScreenResolution(width, height, this.getCurrentScreen()); + } + + @Override + public int nativeWindowWidth() { + return round(this.windowWidth() * this.scaleFactor()); + } + + @Override + public int nativeWindowHeight() { + return round(this.windowHeight() * this.scaleFactor()); + } + + @Override + public int scaleFactor() { + return this.scale; + } + + public void setScaleFactor(int scale) { + this.scale = scale; + } + + @Override + public boolean isMac() { + return this.isMac; + } + + @Override + public Path gameDirectory() { + return this.gameDirectory; + } + + @Override + public MinecraftServerInfo currentServerInfo() { + return this.serverInfo; + } + + @Override + public Mouse mouse() { + return this.mouse; + } + + @Override + public Keyboard keyboard() { + return this.keyboard; + } + + @Override + public Clipboard clipboard() { + return this.clipboard; + } + + @Override + public SoundSystem soundSystem() { + return this.soundSystem; + } + + @Override + public Translator translator() { + return this.translator; + } + + @Override + public Font defaultFont() { + return this.font; + } + + @Override + public DrawContext guiDrawContext() { + return this.drawContext; + } + + @Override + public SpriteLibrary sprites() { + return this.spriteLibrary; + } + + @Override + public boolean isGlAvailabale() { + return false; + } + + @Override + public void displayScreen(Screen screen) { + if (this.currentScreen != null) { + this.currentScreen.onClosed(); + } + this.currentScreen = screen; + setScreenResolution(this.windowWidth(), this.windowHeight(), this.currentScreen); + } + + @Override + public Screen getCurrentScreen() { + return this.currentScreen; + } + + @Override + public void displayPopup(@NotNull Popup popup) { + this.displayScreen(new TestPopupScreen(this.currentScreen, popup)); + } + + @Override + public @Nullable Popup getTopPopup() { + if (this.currentScreen instanceof PopupScreen) { + return ((PopupScreen) this.currentScreen).getPopup(); + } + return null; + } + + @Override + public @Nullable Popup closeTopPopup() { + if (!(this.currentScreen instanceof PopupScreen)) { + return null; + } + TestPopupScreen popupScreen = (TestPopupScreen) this.currentScreen; + this.displayScreen(popupScreen.background); + return popupScreen.getPopup(); + } + + @Override + public int closeAllPopups() { + int closed = 0; + while (this.currentScreen instanceof PopupScreen) { + TestPopupScreen popupScreen = (TestPopupScreen) this.currentScreen; + this.displayScreen(popupScreen.background); + closed++; + } + return closed; + } + + @Override + public int currentFPS() { + return this.targetFps; + } + + public void setIsMac(boolean yesNo) { + this.isMac = yesNo; + } + + public MinecraftServerInfo setServerInfo(MinecraftServerInfo info) { + return this.serverInfo; + } + + public void setTargetFps(int fps) { + this.targetFps = fps; + this.frameTime = (int)(round(1 / (double)fps * 100)); + } + + public void doTick() throws InterruptedException { + long stime = currentTimeMillis(); + this.processMouseEvents(); + this.processKeyboardEvents(); + this.currentScreen.onUpdate(this.mouse.x(), this.mouse.y(), null); + // At this point we would draw the screen, but we aren't doing that here + // this.currentScreen.draw(0, 0, this.mouseX, this.mouseY, true, true, null); + long dt = currentTimeMillis() - stime; + sleep(max(0, this.frameTime - dt)); + this.screenTime += currentTimeMillis() - stime; + } + + public void runFor(long milliseconds) throws InterruptedException { + long stime = this.screenTime; + while (this.screenTime < stime + milliseconds) this.doTick(); + } + + public void moveMouse(float x, float y, long time) throws InterruptedException { + long updates = time / this.frameTime; + float dX = (x - this.mouse.x()) / updates; + float dY = (y - this.mouse.y()) / updates; + for (long i = 0; i < updates; i++) { + this.mouse.setX(this.mouse.x() + dX); + this.mouse.setY(this.mouse.y() + dY); + if (this.lastClickedButton >= 0 && this.mouse.isButtonPressed(this.lastClickedButton)) { + this.mouseEvents.add(new MouseEvent(-1, false, this.screenTime)); + } + this.doTick(); + } + this.mouse.setX(x); + this.mouse.setY(y); + this.doTick(); + } + + public void click(int mouseButton) { + this.mouseEvents.add(new MouseEvent(mouseButton, true, this.screenTime)); + this.mouseEvents.add(new MouseEvent(mouseButton, false, this.screenTime + this.frameTime - 1)); + } + + public void doubleClick(int mouseButton) { + this.click(mouseButton); + this.click(mouseButton); + } + + public void pressMouseButton(int button) { + this.mouseEvents.add(new MouseEvent(button, true, this.screenTime)); + } + + public void releaseMouseButton(int button) { + this.mouseEvents.add(new MouseEvent(button, false, this.screenTime)); + } + + public void scrollMouse(int amount) { + if (amount == 0) return; + int inc = amount / abs(amount); + for (int i = 0; i != amount; i += inc) { + this.mouseWheelEvents.add(new MouseWheelEvent(inc, this.screenTime)); + } + } + + public void pressKey(char typedChar, Key key) { + this.keyboardEvents.add(new KeyboardEvent(typedChar, key, this.screenTime)); + } + + private void processMouseEvent(MouseEvent event) { + long ctime = this.screenTime; + int mouseButton = event.button; + if(event.buttonState) { + this.mouse.setButtonPressed(mouseButton, true); + boolean mouseDidNotMove = this.lastClickX[mouseButton] == this.mouse.x() && this.lastClickY[mouseButton] == this.mouse.y(); + if(ctime - this.lastClickTime[mouseButton] <= 500 && mouseDidNotMove) { //TODO de-hardcode double click delay in tests + this.currentScreen.onDoubleClick(this.mouse.x(), this.mouse.y(), mouseButton, null); + } else { + this.currentScreen.onClick(this.mouse.x(), this.mouse.y(), mouseButton, null); + } + this.lastClickedButton = mouseButton; + this.lastClickTime[mouseButton] = ctime; + this.lastClickX[mouseButton] = this.mouse.x(); + this.lastClickY[mouseButton] = this.mouse.y(); + } else if(mouseButton >= 0) { + this.mouse.setButtonPressed(mouseButton, false); + this.lastClickedButton = -1; + this.currentScreen.onMouseReleased(this.mouse.x(), this.mouse.y(), mouseButton, null); + } else if(this.lastClickedButton >= 0 && this.mouse.isButtonPressed(this.lastClickedButton)) { + float dX = this.mouse.x() - this.lastClickX[this.lastClickedButton]; + float dY = this.mouse.y() - this.lastClickY[this.lastClickedButton]; + long dt = ctime - this.lastClickTime[this.lastClickedButton]; + this.lastClickX[this.lastClickedButton] = this.mouse.x(); + this.lastClickY[this.lastClickedButton] = this.mouse.y(); + this.lastClickTime[this.lastClickedButton] = ctime; + this.currentScreen.onMouseDragged(this.mouse.x(), this.mouse.y(), dX, dY, this.lastClickedButton, null, dt); + } + + Iterator iterator = this.mouseWheelEvents.iterator(); + while (iterator.hasNext()) { + MouseWheelEvent wheelEvent = iterator.next(); + if (wheelEvent.time > this.screenTime) break; + if(wheelEvent.scroll != 0) this.currentScreen.onMouseWheeled(this.mouse.x(), this.mouse.y(), wheelEvent.scroll, null); + iterator.remove(); + } + } + + private void processMouseEvents() { + Iterator iterator = this.mouseEvents.iterator(); + while (iterator.hasNext()) { + MouseEvent event = iterator.next(); + if (event.time > this.screenTime) break; + this.processMouseEvent(event); + iterator.remove(); + } + } + private void processKeyboardEvents() { + Iterator iterator = this.keyboardEvents.iterator(); + while (iterator.hasNext()) { + KeyboardEvent event = iterator.next(); + if (event.time > this.screenTime) break; + this.currentScreen.onKeyTyped(event.character, event.eventKey, null); + iterator.remove(); + } + } + + private final static class MouseEvent implements Comparable { + final int button; + final boolean buttonState; + final long time; + public MouseEvent(int button, boolean buttonState, long time) { + this.button = button; + this.buttonState = buttonState; + this.time = time; + } + @Override + public int compareTo(MouseEvent other) { + return Long.compare(this.time, other.time); + } + } + + private final static class MouseWheelEvent implements Comparable { + final int scroll; + final long time; + public MouseWheelEvent(int scroll, long time) { + this.scroll = scroll; + this.time = time; + } + @Override + public int compareTo(MouseWheelEvent other) { + return Long.compare(this.time, other.time); + } + } + + private final static class KeyboardEvent implements Comparable { + final char character; + final Key eventKey; + final long time; + public KeyboardEvent(char character, Key eventKey, long time) { + this.character = character; + this.eventKey = eventKey; + this.time = time; + } + @Override + public int compareTo(KeyboardEvent other) { + return Long.compare(this.time, other.time); + } + } + +} diff --git a/smylib/testing/src/main/java/net/smyler/smylib/gui/DummyDrawContext.java b/smylib/testing/src/main/java/net/smyler/smylib/gui/DummyDrawContext.java index 9b58de5e..9e2d288c 100644 --- a/smylib/testing/src/main/java/net/smyler/smylib/gui/DummyDrawContext.java +++ b/smylib/testing/src/main/java/net/smyler/smylib/gui/DummyDrawContext.java @@ -43,4 +43,9 @@ public void drawSpriteCropped(double x, double y, double z, Sprite sprite, doubl } + @Override + public void drawTooltip(String text, double x, double y) { + + } + } diff --git a/smylib/testing/src/main/java/net/smyler/smylib/gui/TestingWidgetContainer.java b/smylib/testing/src/main/java/net/smyler/smylib/gui/TestingWidgetContainer.java deleted file mode 100644 index 9049e0c5..00000000 --- a/smylib/testing/src/main/java/net/smyler/smylib/gui/TestingWidgetContainer.java +++ /dev/null @@ -1,252 +0,0 @@ -package net.smyler.smylib.gui; - -import net.smyler.smylib.game.Key; - -import java.util.Iterator; -import java.util.PriorityQueue; -import java.util.Queue; - -import static java.lang.Math.abs; -import static java.lang.Math.max; -import static net.smyler.smylib.SmyLib.getGameClient; - -/** - * A mock widget container to use in unit tests. - * This class behaves like a normal container, - * except that it can be passed user inputs programmatically, - * and doesn't call its children draw methods. - * - * @author SmylerMC - */ -//FIXME Repair TestingWidgetContainer once GUIs are abstracted -public class TestingWidgetContainer { -/* -public class TestingWidgetContainer extends WidgetContainer { - - - private long screenTime = 0L; - private final int frameTime; - private final Queue mouseEvents = new PriorityQueue<>(); - private final Queue mouseWheelEvents = new PriorityQueue<>(); - private final Queue keyboardEvents = new PriorityQueue<>(); - - private final float[] lastClickX = new float[getGameClient().mouse().getButtonCount()]; - private final float[] lastClickY = new float[getGameClient().mouse().getButtonCount()]; - private final long[] lastClickTime = new long[getGameClient().mouse().getButtonCount()]; - private int lastClickedButton = -1; - - /** - * {@link TestingWidgetContainer} constructor. - * - * @param fps the frame-rate to simulate - * @param width the initial width of the window - * @param height the initial height of the window - * / - public TestingWidgetContainer(int fps, float width, float height) { - super(Integer.MAX_VALUE); - SmyLibGui.getTestGameContext().setWindowWidth(width); - SmyLibGui.getTestGameContext().setWindowHeight(height); - this.frameTime = 1000 / fps; - } - - /** - * Runs this screen for a single frame. - * - * @throws InterruptedException if sleeping for the correct timing is interrupted - * / - public void doTick() throws InterruptedException { - long stime = System.currentTimeMillis(); - this.processMouseEvents(); - this.processKeyboardEvents(); - float mouseX = SmyLibGui.getTestMouse().getX(); - float mouseY = SmyLibGui.getTestMouse().getY(); - this.onUpdate(mouseX, mouseY, this); - // At this point we would draw the screen, but we aren't doing that here - // this.draw(0, 0, this.mouseX, this.mouseY, true, true, null); - long dt = System.currentTimeMillis() - stime; - Thread.sleep(max(0, this.frameTime - dt)); - this.screenTime += System.currentTimeMillis() - stime; - } - - public void runFor(long milliseconds) throws InterruptedException { - long stime = this.screenTime; - while (this.screenTime < stime + milliseconds) this.doTick(); - } - - public void moveMouse(float x, float y, long time) throws InterruptedException { - long updates = time / this.frameTime; - DummyMouse mouse = SmyLibGui.getTestMouse(); - float dX = (x - mouse.getX()) / updates; - float dY = (y - mouse.getY()) / updates; - for (long i = 0; i < updates; i++) { - mouse.setX(mouse.getX() + dX); - mouse.setY(mouse.getY() + dY); - if (this.lastClickedButton >= 0 && SmyLibGui.getTestMouse().isButtonPressed(this.lastClickedButton)) { - this.mouseEvents.add(new MouseEvent(-1, false, this.screenTime)); - } - this.doTick(); - } - mouse.setX(x); - mouse.setY(y); - this.doTick(); - } - - public void resize(float width, float height) { - SmyLibGui.getTestGameContext().setWindowWidth(width); - SmyLibGui.getTestGameContext().setWindowHeight(height); - this.init(); - } - - public void click(int mouseButton) { - this.mouseEvents.add(new MouseEvent(mouseButton, true, this.screenTime)); - this.mouseEvents.add(new MouseEvent(mouseButton, false, this.screenTime + this.frameTime - 1)); - } - - public void doubleClick(int mouseButton) { - this.click(mouseButton); - this.click(mouseButton); - } - - public void pressMouseButton(int button) { - this.mouseEvents.add(new MouseEvent(button, true, this.screenTime)); - } - - public void releaseMouseButton(int button) { - this.mouseEvents.add(new MouseEvent(button, false, this.screenTime)); - } - - public void scrollMouse(int amount) { - if (amount == 0) return; - int inc = amount / abs(amount); - for (int i = 0; i != amount; i += inc) { - this.mouseWheelEvents.add(new MouseWheelEvent(inc, this.screenTime)); - } - } - - public void pressKey(char typedChar, Key key) { - this.keyboardEvents.add(new KeyboardEvent(typedChar, key, this.screenTime)); - } - - private void processMouseEvents() { - Iterator iterator = this.mouseEvents.iterator(); - while (iterator.hasNext()) { - MouseEvent event = iterator.next(); - if (event.time > this.screenTime) break; - this.processMouseEvent(event); - iterator.remove(); - } - } - - private void processMouseEvent(MouseEvent event) { - long ctime = this.screenTime; - int mouseButton = event.button; - DummyMouse mouse = SmyLibGui.getTestMouse(); - if(event.buttonState) { - SmyLibGui.getTestMouse().setButtonPressed(mouseButton, true); - if(ctime - this.lastClickTime[mouseButton] <= TerramapConfig.CLIENT.doubleClickDelay && this.lastClickX[mouseButton] == mouse.getX() && this.lastClickY[mouseButton] == mouse.getY()) { - this.onDoubleClick(mouse.getX(), mouse.getY(), mouseButton, null); - } else { - this.onClick(mouse.getX(), mouse.getY(), mouseButton, null); - } - this.lastClickedButton = mouseButton; - this.lastClickTime[mouseButton] = ctime; - this.lastClickX[mouseButton] = mouse.getX(); - this.lastClickY[mouseButton] = mouse.getY(); - } else if(mouseButton >= 0) { - SmyLibGui.getTestMouse().setButtonPressed(mouseButton, false); - this.lastClickedButton = -1; - this.onMouseReleased(mouse.getX(), mouse.getY(), mouseButton, null); - } else if(this.lastClickedButton >= 0 && SmyLibGui.getTestMouse().isButtonPressed(this.lastClickedButton)) { - float dX = mouse.getX() - this.lastClickX[this.lastClickedButton]; - float dY = mouse.getY() - this.lastClickY[this.lastClickedButton]; - long dt = ctime - this.lastClickTime[this.lastClickedButton]; - this.lastClickX[this.lastClickedButton] = mouse.getX(); - this.lastClickY[this.lastClickedButton] = mouse.getY(); - this.lastClickTime[this.lastClickedButton] = ctime; - this.onMouseDragged(mouse.getX(), mouse.getY(), dX, dY, this.lastClickedButton, null, dt); - } - - Iterator iterator = this.mouseWheelEvents.iterator(); - while (iterator.hasNext()) { - MouseWheelEvent wheelEvent = iterator.next(); - if (wheelEvent.time > this.screenTime) break; - if(wheelEvent.scroll != 0) this.onMouseWheeled(mouse.getX(), mouse.getY(), wheelEvent.scroll, null); - iterator.remove(); - } - } - - private void processKeyboardEvents() { - Iterator iterator = this.keyboardEvents.iterator(); - while (iterator.hasNext()) { - KeyboardEvent event = iterator.next(); - if (event.time > this.screenTime) break; - this.onKeyTyped(event.character, event.eventKey, null); - iterator.remove(); - } - } - - @Override - public float getX() { - return 0; - } - - @Override - public float getY() { - return 0; - } - - @Override - public float getWidth() { - return SmyLibGui.getTestGameContext().getWindowWidth(); - } - - @Override - public float getHeight() { - return SmyLibGui.getTestGameContext().getWindowHeight(); - } - - private final static class MouseEvent implements Comparable { - final int button; - final boolean buttonState; - final long time; - public MouseEvent(int button, boolean buttonState, long time) { - this.button = button; - this.buttonState = buttonState; - this.time = time; - } - @Override - public int compareTo(MouseEvent other) { - return Long.compare(this.time, other.time); - } - } - - private final static class MouseWheelEvent implements Comparable { - final int scroll; - final long time; - public MouseWheelEvent(int scroll, long time) { - this.scroll = scroll; - this.time = time; - } - @Override - public int compareTo(MouseWheelEvent other) { - return Long.compare(this.time, other.time); - } - } - - private final static class KeyboardEvent implements Comparable { - final char character; - final Key eventKey; - final long time; - public KeyboardEvent(char character, Key eventKey, long time) { - this.character = character; - this.eventKey = eventKey; - this.time = time; - } - @Override - public int compareTo(KeyboardEvent other) { - return Long.compare(this.time, other.time); - } - } - */ - -} diff --git a/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestPopupScreen.java b/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestPopupScreen.java new file mode 100644 index 00000000..aff219f7 --- /dev/null +++ b/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestPopupScreen.java @@ -0,0 +1,14 @@ +package net.smyler.smylib.gui.screen; + +import net.smyler.smylib.gui.popups.Popup; + +public class TestPopupScreen extends PopupScreen { + + public final Screen background; + + public TestPopupScreen(Screen background, Popup popup) { + super(popup); + this.background = background; + } + +} diff --git a/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestScreenProxy.java b/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestScreenProxy.java new file mode 100644 index 00000000..1cf7d407 --- /dev/null +++ b/smylib/testing/src/main/java/net/smyler/smylib/gui/screen/TestScreenProxy.java @@ -0,0 +1,15 @@ +package net.smyler.smylib.gui.screen; + +/** + * The sole purpose of this class is to expose package-visible methods + * of {@link Screen} for testing purposes. + */ +public final class TestScreenProxy { + + public static void setScreenResolution(float width, float height, Screen screen) { + screen.width = width; + screen.height = height; + screen.init(); + } + +}