diff --git a/src/omaloon/OlVars.java b/src/omaloon/OlVars.java new file mode 100644 index 00000000..36617214 --- /dev/null +++ b/src/omaloon/OlVars.java @@ -0,0 +1,76 @@ +package omaloon; + +import arc.*; +import arc.func.*; +import arc.util.*; +import lombok.*; +import mindustry.*; +import mindustry.game.EventType.*; +import omaloon.ui.*; + +import static arc.Core.settings; + +public class OlVars{ + @Getter(lazy = true) + private static final ClientLauncher clientLauncher = findClientLauncher(); + @Getter(value = AccessLevel.PRIVATE, lazy = true) + private static final Cons listenerAdder = computeClientListeners(); + + private static ClientLauncher findClientLauncher(){ + if(Vars.headless) return null; + val seq = Core.app.getListeners(); + for(int i = 0; i < seq.size; i++){ + ApplicationListener listener = seq.get(i); + if(listener instanceof ClientLauncher launcher) return launcher; + } + + if(Vars.platform instanceof ClientLauncher launcher) return launcher; + + throw new RuntimeException("Cannot run Omaloon because your client is strange..."); + } + + private static Cons computeClientListeners(){ + if(Vars.headless){ + return Core.app::addListener; + }else{ + return getClientLauncher()::add; + } + } + + public static T appListener(T applicationListener){ + getListenerAdder().get(applicationListener); + return applicationListener; + } + + public static void init(){ + setKeybinds(OlBinding.values()); + } + + /** + * @author Zelaux + * source + */ + public static void setKeybinds(KeyBinds.KeyBind... modBindings){ + Time.mark(); + KeyBinds.KeyBind[] originalBinds = Core.keybinds.getKeybinds(); + KeyBinds.KeyBind[] newBinds = new KeyBinds.KeyBind[originalBinds.length + modBindings.length]; + + System.arraycopy(originalBinds, 0, newBinds, 0, originalBinds.length); + System.arraycopy(modBindings, 0, newBinds, originalBinds.length, modBindings.length); + + OmaloonMod.olLog("Time to combine arrays: @ms", Time.elapsed()); + Core.keybinds.setDefaults(newBinds); + settings.load(); + } + + public static void onClientLoad(Runnable runnable){ + Events.on(ClientLoadEvent.class, it -> runnable.run()); + } + public static void onServerLoad(Runnable runnable){ + Events.on(ServerLoadEvent.class, it -> runnable.run()); + } + public static void onAnyLoad(Runnable runnable){ + onClientLoad(runnable); + onServerLoad(runnable); + } +} diff --git a/src/omaloon/OmaloonMod.java b/src/omaloon/OmaloonMod.java index ee10e31f..006f94d7 100644 --- a/src/omaloon/OmaloonMod.java +++ b/src/omaloon/OmaloonMod.java @@ -8,21 +8,25 @@ import mindustry.game.*; import mindustry.mod.*; import mindustry.type.*; -import ol.gen.OlCall; +import ol.gen.*; import omaloon.content.*; import omaloon.core.*; +import omaloon.core.extra.*; +import omaloon.core.extra.RelatedApplicationListener.*; import omaloon.gen.*; import omaloon.graphics.*; import omaloon.net.*; -import omaloon.ui.*; import omaloon.ui.dialogs.*; import omaloon.utils.*; import omaloon.world.blocks.environment.*; -import omaloon.world.save.OlDelayedItemTransfer; +import omaloon.world.save.*; +import org.jetbrains.annotations.Nullable; import static arc.Core.app; +import static omaloon.OlVars.*; import static omaloon.core.OlUI.*; +@Nullable public class OmaloonMod extends Mod{ /** @@ -30,19 +34,34 @@ public class OmaloonMod extends Mod{ */ public static float shieldBuffer = 40f; public static SafeClearer safeClearer; + public static OlUI ui; + public static OlControl control; public static EditorListener editorListener; + public static OlNetClient netClient; public OmaloonMod(){ - super(); OlCall.registerPackets(); new OlDelayedItemTransfer(); - if(!Vars.headless) - editorListener = new EditorListener(); - ui = new OlUI(OlBinding.values()); + appListener(new ApplicationListener(){ + @Override + public void init(){ + OlVars.init(); + } + }); + if(!Vars.headless){ + editorListener = appListener(new EditorListener()); + ui = appListener(new OlUI()); + control = appListener(new OlControl()); + netClient= RelatedApplicationListener.register( + new OlNetClient(), + RelativeOrder.before, + Vars.netClient + ); + } - Events.on(EventType.ClientLoadEvent.class, e -> { + OlVars.onClientLoad(() -> { Vars.maps.all().removeAll(map -> { if(map.mod == null || !map.mod.name.equals("omaloon")){ return false; @@ -50,22 +69,6 @@ public OmaloonMod(){ Mods.LoadedMod otherMod = Vars.mods.getMod("test-utils"); return otherMod == null || !otherMod.enabled(); }); - Core.app.addListener(new ApplicationListener(){ - @Override - public void update(){ - if(Core.input.keyTap(OlBinding.switchDebugDraw)){ - DebugDraw.switchEnabled(); - } - } - }); - - - }); - - if(!Vars.headless){ - editorListener = new EditorListener(); - } - Events.on(EventType.ClientLoadEvent.class, ignored -> { OlIcons.load(); OlSettings.load(); EventHints.addHints(); @@ -88,6 +91,7 @@ public void update(){ Log.info("Loaded OmaloonMod constructor."); } + public static void olLog(String string, Object... args){ Log.infoTag("omaloon", Strings.format(string, args)); } diff --git a/src/omaloon/ai/drone/AttackDroneAI.java b/src/omaloon/ai/drone/AttackDroneAI.java index b415476b..3b27d1d9 100644 --- a/src/omaloon/ai/drone/AttackDroneAI.java +++ b/src/omaloon/ai/drone/AttackDroneAI.java @@ -1,17 +1,23 @@ package omaloon.ai.drone; +import arc.*; import arc.graphics.g2d.*; import arc.math.geom.*; import arc.util.*; import arclibrary.graphics.*; +import mindustry.*; +import mindustry.entities.*; import mindustry.gen.*; import mindustry.graphics.*; +import mindustry.input.*; +import mindustry.type.*; import mindustry.ui.*; +import omaloon.*; import omaloon.ai.*; import omaloon.math.*; import omaloon.utils.*; -import static mindustry.Vars.tilesize; +import static mindustry.Vars.*; /** * @author Zelaux @@ -124,7 +130,34 @@ public void updateMovement(){ } private boolean isOwnerShooting(){ - return owner.isShooting() || owner.controller() instanceof Player player && player.shooting; + if(owner.isShooting()) return true; + if(!(owner.controller() instanceof Player player)) return false; + if(player.shooting) return true; + if(player != Vars.player) return false; + + MobileInput mobile = OmaloonMod.control.input.mobile; + if(mobile == null) return false; + if(!Core.settings.getBool("autotarget")) return false; + UnitType ownerType = owner.type; + float ownerRange = owner.range(); +// if(!ownerType.canAttack) return false; + if(mobile.target == null){ + mobile.target = Units.closestTarget( + owner.team, owner.x, owner.y, + ownerRange, u -> u.checkTarget(ownerType.targetAir, ownerType.targetGround), u -> ownerType.targetGround); + + if(mobile.target == null) return false; + } + + //using self unit bulletSpeed + float bulletSpeed = unit.type.weapons.first().bullet.speed; + Vec2 intercept = Predict.intercept(owner, mobile.target, bulletSpeed); + +// player.shooting = !boosted; + + owner.aim(player.mouseX = intercept.x, player.mouseY = intercept.y); + + return true; } @Override @@ -136,4 +169,10 @@ public Teamc target(float x, float y, float range, boolean air, boolean ground){ public boolean shouldShoot(){ return isOwnerShooting(); } + + public void beforeSync(){ + if(owner.controller() != player) return; + if(owner.isShooting())return; + player.shooting=isOwnerShooting();//sets aim stuff + } } \ No newline at end of file diff --git a/src/omaloon/client/OlClientStuff.java b/src/omaloon/client/OlClientStuff.java new file mode 100644 index 00000000..01fc45d2 --- /dev/null +++ b/src/omaloon/client/OlClientStuff.java @@ -0,0 +1,9 @@ +package omaloon.client; + +import arc.*; +import lombok.*; +import mindustry.*; + +public class OlClientStuff{ + +} diff --git a/src/omaloon/core/EditorListener.java b/src/omaloon/core/EditorListener.java index 80d63ef8..0c334cad 100644 --- a/src/omaloon/core/EditorListener.java +++ b/src/omaloon/core/EditorListener.java @@ -11,7 +11,6 @@ public class EditorListener implements ApplicationListener{ boolean isEditor; public EditorListener(){ - if(Vars.platform instanceof ApplicationCore core) core.add(this); Events.on(StateChangeEvent.class, e -> { if(e.from == State.menu && e.to == State.playing && state.isEditor()){ if(true){ diff --git a/src/omaloon/core/OlControl.java b/src/omaloon/core/OlControl.java new file mode 100644 index 00000000..a23f3612 --- /dev/null +++ b/src/omaloon/core/OlControl.java @@ -0,0 +1,24 @@ +package omaloon.core; + +import arc.*; +import mindustry.*; +import mindustry.game.EventType.*; +import omaloon.ui.*; +import omaloon.utils.*; + + +public class OlControl implements ApplicationListener{ + public OlInput input; + + @Override + public void init(){ + input = new OlInput(Vars.control.input); + } + + @Override + public void update(){ + if(Core.input.keyTap(OlBinding.switchDebugDraw)){ + DebugDraw.switchEnabled(); + } + } +} diff --git a/src/omaloon/core/OlInput.java b/src/omaloon/core/OlInput.java new file mode 100644 index 00000000..92d782de --- /dev/null +++ b/src/omaloon/core/OlInput.java @@ -0,0 +1,29 @@ +package omaloon.core; + +import lombok.*; +import mindustry.*; +import mindustry.input.*; +import org.jetbrains.annotations.*; + +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class OlInput{ + + @NotNull + public final InputHandler any; + @Nullable + public final DesktopInput desktop; + @Nullable + public final MobileInput mobile; + + public OlInput(@NonNull InputHandler any){ + this( + any, + Vars.mobile ? null : (DesktopInput)any, + Vars.mobile ? (MobileInput)any : null + ); + } + + public static void makeLazy(){ + } + +} diff --git a/src/omaloon/core/OlNetClient.java b/src/omaloon/core/OlNetClient.java new file mode 100644 index 00000000..3a210c75 --- /dev/null +++ b/src/omaloon/core/OlNetClient.java @@ -0,0 +1,27 @@ +package omaloon.core; + +import arc.*; +import mindustry.*; +import mindustry.gen.*; +import omaloon.ai.drone.*; +import omaloon.entities.abilities.*; + +public class OlNetClient implements ApplicationListener{ + @Override + public void update(){ + if(!Vars.mobile) return; + if(Vars.player == null) return; + Unit unit = Vars.player.unit(); + if(unit == null) return; + if(!DroneAbility.isDroneOwner(unit.type)) return; + int[] indecies = DroneAbility.abilityIndecies(unit.type); + for(int i : indecies){ + DroneAbility ability = (DroneAbility)unit.abilities[i]; + for(Unit drone : ability.drones){ + if(!(drone.controller() instanceof AttackDroneAI attackDroneAI)) continue; + attackDroneAI.beforeSync(); + + } + } + } +} diff --git a/src/omaloon/core/OlUI.java b/src/omaloon/core/OlUI.java index 520a14c0..5bcd3dd6 100644 --- a/src/omaloon/core/OlUI.java +++ b/src/omaloon/core/OlUI.java @@ -1,8 +1,6 @@ package omaloon.core; -import arc.Core; -import arc.Events; -import arc.KeyBinds; +import arc.*; import arc.util.Time; import mindustry.Vars; import mindustry.game.EventType; @@ -18,7 +16,7 @@ import static arc.Core.settings; -public class OlUI { +public class OlUI implements ApplicationListener{ public static ShapedEnvPlacerFragment shapedEnvPlacerFragment; public static CliffFragment cliffFragment; public static OlInputDialog olInputDialog; @@ -26,10 +24,7 @@ public class OlUI { public static OlGameDialog olGameDialog; public static OlEndDialog olEndDialog; - public OlUI(KeyBinds.KeyBind... binds) { - setKeybinds(binds); - - + public OlUI() { Events.on(EventType.ClientLoadEvent.class,it->onClient()); } protected void onClient(){ @@ -48,20 +43,4 @@ protected void onClient(){ cliffFragment.build(Vars.ui.hudGroup); } - /** - * @author Zelaux - * source - * */ - protected void setKeybinds(KeyBinds.KeyBind... modBindings){ - Time.mark(); - KeyBinds.KeyBind[] originalBinds = Core.keybinds.getKeybinds(); - KeyBinds.KeyBind[] newBinds = new KeyBinds.KeyBind[originalBinds.length + modBindings.length]; - - System.arraycopy(originalBinds,0,newBinds,0,originalBinds.length); - System.arraycopy(modBindings,0,newBinds,originalBinds.length,modBindings.length); - - OmaloonMod.olLog("Time to combine arrays: @ms",Time.elapsed()); - Core.keybinds.setDefaults(newBinds); - settings.load(); - } } diff --git a/src/omaloon/core/extra/AnchorNotFound.java b/src/omaloon/core/extra/AnchorNotFound.java new file mode 100644 index 00000000..208d1c4a --- /dev/null +++ b/src/omaloon/core/extra/AnchorNotFound.java @@ -0,0 +1,15 @@ +package omaloon.core.extra; + +import arc.*; +import omaloon.core.extra.RelatedApplicationListener.*; + +public class AnchorNotFound extends RuntimeException{ + public AnchorNotFound(ApplicationListener applicationListener, RelativeOrder relativeOrder, ApplicationListener anchor){ + super(String.format( + "Cannot find '%s' to add listener '%s' with order '%s'", + anchor.toString(), + applicationListener.toString(), + relativeOrder.toString() + )); + } +} diff --git a/src/omaloon/core/extra/RelatedApplicationListener.java b/src/omaloon/core/extra/RelatedApplicationListener.java new file mode 100644 index 00000000..ca8cf27a --- /dev/null +++ b/src/omaloon/core/extra/RelatedApplicationListener.java @@ -0,0 +1,86 @@ +package omaloon.core.extra; + +import arc.*; +import arc.struct.*; +import arc.util.*; +import lombok.*; +import mindustry.*; +import omaloon.*; +import org.intellij.lang.annotations.*; + +import java.lang.reflect.*; + +public class RelatedApplicationListener{ + @SneakyThrows + public static T register(T listener, RelativeOrder relativeOrder, ApplicationListener anchor) throws AnchorNotFound{ + if(Vars.headless){ + Seq listeners = Core.app.getListeners(); + + int i = + resolveIndex(listener, + relativeOrder, + anchor, + listeners.indexOf(anchor), + listeners.size); + + listeners.insert(i,listener); + }else{ + ClientLauncher launcher = OlVars.getClientLauncher(); + Field field = ApplicationCore.class.getDeclaredField("modules"); + field.setAccessible(true); + ApplicationListener[] modules = (ApplicationListener[])field.get(launcher); + + int i = + resolveIndex(listener, + relativeOrder, + anchor, + Structs.indexOf(modules, anchor), + modules.length); + + ApplicationListener[] newModules=new ApplicationListener[modules.length+1]; + System.arraycopy(modules,0,newModules,0,i); + newModules[i]=listener; + System.arraycopy(modules,i,newModules,i+1,modules.length-i); + + field.set(launcher,newModules); + } + return listener; + } + + private static int resolveIndex(ApplicationListener listener, RelativeOrder relativeOrder, ApplicationListener anchor, int i, int length) throws AnchorNotFound{ + if(i ==-1){ + i = relativeOrder.resolveNoIndex(length); + if(i ==-1)throw new AnchorNotFound(listener, relativeOrder, anchor); + return i; + } + return relativeOrder.resolveShift(i, length); + } + + @AllArgsConstructor + public enum RelativeOrder{ + before(-1), + beforeOrEnd(1), + beforeOrStart(0), + after(-1), + afterOrEnd(1), + afterOrStart(0), + ; + public final int id = ordinal(); + @MagicConstant(intValues = {-1, 0, 1}) + private final int type; + + public int resolveShift(int index, int length){ + if(id <= beforeOrStart.ordinal()){ + return index; + } + + return Math.min(index + 1,length); + + } + + public int resolveNoIndex(int length){ + if(type == -1) return -1; + return length * type; + } + } +} diff --git a/src/omaloon/entities/abilities/DroneAbility.java b/src/omaloon/entities/abilities/DroneAbility.java index 1691f6c7..e00189b5 100644 --- a/src/omaloon/entities/abilities/DroneAbility.java +++ b/src/omaloon/entities/abilities/DroneAbility.java @@ -23,10 +23,15 @@ import omaloon.core.*; import omaloon.gen.*; import omaloon.type.*; +import org.jetbrains.annotations.Nullable; public class DroneAbility extends Ability implements IClockedAbility{ public static final int DRONE_SEARCH_TIME = 50; private static final Vec2[] EMPTY_VEC2_ARRAY = new Vec2[0]; + private static final IntMap abilityIndeciesMap = new IntMap<>(); + private static final IntSeq tmpIntSeq = new IntSeq(); + @Nullable + private static Bits droneOwners; private final Vec2 calculatedSpawnPos = new Vec2(); public String name = "omaloon-drone"; public DroneUnitType droneUnit; @@ -43,7 +48,6 @@ public class DroneAbility extends Ability implements IClockedAbility{ public Func droneController = DroneAI::new; protected float timer = 0f; protected float droneSearchTimer = DRONE_SEARCH_TIME; - protected DroneAI sampleController; public DroneAbility(DroneUnitType droneUnit){ @@ -58,6 +62,14 @@ private DroneAbility(){ } + public static boolean isDroneOwner(UnitType type){ + return droneOwners != null && droneOwners.get(type.id); + } + + public static int[] abilityIndecies(UnitType type){ +return abilityIndeciesMap.get(type.id); + } + public void droneUnit(UnitType droneType){ if(!(droneType instanceof DroneUnitType drone)) throw new IllegalArgumentException("Expected " + DroneUnitType.class + " but found " + droneType.getClass()); this.droneUnit = drone; @@ -65,6 +77,18 @@ public void droneUnit(UnitType droneType){ @Override public void init(UnitType type){ + if(droneOwners == null){ + droneOwners = new Bits(Vars.content.units().size); + } + if(!droneOwners.get(type.id)){ + droneOwners.set(type.id); + tmpIntSeq.size = 0; + for(int i = 0; i < type.abilities.size; i++){ + if(!(type.abilities.get(i) instanceof DroneAbility)) continue; + tmpIntSeq.add(i); + } + abilityIndeciesMap.put(type.id, tmpIntSeq.toArray()); + } this.data = 0; sampleController = droneController.get(Nulls.unit); } diff --git a/src/omaloon/world/save/OlDelayedItemTransfer.java b/src/omaloon/world/save/OlDelayedItemTransfer.java index 99c76bd3..d53d4e03 100644 --- a/src/omaloon/world/save/OlDelayedItemTransfer.java +++ b/src/omaloon/world/save/OlDelayedItemTransfer.java @@ -46,7 +46,7 @@ private static void firstState(Item item, float x, float y, Unit owner, Building Call.transferItemTo(owner,owner.item(),amount,owner.x,owner.y,core); owner.clearItem(); } - owner.addItem(item); +// owner.addItem(item); secondState(request); }); } @@ -61,9 +61,9 @@ private static void secondState(Request request) { return; } InputHandler.createItemTransfer(item, 1, owner.x, owner.y, core, () -> { - if (owner.stack().item != item || owner.stack().amount <= 0) return; +// if (owner.stack().item != item || owner.stack().amount <= 0) return; int amount = core.acceptStack(item, 1, owner); - owner.stack().amount -=amount; +// owner.stack().amount -=amount; core.handleStack(item,amount,owner); requests.remove(request); requestPool.free(request); diff --git a/tests/setup-tests.gradle b/tests/setup-tests.gradle index 0d2e425c..b32eaf08 100644 --- a/tests/setup-tests.gradle +++ b/tests/setup-tests.gradle @@ -12,10 +12,10 @@ test { }*/ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' testCompileOnly 'org.projectlombok:lombok:1.18.32' testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' - testAnnotationProcessor project(":annotations") - + testAnnotationProcessor(project(":annotations")) } \ No newline at end of file diff --git a/tests/test/omaloon/core/AbstractRelatedApplicationListenerTest.java b/tests/test/omaloon/core/AbstractRelatedApplicationListenerTest.java new file mode 100644 index 00000000..881f8bea --- /dev/null +++ b/tests/test/omaloon/core/AbstractRelatedApplicationListenerTest.java @@ -0,0 +1,54 @@ +package omaloon.core; + +import arc.*; +import arc.util.*; +import lombok.*; +import omaloon.core.extra.*; +import omaloon.core.extra.RelatedApplicationListener.*; +import org.jetbrains.annotations.*; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +public abstract class AbstractRelatedApplicationListenerTest{ + + public static final NamedApplicationListener[] tmpListeners; + public static final NamedApplicationListener injected = listener("injected"); + + static{ + tmpListeners = new NamedApplicationListener[4]; + for(int i = 0; i < tmpListeners.length; i++){ + tmpListeners[i] = listener(i + ""); + } + } + + + static @NotNull NamedApplicationListener listener(String name){ + return new NamedApplicationListener(name); + } + + static @NotNull NamedApplicationListener getUnknown(){ + return listener("unknown"); + } + + static int[] i(int... ints){ + return ints; + } + + abstract ApplicationListener[] getModules(); + + @SneakyThrows + protected void tryInject(RelativeOrder order, NamedApplicationListener anchor, int[] expectedScheme){ + RelatedApplicationListener.register(injected, order, anchor); + ApplicationListener[] modules = getModules(); + int[] currentScheme = new int[modules.length]; + for(int i = 0; i < modules.length; i++){ + ApplicationListener module_ = modules[i]; + NamedApplicationListener module = (NamedApplicationListener)module_; + currentScheme[i] = Strings.parseInt(module.name, -1); + } + assertEquals(Arrays.toString(expectedScheme), Arrays.toString( currentScheme)); + } + +} diff --git a/tests/test/omaloon/core/ClientRelatedApplicationListenerTest.java b/tests/test/omaloon/core/ClientRelatedApplicationListenerTest.java new file mode 100644 index 00000000..dd151274 --- /dev/null +++ b/tests/test/omaloon/core/ClientRelatedApplicationListenerTest.java @@ -0,0 +1,77 @@ +package omaloon.core; + +import arc.*; +import lombok.*; +import mindustry.*; +import omaloon.*; +import omaloon.core.extra.*; +import omaloon.core.extra.RelatedApplicationListener.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; + +import java.lang.reflect.*; +import java.util.concurrent.atomic.*; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ClientRelatedApplicationListenerTest extends AbstractRelatedApplicationListenerTest{ + + private MockClientLauncher clientLauncher; + + + @SneakyThrows + private static AtomicReference getClientLauncherRef(){ + Field field = OlVars.class.getDeclaredField("clientLauncher"); + field.setAccessible(true); + //noinspection unchecked + return (AtomicReference)field.get(null); + } + + @AfterAll + static void afterAll(){ + getClientLauncherRef().set(null); + } + + @SneakyThrows + @BeforeEach + void setUp(){ + getClientLauncherRef().set(clientLauncher = new MockClientLauncher()); + for(ApplicationListener listener : tmpListeners){ + clientLauncher.add(listener); + } + } + + @SneakyThrows() + @ParameterizedTest + @EnumSource(RelativeOrder.class) + void testInject(RelativeOrder order){ + tryInject(order, tmpListeners[1], switch(order){ + case before, beforeOrEnd, beforeOrStart -> i(0, -1, 1, 2, 3); + case after, afterOrEnd, afterOrStart -> i(0, 1, -1, 2, 3); + }); + } + + @ParameterizedTest + @EnumSource(RelativeOrder.class) + void checkMissing(RelativeOrder order){ + int[] scheme = switch(order){ + case before, after -> { + assertThrows(AnchorNotFound.class, () -> { + tryInject(order, getUnknown(), i()); + }); + + yield null; + } + case beforeOrStart, afterOrStart -> i(-1, 0, 1, 2, 3); + case beforeOrEnd, afterOrEnd -> i(0, 1, 2, 3, -1); + }; + if(scheme == null) return; + tryInject(order, getUnknown(), scheme); + } + + @Override + ApplicationListener[] getModules(){ + return clientLauncher.modules(); + } +} diff --git a/tests/test/omaloon/core/MockClientLauncher.java b/tests/test/omaloon/core/MockClientLauncher.java new file mode 100644 index 00000000..3d29f312 --- /dev/null +++ b/tests/test/omaloon/core/MockClientLauncher.java @@ -0,0 +1,10 @@ +package omaloon.core; + +import arc.*; +import mindustry.*; + +class MockClientLauncher extends ClientLauncher{ + public ApplicationListener[] modules(){ + return modules; + } +} diff --git a/tests/test/omaloon/core/NamedApplicationListener.java b/tests/test/omaloon/core/NamedApplicationListener.java new file mode 100644 index 00000000..4bf83678 --- /dev/null +++ b/tests/test/omaloon/core/NamedApplicationListener.java @@ -0,0 +1,15 @@ +package omaloon.core; + +import arc.*; + +public class NamedApplicationListener implements ApplicationListener{ + + public final String name; + + public NamedApplicationListener(String name){this.name = name;} + + @Override + public String toString(){ + return name; + } +} diff --git a/tests/test/omaloon/core/ServerRelatedApplicationListenerTest.java b/tests/test/omaloon/core/ServerRelatedApplicationListenerTest.java new file mode 100644 index 00000000..af71d2a1 --- /dev/null +++ b/tests/test/omaloon/core/ServerRelatedApplicationListenerTest.java @@ -0,0 +1,74 @@ +package omaloon.core; + +import arc.*; +import arc.mock.*; +import arc.struct.*; +import lombok.*; +import mindustry.*; +import omaloon.*; +import omaloon.core.extra.*; +import omaloon.core.extra.RelatedApplicationListener.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; + +import java.lang.reflect.*; +import java.util.concurrent.atomic.*; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ServerRelatedApplicationListenerTest extends AbstractRelatedApplicationListenerTest{ + private static Seq myListeners=new Seq<>(ApplicationListener.class); + + + @AfterAll + static void afterAll(){ + Core.app=null; + Vars.headless=false; + } + @SneakyThrows + @BeforeEach + void setUp(){ + Vars.headless=true; + Core.app=new MockApplication(){ + @Override + public Seq getListeners(){ + return myListeners; + } + }; + myListeners.set(tmpListeners); + } + + @SneakyThrows() + @ParameterizedTest + @EnumSource(RelativeOrder.class) + void testInject(RelativeOrder order){ + tryInject(order, tmpListeners[1], switch(order){ + case before, beforeOrEnd, beforeOrStart -> i(0, -1, 1, 2, 3); + case after, afterOrEnd, afterOrStart -> i(0, 1, -1, 2, 3); + }); + } + + @ParameterizedTest + @EnumSource(RelativeOrder.class) + void checkMissing(RelativeOrder order){ + int[] scheme = switch(order){ + case before, after -> { + assertThrows(AnchorNotFound.class, () -> { + tryInject(order, getUnknown(), i()); + }); + + yield null; + } + case beforeOrStart, afterOrStart -> i(-1, 0, 1, 2, 3); + case beforeOrEnd, afterOrEnd -> i(0, 1, 2, 3, -1); + }; + if(scheme == null) return; + tryInject(order, getUnknown(), scheme); + } + + @Override + ApplicationListener[] getModules(){ + return myListeners.toArray(); + } +}