diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java index 8be6545..aaf7c26 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/ConsoleIO.java @@ -32,8 +32,8 @@ public class ConsoleIO implements GameIO { private final BufferedReader in; private final PrintStream out; - private final boolean useColor; - private final GlyphMode glyphs; + private boolean useColor; + private GlyphMode glyphs; public ConsoleIO() { this(new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)), @@ -49,13 +49,23 @@ public class ConsoleIO implements GameIO { this.in = in; this.out = out; this.glyphs = glyphs; - this.useColor = switch (colorMode) { + setColorMode(colorMode); + } + + /** Re-resolves colour emission from the given mode (AUTO checks the console). */ + public void setColorMode(ColorMode mode) { + this.useColor = switch (mode) { case ON -> true; case OFF -> false; case AUTO -> System.console() != null; }; } + /** Switches the frame/glyph fidelity tier live. */ + public void setGlyphMode(GlyphMode mode) { + this.glyphs = mode; + } + @Override public String readLine() { out.print("> "); diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/Settings.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/Settings.java new file mode 100644 index 0000000..cebac84 --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/Settings.java @@ -0,0 +1,11 @@ +package thb.jeanluc.adventure.save; + +import thb.jeanluc.adventure.io.ConsoleIO; + +/** Persisted user preferences (minimal: colour + glyph fidelity). */ +public record Settings(ConsoleIO.ColorMode colorMode, ConsoleIO.GlyphMode glyphMode) { + + public static Settings defaults() { + return new Settings(ConsoleIO.ColorMode.AUTO, ConsoleIO.GlyphMode.UNICODE); + } +} diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/SettingsStore.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/SettingsStore.java new file mode 100644 index 0000000..c912041 --- /dev/null +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/save/SettingsStore.java @@ -0,0 +1,49 @@ +package thb.jeanluc.adventure.save; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** Loads/saves {@link Settings} as JSON (default {@code saves/settings.json}). */ +@Slf4j +public class SettingsStore { + + private final Path file; + private final ObjectMapper mapper = new ObjectMapper(); + + public SettingsStore() { + this(Path.of("saves", "settings.json")); + } + + public SettingsStore(Path file) { + this.file = file; + } + + /** Returns persisted settings, or {@link Settings#defaults()} on any problem. */ + public Settings load() { + if (!Files.isRegularFile(file)) { + return Settings.defaults(); + } + try { + return mapper.readValue(file.toFile(), Settings.class); + } catch (IOException e) { + log.warn("Could not read settings {}, using defaults", file, e); + return Settings.defaults(); + } + } + + /** Persists settings; logs and swallows failures (non-fatal). */ + public void save(Settings settings) { + try { + if (file.getParent() != null) { + Files.createDirectories(file.getParent()); + } + mapper.writerWithDefaultPrettyPrinter().writeValue(file.toFile(), settings); + } catch (IOException e) { + log.warn("Could not write settings {}", file, e); + } + } +} diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/ConsoleIOSettingsTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/ConsoleIOSettingsTest.java new file mode 100644 index 0000000..927ddbb --- /dev/null +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/io/ConsoleIOSettingsTest.java @@ -0,0 +1,23 @@ +package thb.jeanluc.adventure.io; + +import org.junit.jupiter.api.Test; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.StringReader; + +import static org.assertj.core.api.Assertions.assertThat; + +class ConsoleIOSettingsTest { + + @Test + void colorSetterTogglesAnsiEmission() { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ConsoleIO io = new ConsoleIO(new BufferedReader(new StringReader("")), + new PrintStream(out), ConsoleIO.ColorMode.OFF, ConsoleIO.GlyphMode.UNICODE); + io.setColorMode(ConsoleIO.ColorMode.ON); + io.print(thb.jeanluc.adventure.io.text.StyledText.builder().heading("Hi").build()); + assertThat(out.toString()).contains("["); // ANSI escape present + } +} diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/save/SettingsStoreTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/save/SettingsStoreTest.java new file mode 100644 index 0000000..8b959d0 --- /dev/null +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/save/SettingsStoreTest.java @@ -0,0 +1,27 @@ +package thb.jeanluc.adventure.save; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import thb.jeanluc.adventure.io.ConsoleIO; + +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class SettingsStoreTest { + + @Test + void savesAndLoads(@TempDir Path dir) { + SettingsStore store = new SettingsStore(dir.resolve("settings.json")); + store.save(new Settings(ConsoleIO.ColorMode.ON, ConsoleIO.GlyphMode.ASCII)); + Settings loaded = store.load(); + assertThat(loaded.colorMode()).isEqualTo(ConsoleIO.ColorMode.ON); + assertThat(loaded.glyphMode()).isEqualTo(ConsoleIO.GlyphMode.ASCII); + } + + @Test + void missingFileReturnsDefaults(@TempDir Path dir) { + Settings loaded = new SettingsStore(dir.resolve("nope.json")).load(); + assertThat(loaded).isEqualTo(Settings.defaults()); + } +}