Skip to content

Commit c62e776

Browse files
authored
fix(headless-fixes): remove InputSystem and NuiManager from headlesses (#4907)
1 parent 8f6ef15 commit c62e776

File tree

12 files changed

+84
-67
lines changed

12 files changed

+84
-67
lines changed

engine/src/main/java/org/terasology/engine/core/TerasologyEngine.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ private void verifyInitialisation() {
247247
verifyRequiredSystemIsRegistered(Time.class);
248248
verifyRequiredSystemIsRegistered(DisplayDevice.class);
249249
verifyRequiredSystemIsRegistered(RenderingSubsystemFactory.class);
250-
verifyRequiredSystemIsRegistered(InputSystem.class);
251250
}
252251

253252
/**
@@ -588,7 +587,9 @@ private void switchState(GameState newState) {
588587
newState.init(this);
589588
stateChangeSubscribers.forEach(StateChangeSubscriber::onStateChange);
590589
InputSystem inputSystem = rootContext.get(InputSystem.class);
591-
inputSystem.drainQueues();
590+
if (inputSystem != null) {
591+
inputSystem.drainQueues();
592+
}
592593
}
593594

594595
@Override

engine/src/main/java/org/terasology/engine/core/modes/AbstractState.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public abstract class AbstractState implements GameState {
3131
protected EventSystem eventSystem;
3232
protected ComponentSystemManager componentSystemManager;
3333

34-
protected void initEntityAndComponentManagers() {
34+
protected void initEntityAndComponentManagers(boolean isHeadless) {
3535
verifyNotNull(context);
3636
CoreRegistry.setContext(context);
3737

@@ -41,9 +41,10 @@ protected void initEntityAndComponentManagers() {
4141

4242
eventSystem = context.get(EventSystem.class);
4343
context.put(Console.class, new ConsoleImpl(context));
44-
45-
NUIManager nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
46-
context.put(NUIManager.class, nuiManager);
44+
if (!isHeadless) {
45+
NUIManager nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
46+
context.put(NUIManager.class, nuiManager);
47+
}
4748

4849
componentSystemManager = new ComponentSystemManager(context);
4950
context.put(ComponentSystemManager.class, componentSystemManager);

engine/src/main/java/org/terasology/engine/core/modes/StateIngame.java

+27-18
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,28 @@ public void init(GameEngine engine) {
8383
componentSystemManager = context.get(ComponentSystemManager.class);
8484
entityManager = context.get(EngineEntityManager.class);
8585
cameraTargetSystem = context.get(CameraTargetSystem.class);
86-
inputSystem = context.get(InputSystem.class);
87-
eventSystem.registerEventHandler(nuiManager);
86+
if (nuiManager != null) {
87+
inputSystem = context.get(InputSystem.class);
88+
eventSystem.registerEventHandler(nuiManager);
89+
}
8890
networkSystem = context.get(NetworkSystem.class);
8991
storageManager = context.get(StorageManager.class);
9092
storageServiceWorker = context.get(StorageServiceWorker.class);
9193
console = context.get(Console.class);
9294

93-
// Show or hide the HUD according to the settings
94-
nuiManager.getHUD().bindVisible(new ReadOnlyBinding<Boolean>() {
95-
@Override
96-
public Boolean get() {
97-
return !context.get(Config.class).getRendering().getDebug().isHudHidden();
98-
}
99-
});
95+
if (nuiManager != null) {
96+
// Show or hide the HUD according to the settings
97+
nuiManager.getHUD().bindVisible(new ReadOnlyBinding<Boolean>() {
98+
@Override
99+
public Boolean get() {
100+
return !context.get(Config.class).getRendering().getDebug().isHudHidden();
101+
}
102+
});
103+
}
100104

101105
if (networkSystem.getMode() == NetworkMode.CLIENT) {
102106
String motd = networkSystem.getServer().getInfo().getMOTD();
103-
if (motd != null && motd.length() != 0) {
107+
if (nuiManager != null && motd != null && motd.length() != 0) {
104108
nuiManager.pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage("Server MOTD", motd);
105109
}
106110
}
@@ -133,7 +137,9 @@ public void dispose(boolean shuttingDown) {
133137
// TODO: Shutdown background threads
134138
eventSystem.process();
135139
GameThread.processWaitingProcesses();
136-
nuiManager.clear();
140+
if (nuiManager != null) {
141+
nuiManager.clear();
142+
}
137143

138144
context.get(AudioManager.class).stopAllSounds();
139145

@@ -162,11 +168,13 @@ public void dispose(boolean shuttingDown) {
162168
console.dispose();
163169
GameThread.clearWaitingProcesses();
164170

165-
/*
166-
* Clear the binding as otherwise the complete ingame state would be
167-
* referenced.
168-
*/
169-
nuiManager.getHUD().clearVisibleBinding();
171+
if (nuiManager != null) {
172+
/*
173+
* Clear the binding as otherwise the complete ingame state would be
174+
* referenced.
175+
*/
176+
nuiManager.getHUD().clearVisibleBinding();
177+
}
170178
}
171179

172180
@Override
@@ -187,8 +195,9 @@ public void update(float delta) {
187195
storageManager.update();
188196
}
189197

190-
191-
updateUserInterface(delta);
198+
if (nuiManager != null) {
199+
updateUserInterface(delta);
200+
}
192201

193202
storageServiceWorker.flushNotificationsToConsole(console);
194203
}

engine/src/main/java/org/terasology/engine/core/modes/StateLoading.java

+27-15
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
import org.terasology.engine.core.modes.loadProcesses.InitialisePhysics;
2727
import org.terasology.engine.core.modes.loadProcesses.InitialiseRecordAndReplay;
2828
import org.terasology.engine.core.modes.loadProcesses.InitialiseRemoteWorld;
29+
import org.terasology.engine.core.modes.loadProcesses.InitialiseRendering;
2930
import org.terasology.engine.core.modes.loadProcesses.InitialiseSystems;
3031
import org.terasology.engine.core.modes.loadProcesses.InitialiseWorld;
3132
import org.terasology.engine.core.modes.loadProcesses.InitialiseWorldGenerator;
32-
import org.terasology.engine.core.modes.loadProcesses.InitialiseRendering;
3333
import org.terasology.engine.core.modes.loadProcesses.JoinServer;
3434
import org.terasology.engine.core.modes.loadProcesses.LoadEntities;
3535
import org.terasology.engine.core.modes.loadProcesses.LoadExtraBlockData;
@@ -110,8 +110,10 @@ public void init(GameEngine engine) {
110110

111111
systemConfig = context.get(SystemConfig.class);
112112

113-
this.nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
114-
context.put(NUIManager.class, nuiManager);
113+
if (netMode.hasLocalClient()) {
114+
this.nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
115+
context.put(NUIManager.class, nuiManager);
116+
}
115117

116118
EngineTime time = (EngineTime) context.get(Time.class);
117119
time.setPaused(true);
@@ -134,9 +136,10 @@ public void init(GameEngine engine) {
134136
}
135137

136138
popStep();
137-
loadingScreen = nuiManager.pushScreen("engine:loadingScreen", LoadingScreen.class);
138-
loadingScreen.updateStatus(current.getMessage(), current.getProgress());
139-
139+
if (nuiManager != null) {
140+
loadingScreen = nuiManager.pushScreen("engine:loadingScreen", LoadingScreen.class);
141+
loadingScreen.updateStatus(current.getMessage(), current.getProgress());
142+
}
140143
chunkGenerationStarted = false;
141144
}
142145

@@ -167,16 +170,20 @@ private void initClient() {
167170

168171
private void initHost() {
169172
loadProcesses.add(new RegisterMods(context, gameManifest));
170-
if(netMode.hasLocalClient()) {
173+
if (netMode.hasLocalClient()) {
171174
loadProcesses.add(new InitialiseRendering(context));
172175
}
173176
loadProcesses.add(new InitialiseEntitySystem(context));
174177
loadProcesses.add(new RegisterBlocks(context, gameManifest));
175-
loadProcesses.add(new InitialiseGraphics(context));
178+
if (netMode.hasLocalClient()) {
179+
loadProcesses.add(new InitialiseGraphics(context));
180+
}
176181
loadProcesses.add(new LoadPrefabs(context));
177182
loadProcesses.add(new ProcessBlockPrefabs(context));
178183
loadProcesses.add(new InitialiseComponentSystemManager(context));
179-
loadProcesses.add(new RegisterInputSystem(context));
184+
if (netMode.hasLocalClient()) {
185+
loadProcesses.add(new RegisterInputSystem(context));
186+
}
180187
loadProcesses.add(new RegisterSystems(context, netMode));
181188
loadProcesses.add(new InitialiseCommandSystem(context));
182189
loadProcesses.add(new LoadExtraBlockData(context));
@@ -252,14 +259,17 @@ public void update(float delta) {
252259
}
253260
}
254261
if (current == null) {
255-
nuiManager.closeScreen(loadingScreen);
256-
nuiManager.setHUDVisible(true);
262+
if (nuiManager != null) {
263+
nuiManager.closeScreen(loadingScreen);
264+
nuiManager.setHUDVisible(true);
265+
}
257266
context.get(GameEngine.class).changeState(new StateIngame(gameManifest, context));
258267
} else {
259268
float progressValue = (progress + current.getExpectedCost() * current.getProgress()) / maxProgress;
260-
loadingScreen.updateStatus(current.getMessage(), progressValue);
261-
nuiManager.update(delta);
262-
269+
if (nuiManager != null) {
270+
loadingScreen.updateStatus(current.getMessage(), progressValue);
271+
nuiManager.update(delta);
272+
}
263273
// chunk generation begins at the AwaitCharacterSpawn step
264274
if (current instanceof AwaitCharacterSpawn && !chunkGenerationStarted) {
265275
chunkGenerationStarted = true;
@@ -280,7 +290,9 @@ public void update(float delta) {
280290

281291
@Override
282292
public void render() {
283-
nuiManager.render();
293+
if (nuiManager != null) {
294+
nuiManager.render();
295+
}
284296
}
285297

286298
@Override

engine/src/main/java/org/terasology/engine/core/modes/StateMainMenu.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public StateMainMenu(String showMessageOnLoad) {
4444
@Override
4545
public void init(GameEngine gameEngine) {
4646
context = gameEngine.createChildContext();
47-
initEntityAndComponentManagers();
47+
initEntityAndComponentManagers(false);
4848

4949
createLocalPlayer(context);
5050

engine/src/main/java/org/terasology/engine/core/subsystem/headless/HeadlessInput.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import org.terasology.engine.context.Context;
66
import org.terasology.engine.core.subsystem.EngineSubsystem;
7-
import org.terasology.engine.input.InputSystem;
87

98
public class HeadlessInput implements EngineSubsystem {
109

@@ -19,8 +18,7 @@ public void postInitialise(Context context) {
1918
}
2019

2120
private void initControls(Context context) {
22-
InputSystem inputSystem = new InputSystem();
23-
context.put(InputSystem.class, inputSystem);
21+
2422
}
2523

2624
}

engine/src/main/java/org/terasology/engine/core/subsystem/headless/mode/StateHeadlessSetup.java

+1-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.terasology.engine.core.module.ModuleManager;
1616
import org.terasology.engine.core.module.StandardModuleExtension;
1717
import org.terasology.engine.game.GameManifest;
18-
import org.terasology.engine.input.InputSystem;
1918
import org.terasology.engine.network.NetworkMode;
2019
import org.terasology.engine.rendering.nui.layers.mainMenu.savedGames.GameInfo;
2120
import org.terasology.engine.rendering.nui.layers.mainMenu.savedGames.GameProvider;
@@ -40,12 +39,9 @@ public StateHeadlessSetup() {
4039
@Override
4140
public void init(GameEngine gameEngine) {
4241
context = gameEngine.createChildContext();
43-
initEntityAndComponentManagers();
42+
initEntityAndComponentManagers(true);
4443
createLocalPlayer(context);
4544

46-
componentSystemManager.register(context.get(InputSystem.class), "engine:InputSystem");
47-
componentSystemManager.initialise();
48-
4945
GameManifest gameManifest;
5046
List<GameInfo> savedGames = GameProvider.getSavedGames();
5147
if (savedGames.size() > 0) {

engine/src/main/java/org/terasology/engine/core/subsystem/headless/renderer/HeadlessWorldRenderer.java

-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.joml.Vector3ic;
99
import org.terasology.engine.config.Config;
1010
import org.terasology.engine.context.Context;
11-
import org.terasology.engine.logic.players.LocalPlayerSystem;
1211
import org.terasology.engine.monitoring.PerformanceMonitor;
1312
import org.terasology.engine.rendering.assets.material.Material;
1413
import org.terasology.engine.rendering.cameras.Camera;
@@ -48,8 +47,6 @@ public class HeadlessWorldRenderer implements WorldRenderer {
4847
public HeadlessWorldRenderer(Context context) {
4948
this.worldProvider = context.get(WorldProvider.class);
5049
this.chunkProvider = context.get(ChunkProvider.class);
51-
LocalPlayerSystem localPlayerSystem = context.get(LocalPlayerSystem.class);
52-
localPlayerSystem.setPlayerCamera(noCamera);
5350
config = context.get(Config.class);
5451
}
5552

engine/src/main/java/org/terasology/engine/input/InputSystem.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.terasology.engine.core.subsystem.config.BindsManager;
1515
import org.terasology.engine.entitySystem.entity.EntityRef;
1616
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
17+
import org.terasology.engine.entitySystem.systems.RegisterMode;
1718
import org.terasology.engine.entitySystem.systems.RegisterSystem;
1819
import org.terasology.engine.input.cameraTarget.CameraTargetSystem;
1920
import org.terasology.engine.input.events.CharEvent;
@@ -61,7 +62,7 @@
6162
* In addition to raw keyboard and mouse input, the system handles Bind Buttons and Bind Axis, which can be mapped to
6263
* one or more inputs.
6364
*/
64-
@RegisterSystem
65+
@RegisterSystem(RegisterMode.CLIENT)
6566
public class InputSystem extends BaseComponentSystem {
6667

6768
@In

engine/src/main/java/org/terasology/engine/logic/chat/ChatSystem.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ public class ChatSystem extends BaseComponentSystem {
5050

5151
@Override
5252
public void initialise() {
53-
overlay = nuiManager.addOverlay(NotificationOverlay.ASSET_URI, NotificationOverlay.class);
53+
if (nuiManager != null) {
54+
overlay = nuiManager.addOverlay(NotificationOverlay.ASSET_URI, NotificationOverlay.class);
55+
}
5456
}
5557

5658
@ReceiveEvent(components = ClientComponent.class)

engine/src/main/java/org/terasology/engine/logic/console/ConsoleSystem.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
import org.terasology.engine.entitySystem.systems.BaseComponentSystem;
99
import org.terasology.engine.entitySystem.systems.RegisterMode;
1010
import org.terasology.engine.entitySystem.systems.RegisterSystem;
11+
import org.terasology.engine.input.binds.general.ConsoleButton;
1112
import org.terasology.engine.logic.console.commandSystem.ConsoleCommand;
1213
import org.terasology.engine.logic.console.ui.NotificationOverlay;
13-
import org.terasology.input.ButtonState;
14-
import org.terasology.engine.input.binds.general.ConsoleButton;
1514
import org.terasology.engine.network.ClientComponent;
1615
import org.terasology.engine.registry.In;
1716
import org.terasology.engine.rendering.nui.NUIManager;
17+
import org.terasology.input.ButtonState;
1818

1919
@RegisterSystem
2020
public class ConsoleSystem extends BaseComponentSystem {
@@ -29,16 +29,18 @@ public class ConsoleSystem extends BaseComponentSystem {
2929

3030
@Override
3131
public void initialise() {
32-
overlay = nuiManager.addOverlay(NotificationOverlay.ASSET_URI, NotificationOverlay.class);
33-
console.subscribe((Message message) -> {
34-
if (!nuiManager.isOpen("engine:console")) {
35-
// make sure the message isn't already shown in the chat overlay
36-
if (message.getType() != CoreMessageType.CHAT && message.getType() != CoreMessageType.NOTIFICATION
37-
|| !nuiManager.isOpen("engine:chat")) {
38-
overlay.setVisible(true);
32+
if (nuiManager != null) {
33+
overlay = nuiManager.addOverlay(NotificationOverlay.ASSET_URI, NotificationOverlay.class);
34+
console.subscribe((Message message) -> {
35+
if (!nuiManager.isOpen("engine:console")) {
36+
// make sure the message isn't already shown in the chat overlay
37+
if (message.getType() != CoreMessageType.CHAT && message.getType() != CoreMessageType.NOTIFICATION
38+
|| !nuiManager.isOpen("engine:chat")) {
39+
overlay.setVisible(true);
40+
}
3941
}
40-
}
41-
});
42+
});
43+
}
4244
}
4345

4446
@ReceiveEvent(components = ClientComponent.class, priority = EventPriority.PRIORITY_CRITICAL)

facades/PC/src/main/java/org/terasology/engine/Terasology.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.terasology.engine.core.subsystem.config.BindsSubsystem;
2424
import org.terasology.engine.core.subsystem.headless.HeadlessAudio;
2525
import org.terasology.engine.core.subsystem.headless.HeadlessGraphics;
26-
import org.terasology.engine.core.subsystem.headless.HeadlessInput;
2726
import org.terasology.engine.core.subsystem.headless.HeadlessTimer;
2827
import org.terasology.engine.core.subsystem.headless.mode.HeadlessStateChangeListener;
2928
import org.terasology.engine.core.subsystem.headless.mode.StateHeadlessSetup;
@@ -270,8 +269,7 @@ private void populateSubsystems(TerasologyEngineBuilder builder) {
270269
if (isHeadless) {
271270
builder.add(new HeadlessGraphics())
272271
.add(new HeadlessTimer())
273-
.add(new HeadlessAudio())
274-
.add(new HeadlessInput());
272+
.add(new HeadlessAudio());
275273
} else {
276274
EngineSubsystem audio = soundEnabled ? new LwjglAudio() : new HeadlessAudio();
277275
builder.add(audio)

0 commit comments

Comments
 (0)