From 74c70653665ace181df0825b59f4445aabaeb7ee Mon Sep 17 00:00:00 2001 From: Geolykt Date: Sun, 7 Mar 2021 00:16:45 +0100 Subject: [PATCH] More Abstraction and a few changes to existing API --- .../geolykt/starloader/api/Identifiable.java | 12 ++++ .../starloader/api/empire/ActiveEmpire.java | 3 +- .../geolykt/starloader/api/empire/Empire.java | 10 +-- .../geolykt/starloader/api/empire/Star.java | 13 +--- .../api/gui/AutocloseableDialog.java | 11 +++ .../starloader/api/gui/BasicDialog.java | 28 +------- .../api/gui/BasicDialogBuilder.java | 2 +- .../starloader/api/gui/ButtonDialog.java | 12 ++++ .../apimixins/EmpireAnnalsMixins.java | 71 +++++++++++++++++++ .../starloader/apimixins/StarMixins.java | 2 +- .../geolykt/starloader/impl/BasicDialog.java | 58 +++++++++++++++ .../impl/DialogCloseListenerWrapper.java | 1 - src/main/resources/api-mixins.json | 5 +- 13 files changed, 177 insertions(+), 51 deletions(-) create mode 100644 src/main/java/de/geolykt/starloader/api/Identifiable.java create mode 100644 src/main/java/de/geolykt/starloader/api/gui/AutocloseableDialog.java create mode 100644 src/main/java/de/geolykt/starloader/api/gui/ButtonDialog.java create mode 100644 src/main/java/de/geolykt/starloader/apimixins/EmpireAnnalsMixins.java create mode 100644 src/main/java/de/geolykt/starloader/impl/BasicDialog.java diff --git a/src/main/java/de/geolykt/starloader/api/Identifiable.java b/src/main/java/de/geolykt/starloader/api/Identifiable.java new file mode 100644 index 0000000..c7b7879 --- /dev/null +++ b/src/main/java/de/geolykt/starloader/api/Identifiable.java @@ -0,0 +1,12 @@ +package de.geolykt.starloader.api; + +public interface Identifiable { + + /** + * Obtains the usually unique (numeric) identifier of the object. There should be no duplicates. + * However due to the way the game operates, there might be duplicates, which can have unintended consquences. + * @return The UID of the empire + */ + public int getUID(); + +} diff --git a/src/main/java/de/geolykt/starloader/api/empire/ActiveEmpire.java b/src/main/java/de/geolykt/starloader/api/empire/ActiveEmpire.java index 0ca1123..a373968 100644 --- a/src/main/java/de/geolykt/starloader/api/empire/ActiveEmpire.java +++ b/src/main/java/de/geolykt/starloader/api/empire/ActiveEmpire.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import de.geolykt.starloader.api.Metadatable; import snoddasmannen.galimulator.Fleet; import snoddasmannen.galimulator.Religion; import snoddasmannen.galimulator.actors.Flagship; @@ -14,7 +15,7 @@ /** * Interface for any empire that is still in the game */ -public interface ActiveEmpire extends Empire { +public interface ActiveEmpire extends Empire, Metadatable { /** * Assigns a {@link StateActor} to the empire. diff --git a/src/main/java/de/geolykt/starloader/api/empire/Empire.java b/src/main/java/de/geolykt/starloader/api/empire/Empire.java index d323b42..fc45d22 100644 --- a/src/main/java/de/geolykt/starloader/api/empire/Empire.java +++ b/src/main/java/de/geolykt/starloader/api/empire/Empire.java @@ -3,13 +3,13 @@ import org.jetbrains.annotations.NotNull; import de.geolykt.starloader.api.Galimulator; -import de.geolykt.starloader.api.Metadatable; +import de.geolykt.starloader.api.Identifiable; import snoddasmannen.galimulator.GalColor; /** * Base interface for any empires that exist in the game, whether collapsed or not */ -public interface Empire extends Dateable, Metadatable { +public interface Empire extends Dateable, Identifiable { /** * The age of an empire is counted in years and ceases to stop increasing once the empire has collapsed. @@ -45,12 +45,6 @@ public default int getAge() { */ public int getStarCount(); - /** - * Obtains the unique (numeric) identifier of the empire. There should be no duplicates. - * @return The UID of the empire - */ - public int getUID(); - /** * Empires are usually not in the collapse state, however sometimes this is true, albeit rare. * @return true if the empire ceased to exist diff --git a/src/main/java/de/geolykt/starloader/api/empire/Star.java b/src/main/java/de/geolykt/starloader/api/empire/Star.java index 7fc8a9d..26fee06 100644 --- a/src/main/java/de/geolykt/starloader/api/empire/Star.java +++ b/src/main/java/de/geolykt/starloader/api/empire/Star.java @@ -10,13 +10,14 @@ import com.badlogic.gdx.math.Vector2; import de.geolykt.starloader.api.Galimulator; +import de.geolykt.starloader.api.Identifiable; import de.geolykt.starloader.api.Metadatable; import snoddasmannen.galimulator.Religion; /** * Wrapper interface for Stars */ -public interface Star extends Metadatable { +public interface Star extends Identifiable, Metadatable { /** * Adds a star to the neighbour lists. Please note that you likely do not want to call this method yourself. @@ -97,16 +98,6 @@ public interface Star extends Metadatable { */ public @NotNull Vector getNeighboursRecursive(int recurseDepth); - /** - * The unique identifier of the star should not change throughout it's lifecycle, - * however nothing forbids it from actually doing that. - * However it should not be done by any extension as this likely breaks something. - * Additionally nothing verifies it's uniqueness, however if it is not unique most lookup techniques will fail - * or return unexpected results. - * @return The unique identifier that represents the star - */ - public int getUniqueId(); - /** * Obtains the wealth of the star. * Wealthier stars are harder to take and have more additional extras for them and the empire owning the star diff --git a/src/main/java/de/geolykt/starloader/api/gui/AutocloseableDialog.java b/src/main/java/de/geolykt/starloader/api/gui/AutocloseableDialog.java new file mode 100644 index 0000000..aa6f06f --- /dev/null +++ b/src/main/java/de/geolykt/starloader/api/gui/AutocloseableDialog.java @@ -0,0 +1,11 @@ +package de.geolykt.starloader.api.gui; + +public interface AutocloseableDialog { + + /** + * Obtains the time at which the dialog will be closed automatically, or -1 if automatic closing is not done. + * The time is relative to the starting point of {@link System#currentTimeMillis()} and is in milliseconds. + */ + public long getAutocloseTime(); + +} diff --git a/src/main/java/de/geolykt/starloader/api/gui/BasicDialog.java b/src/main/java/de/geolykt/starloader/api/gui/BasicDialog.java index b27ddfd..38c9dad 100644 --- a/src/main/java/de/geolykt/starloader/api/gui/BasicDialog.java +++ b/src/main/java/de/geolykt/starloader/api/gui/BasicDialog.java @@ -1,32 +1,8 @@ package de.geolykt.starloader.api.gui; -import java.util.ArrayList; -import java.util.List; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import de.geolykt.starloader.impl.DialogCloseListenerWrapper; -import snoddasmannen.galimulator.Space; -import snoddasmannen.galimulator.ui.bh; - /** - * A simple wrapper around the dialog, a graphical component of Galimulator + * A basic dialog. */ -public class BasicDialog { +public interface BasicDialog extends AutocloseableDialog, ButtonDialog { - /** - * Creates and displays a dialog - * @param title The title of the dialog - * @param description The description (content/body) of the dialog - * @param choices The buttons of the dialog - * @param listeners The listeners that are applied to the dialog - * @param duration The duration that the dialog should stay opened in seconds - * @param playSFX True if the close sound should be used. - */ - public BasicDialog(@NotNull String title, @NotNull String description, @Nullable List choices, - @NotNull ArrayList listeners, int duration, boolean playSFX) { - bh dialog = Space.a(title, description, choices, duration, null, true); - dialog.a(new DialogCloseListenerWrapper(listeners, playSFX)); - } } diff --git a/src/main/java/de/geolykt/starloader/api/gui/BasicDialogBuilder.java b/src/main/java/de/geolykt/starloader/api/gui/BasicDialogBuilder.java index bea46a1..5fa7e1f 100644 --- a/src/main/java/de/geolykt/starloader/api/gui/BasicDialogBuilder.java +++ b/src/main/java/de/geolykt/starloader/api/gui/BasicDialogBuilder.java @@ -111,6 +111,6 @@ public BasicDialogBuilder supressCloseSound() { * @return The dialog that was built via the operation. */ public BasicDialog buildAndShow() { - return new BasicDialog(title, description, choices, listeners, duration, playSFX); + return new de.geolykt.starloader.impl.BasicDialog(title, description, choices, listeners, duration, playSFX); } } diff --git a/src/main/java/de/geolykt/starloader/api/gui/ButtonDialog.java b/src/main/java/de/geolykt/starloader/api/gui/ButtonDialog.java new file mode 100644 index 0000000..89c084c --- /dev/null +++ b/src/main/java/de/geolykt/starloader/api/gui/ButtonDialog.java @@ -0,0 +1,12 @@ +package de.geolykt.starloader.api.gui; + +import org.jetbrains.annotations.Nullable; + +public interface ButtonDialog { + + /** + * This call simulates a button click. However this method can also be called if the dialog was closed automatically. + * @param buttonPressed Some magic value that I don't fully understand or null, if the dialog was closed automatically + */ + public void close(@Nullable Object buttonPressed); // TODO understand the parameter +} diff --git a/src/main/java/de/geolykt/starloader/apimixins/EmpireAnnalsMixins.java b/src/main/java/de/geolykt/starloader/apimixins/EmpireAnnalsMixins.java new file mode 100644 index 0000000..f9f7527 --- /dev/null +++ b/src/main/java/de/geolykt/starloader/apimixins/EmpireAnnalsMixins.java @@ -0,0 +1,71 @@ +package de.geolykt.starloader.apimixins; + +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import de.geolykt.starloader.api.Galimulator; +import de.geolykt.starloader.api.empire.Empire; +import snoddasmannen.galimulator.GalColor; + +@Mixin(snoddasmannen.galimulator.EmpireAnnals.class) +public class EmpireAnnalsMixins implements Empire { + + @Shadow + public int empireId; + + @Shadow + public int birthYear; + + @Shadow + public int deathYear; + + @Shadow + public String name; + + @Shadow + public String nameIdentifier; + + @Shadow + public GalColor color; + + @Override + public int getFoundationYear() { + return birthYear; + } + + @Override + public int getUID() { + return empireId; + } + + @Override + public int getCollapseYear() { + return deathYear; + } + + @Override + public @NotNull GalColor getColor() { + return color; + } + + @Override + public @NotNull String getEmpireName() { + return name; + } + + @Override + public int getStarCount() { + if (deathYear != -1) { + return 0; + } else { + return Galimulator.getEmpirePerUID(getUID()).getStarCount(); + } + } + + @Override + public boolean hasCollapsed() { + return deathYear != -1; + } + +} diff --git a/src/main/java/de/geolykt/starloader/apimixins/StarMixins.java b/src/main/java/de/geolykt/starloader/apimixins/StarMixins.java index ff21004..20d1833 100644 --- a/src/main/java/de/geolykt/starloader/apimixins/StarMixins.java +++ b/src/main/java/de/geolykt/starloader/apimixins/StarMixins.java @@ -142,7 +142,7 @@ public Vector getNeighbourIDs() { } @Override - public int getUniqueId() { + public int getUID() { return id; } diff --git a/src/main/java/de/geolykt/starloader/impl/BasicDialog.java b/src/main/java/de/geolykt/starloader/impl/BasicDialog.java new file mode 100644 index 0000000..6c34ce2 --- /dev/null +++ b/src/main/java/de/geolykt/starloader/impl/BasicDialog.java @@ -0,0 +1,58 @@ +package de.geolykt.starloader.impl; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import de.geolykt.starloader.api.gui.BasicDialogCloseListener; +import snoddasmannen.galimulator.Space; +import snoddasmannen.galimulator.ui.bh; + +/** + * A simple wrapper around the dialog, a graphical component of Galimulator + */ +public class BasicDialog implements de.geolykt.starloader.api.gui.BasicDialog { + + protected final bh dialog; + protected final long closeTime; + + /** + * Creates and displays a dialog + * @param title The title of the dialog + * @param description The description (content/body) of the dialog + * @param choices The buttons of the dialog + * @param listeners The listeners that are applied to the dialog + * @param duration The duration that the dialog should stay opened in seconds + * @param playSFX True if the close sound should be used. + */ + public BasicDialog(@NotNull String title, @NotNull String description, @Nullable List choices, + @NotNull ArrayList listeners, int duration, boolean playSFX) { + dialog = Space.a(title, description, choices, duration, null, true); + dialog.a(new DialogCloseListenerWrapper(listeners, playSFX)); + // Luckily the close time is final, so we only have to get it once + try { + Field field = this.dialog.getClass().getField("d"); + field.setAccessible(true); + closeTime = field.getLong(this.dialog); + field.setAccessible(false); + } catch (ReflectiveOperationException | SecurityException e) { + throw new RuntimeException("Something went wrong while performing the reflections for Audiosample wrapping", e); + } + } + + /** + * Obtains the time at which the dialog will be closed automatically, or -1 if automatic closing is not done. + * The time is relative to the starting point of {@link System#currentTimeMillis()} and is in milliseconds. + */ + public long getAutocloseTime() { + return closeTime; + } + + @Override + public void close(@Nullable Object buttonPressed) { + dialog.a(buttonPressed); + } +} diff --git a/src/main/java/de/geolykt/starloader/impl/DialogCloseListenerWrapper.java b/src/main/java/de/geolykt/starloader/impl/DialogCloseListenerWrapper.java index 66e86e4..62faa4f 100644 --- a/src/main/java/de/geolykt/starloader/impl/DialogCloseListenerWrapper.java +++ b/src/main/java/de/geolykt/starloader/impl/DialogCloseListenerWrapper.java @@ -7,7 +7,6 @@ import de.geolykt.starloader.api.gui.DialogCloseCause; import de.geolykt.starloader.api.resource.AudioSampleWrapper; import de.geolykt.starloader.api.gui.BasicDialogCloseListener; -import snoddasmannen.galimulator.AudioManager$AudioSample; import snoddasmannen.galimulator.ui.bk; public class DialogCloseListenerWrapper implements bk { diff --git a/src/main/resources/api-mixins.json b/src/main/resources/api-mixins.json index 64316db..3bdbd4e 100644 --- a/src/main/resources/api-mixins.json +++ b/src/main/resources/api-mixins.json @@ -5,9 +5,10 @@ "target": "@env(DEFAULT)", "compatibilityLevel": "JAVA_8", "mixins": [ - "InstanceMixins", - "EmpireMixins", "AllianceMixins", + "EmpireAnnalsMixins", + "EmpireMixins", + "InstanceMixins", "StarMixins" ] }