I have a "console" window in-game where I log messages. When starting up, the game checks for updates by way of a Timer.Task. Any messages I try to log in the task are not displayed, but the file logs show that they were recorded at the proper time. I assume it's a rendering problem and the console's screen fails to render during the task execution.
I use Dagger2 for dependency-injection but the Screen is a @Singleton, plus there are logs in the constructor that are only written once, so I'm confident that the instance injected in MyGame and the one passed to StartupTask are the same.
I would like the console to continue displaying messages "in real time" while the update task is running. What am I missing?
Game class:
public class MyGame extends Game {
private static final Logger LOGGER = LoggerFactory.getLogger(MyGame.class);
private final Lazy<ConsoleScreen> bootScreen;
private final Lazy<StartupTaskProvider> startupTaskProvider;
public MyGame(Lazy<ConsoleScreen> bootScreen, Lazy<StartupTaskProvider> startupTaskProvider) {
super();
this.bootScreen = bootScreen;
this.startupTaskProvider = startupTaskProvider;
}
@Override
public void create() {
LOGGER.info("Startup phase.");
final ConsoleScreen console = bootScreen.get();
this.setScreen(console);
console.addLog("Initialization"); // <--- Correctly displayed
// Update when booting.
Timer.schedule(startupTaskProvider.get().create(), 2);
}
@Override
public void render() {
super.render();
}
@Override
public void dispose() {
}
Provider for MyGame: (Used as a glue between Dagger2 and the call to new Lwjgl3Application)
@Module
public class GameModule {
@Provides
@Singleton
static MyGame provideGame(Lazy<ConsoleScreen> bootScreen, Lazy<StartupTaskProvider> startupTaskProvider) {
return new MyGame(bootScreen, startupTaskProvider);
}
}
Screen class:
@Singleton
public class ConsoleScreen implements Screen {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleScreen.class);
@Inject
DebugUtils debugUtils;
@Inject
TextUtils textUtils;
private final Stage stage;
private final Table table;
private final List<Label> logs;
private final int maxSize;
@Inject
public ConsoleScreen(DebugUtils debugUtils, TextUtils textUtils) {
// Creates the Stage and adds the Table to it, works fine.
}
public void addLog(String text) {
// Adds the text to the Table, works fine.
}
@Override
public void show() {
Gdx.input.setInputProcessor(stage);
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
stage.dispose();
}
Startup task:
public class StartupTask extends Timer.Task {
private final MyGame game;
private final ConsoleScreen consoleScreen;
private final MainScreen mainScreen;
private final UpdateService updateService;
public StartupTask(ConsoleScreen consoleScreen, MyGame game, MainScreen mainScreen, UpdateService service) {
this.game = game;
this.consoleScreen = consoleScreen;
this.mainScreen = mainScreen;
this.updateService = service;
}
@Override
public void run() {
consoleScreen.addLog("Starting update"); // <-- Does not display, at least not before the screen is changed.
updateService.start().get(); // <-- Executes correctly
// The screen is then switched and rendered correctly.
game.setScreen(mainScreen);
mainScreen.fadeIn();
}
}
Provider for startup tasks:
@Module
public class StartupTaskProvider {
@Inject
MyGame game;
@Inject
ConsoleScreen consoleScreen;
@Inject
MainScreen mainScreen;
@Inject
UpdateService service;
@Inject
public StartupTaskProvider() {}
@Provides
@Singleton
public StartupTask create() {
return new StartupTask(consoleScreen, game, mainScreen, service);
}
}