Skip to content

Commit f577944

Browse files
refactor: add event flow for GameView update (#81)
* feat(game): make GameView more event driven * test(game): add view tests * feat(game): add view update listener * chore(game): change view update handling * test(view): move collector creation * test(view): add tick call * chore(view): disable integration test * test(view): fix constructor usage --------- Co-authored-by: theEvilReaper <theEvilReaper@users.noreply.github.com>
1 parent 80df152 commit f577944

10 files changed

Lines changed: 167 additions & 29 deletions

File tree

game/src/main/java/net/onelitefeather/cygnus/Cygnus.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
import net.onelitefeather.cygnus.common.page.event.PageDiscoveryCompletedEvent;
44
import net.onelitefeather.cygnus.event.GameStartEvent;
55
import net.onelitefeather.cygnus.listener.game.GameStartListener;
6+
import net.onelitefeather.cygnus.listener.view.ViewUpdateListener;
67
import net.onelitefeather.cygnus.listener.page.PageDiscoveryCompleteListener;
78
import net.onelitefeather.cygnus.map.GameMapProvider;
89
import net.onelitefeather.cygnus.map.event.GameMapLoadedEvent;
10+
import net.onelitefeather.cygnus.view.event.ViewUpdateEvent;
911
import net.theevilreaper.aves.map.provider.AbstractMapProvider;
10-
import net.theevilreaper.aves.util.Strings;
11-
import net.theevilreaper.aves.util.TimeFormat;
1212
import net.theevilreaper.aves.util.functional.VoidConsumer;
1313
import net.theevilreaper.xerus.api.phase.LinearPhaseSeries;
1414
import net.theevilreaper.xerus.api.phase.Phase;
1515
import net.theevilreaper.xerus.api.phase.TimedPhase;
1616
import net.theevilreaper.xerus.api.team.TeamService;
17-
import net.kyori.adventure.text.Component;
1817
import net.minestom.server.MinecraftServer;
1918
import net.minestom.server.entity.Player;
2019
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
@@ -28,7 +27,6 @@
2827
import net.onelitefeather.cygnus.ambient.AmbientProvider;
2928
import net.onelitefeather.cygnus.command.StartCommand;
3029
import net.onelitefeather.cygnus.common.ListenerHandling;
31-
import net.onelitefeather.cygnus.common.Messages;
3230
import net.onelitefeather.cygnus.common.config.GameConfig;
3331
import net.onelitefeather.cygnus.common.config.GameConfigReader;
3432
import net.onelitefeather.cygnus.common.event.GamePreLaunchEvent;
@@ -100,7 +98,7 @@ public Cygnus() {
10098
MinecraftServer.getConnectionManager().setPlayerProvider(CygnusPlayer::new);
10199
this.pageProvider = new PageProvider();
102100
this.mapProvider = new GameMapProvider(path);
103-
this.view = new GameViewImpl(this::getViewComponent);
101+
this.view = new GameViewImpl();
104102
this.createTeams(this.gameConfig, this.teamService, this.ambientProvider);
105103
this.initPhases();
106104
this.initCommands();
@@ -152,6 +150,8 @@ private void registerGameListener() {
152150
manager.addListener(GamePreLaunchEvent.class, new GamePreLaunchListener(this.pageProvider::setMaxPageAmount));
153151
manager.addListener(StaminaStateChangeEvent.class, new StaminaStateChangeListener());
154152
manager.addListener(PageDiscoveryCompletedEvent.class, new PageDiscoveryCompleteListener(this.linearPhaseSeries));
153+
manager.addListener(ViewUpdateEvent.class, new ViewUpdateListener(this.view, this.pageProvider));
154+
155155
MinecraftServer.getPacketListenerManager().setPlayListener(ClientEntityActionPacket.class, CygnusEntityActionListener::listener);
156156
}
157157

@@ -180,14 +180,6 @@ private void finishGame() {
180180
MinecraftServer.getPacketListenerManager().setPlayListener(ClientEntityActionPacket.class, EntityActionListener::listener);
181181
}
182182

183-
private @NotNull Component getViewComponent() {
184-
var gamePhase = (GamePhase) this.linearPhaseSeries.getCurrentPhase();
185-
return Messages.getViewComponent(
186-
Strings.getTimeString(TimeFormat.MM_SS, gamePhase.getCurrentTicks()),
187-
this.pageProvider.getPageStatus()
188-
);
189-
}
190-
191183
private void triggerViewRuleUpdate(@NotNull Player player) {
192184
ViewRuleUpdater.updateViewer(player, this.teamService.getTeams().get(Helper.SURVIVOR_ID));
193185
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.onelitefeather.cygnus.listener.view;
2+
3+
import net.kyori.adventure.text.Component;
4+
import net.onelitefeather.cygnus.common.Messages;
5+
import net.onelitefeather.cygnus.common.page.PageProvider;
6+
import net.onelitefeather.cygnus.phase.GamePhase;
7+
import net.onelitefeather.cygnus.view.GameView;
8+
import net.onelitefeather.cygnus.view.event.ViewUpdateEvent;
9+
import net.theevilreaper.aves.util.Strings;
10+
import net.theevilreaper.aves.util.TimeFormat;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.util.function.Consumer;
14+
15+
public class ViewUpdateListener implements Consumer<ViewUpdateEvent> {
16+
17+
private final GameView gameView;
18+
private final PageProvider pageProvider;
19+
20+
public ViewUpdateListener(GameView gameView, PageProvider pageProvider) {
21+
this.gameView = gameView;
22+
this.pageProvider = pageProvider;
23+
}
24+
25+
@Override
26+
public void accept(ViewUpdateEvent event) {
27+
int ticks = event.ticks();
28+
Component component = Messages.getViewComponent(
29+
Strings.getTimeString(TimeFormat.MM_SS, ticks),
30+
this.pageProvider.getPageStatus()
31+
);
32+
this.gameView.updateView(component);
33+
}
34+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@NotNullByDefault
2+
package net.onelitefeather.cygnus.listener.view;
3+
4+
import org.jetbrains.annotations.NotNullByDefault;

game/src/main/java/net/onelitefeather/cygnus/phase/GamePhase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import net.minestom.server.event.EventDispatcher;
44
import net.onelitefeather.cygnus.event.GameStartEvent;
5+
import net.onelitefeather.cygnus.view.event.ViewUpdateEvent;
56
import net.theevilreaper.xerus.api.phase.TickDirection;
67
import net.theevilreaper.xerus.api.phase.TimedPhase;
78
import net.minestom.server.MinecraftServer;
@@ -72,6 +73,6 @@ protected void onFinish() {
7273
*/
7374
@Override
7475
public void onUpdate() {
75-
this.gameView.updateView();
76+
EventDispatcher.call(new ViewUpdateEvent(getCurrentTicks()));
7677
}
7778
}
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
package net.onelitefeather.cygnus.view;
22

3+
import net.kyori.adventure.text.Component;
34
import net.theevilreaper.xerus.api.Joinable;
45

6+
/**
7+
* Represents a view that can be displayed to players
8+
*
9+
* @author theEvilReaper
10+
* @version 1.1.0
11+
* @since 0.1.0
12+
*/
513
public interface GameView extends Joinable {
614

7-
void updateView();
15+
/**
16+
* Updates the view with a new {@link Component} to display
17+
*
18+
* @param component to display
19+
*/
20+
void updateView(Component component);
821
}

game/src/main/java/net/onelitefeather/cygnus/view/GameViewImpl.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@
1111
public final class GameViewImpl implements GameView {
1212

1313
private final BossBar bossBar;
14-
private final ViewUpdater updateFunction;
1514

16-
public GameViewImpl(ViewUpdater updateFunction) {
17-
this.updateFunction = updateFunction;
15+
public GameViewImpl() {
1816
this.bossBar = BossBar.bossBar(Component.empty(), 1f, BossBar.Color.WHITE, BossBar.Overlay.PROGRESS);
1917
}
2018

2119
@Override
22-
public void updateView() {
23-
this.bossBar.name(this.updateFunction.updateView());
20+
public void updateView(Component component) {
21+
this.bossBar.name(component);
2422
}
2523

2624
@Override

game/src/main/java/net/onelitefeather/cygnus/view/ViewUpdater.java

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.onelitefeather.cygnus.view.event;
2+
3+
import net.minestom.server.event.Event;
4+
5+
/**
6+
* The event is used that the {@link net.onelitefeather.cygnus.view.GameView} needs to be updated.
7+
*
8+
* @param ticks value to update the view
9+
* @author theEvilReaper
10+
* @version 1.0.0
11+
* @since 2.3.1
12+
*/
13+
public record ViewUpdateEvent(int ticks) implements Event {
14+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package net.onelitefeather.cygnus.view;
2+
3+
import net.kyori.adventure.text.Component;
4+
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
5+
import net.minestom.server.entity.Player;
6+
import net.minestom.server.event.EventFilter;
7+
import net.minestom.server.instance.Instance;
8+
import net.minestom.server.network.packet.server.play.BossBarPacket;
9+
import net.minestom.testing.Collector;
10+
import net.minestom.testing.Env;
11+
import net.minestom.testing.TestConnection;
12+
import net.minestom.testing.extension.MicrotusExtension;
13+
import net.onelitefeather.cygnus.common.page.PageProvider;
14+
import net.onelitefeather.cygnus.listener.view.ViewUpdateListener;
15+
import net.onelitefeather.cygnus.view.event.ViewUpdateEvent;
16+
import org.junit.jupiter.api.Disabled;
17+
import org.junit.jupiter.api.Test;
18+
import org.junit.jupiter.api.extension.ExtendWith;
19+
20+
import static org.junit.jupiter.api.Assertions.*;
21+
22+
@ExtendWith(MicrotusExtension.class)
23+
class GameViewIntegrationTest {
24+
25+
@Disabled("Investigate why this test is broken")
26+
@Test
27+
void testViewUpdate(Env env) {
28+
Instance instance = env.createEmptyInstance();
29+
TestConnection connection = env.createConnection();
30+
Player player = connection.connect(instance);
31+
GameView gameView = new GameViewImpl();
32+
PageProvider pageProvider = new PageProvider();
33+
34+
env.process().eventHandler().addListener(ViewUpdateEvent.class, new ViewUpdateListener(gameView, pageProvider));
35+
36+
Collector<BossBarPacket> barCollector = connection.trackIncoming(BossBarPacket.class);
37+
38+
gameView.addPlayer(player);
39+
40+
barCollector.assertSingle();
41+
42+
ViewUpdateEvent updateEvent = new ViewUpdateEvent(100);
43+
44+
EventFilter<ViewUpdateEvent, ViewUpdateEvent> filter = EventFilter.from(
45+
ViewUpdateEvent.class,
46+
ViewUpdateEvent.class,
47+
e -> e
48+
);
49+
Collector<ViewUpdateEvent> eventCollector = env.trackEvent(ViewUpdateEvent.class, filter, updateEvent);
50+
Collector<BossBarPacket> secondBarCollector = connection.trackIncoming(BossBarPacket.class);
51+
52+
env.process().eventHandler().call(updateEvent);
53+
54+
env.tick();
55+
56+
eventCollector.assertSingle();
57+
eventCollector.assertSingle(event -> {
58+
assertEquals(updateEvent.ticks(), event.ticks());
59+
});
60+
61+
secondBarCollector.assertSingle(bossBarPacket -> {
62+
assertInstanceOf(BossBarPacket.UpdateTitleAction.class, bossBarPacket.action());
63+
64+
BossBarPacket.UpdateTitleAction updateTitle = ((BossBarPacket.UpdateTitleAction) bossBarPacket.action());
65+
assertEquals(1, updateTitle.components().size());
66+
Component component = updateTitle.components().stream().findAny().orElse(Component.empty());
67+
assertNotEquals(component, Component.empty());
68+
69+
String content = PlainTextComponentSerializer.plainText().serialize(component);
70+
assertTrue(content.contains("Time: 01:40"));
71+
});
72+
73+
env.destroyInstance(instance, true);
74+
}
75+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.onelitefeather.cygnus.view.event;
2+
3+
import net.minestom.server.event.Event;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.junit.jupiter.api.Assertions.*;
7+
8+
class ViewUpdateEventTest {
9+
10+
@Test
11+
void testEventCreation() {
12+
ViewUpdateEvent viewUpdateEvent = new ViewUpdateEvent(100);
13+
assertEquals(100, viewUpdateEvent.ticks());
14+
assertInstanceOf(Event.class, viewUpdateEvent);
15+
}
16+
}

0 commit comments

Comments
 (0)