Added wrapper around AppGameContainer to catch critical errors.
Critical game errors (detected in Game.updateAndRender()) are now passed through ErrorHandler. Note that the actual exception is not displayed in the ErrorHandler window, only the log. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
2f56bca9f7
commit
ee17b20b25
88
src/itdelatrisu/opsu/Container.java
Normal file
88
src/itdelatrisu/opsu/Container.java
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu! is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package itdelatrisu.opsu;
|
||||
|
||||
import itdelatrisu.opsu.audio.MusicController;
|
||||
|
||||
import org.newdawn.slick.AppGameContainer;
|
||||
import org.newdawn.slick.Game;
|
||||
import org.newdawn.slick.SlickException;
|
||||
|
||||
/**
|
||||
* AppGameContainer extension that sends critical errors to ErrorHandler.
|
||||
*/
|
||||
public class Container extends AppGameContainer {
|
||||
/**
|
||||
* SlickException causing game failure.
|
||||
*/
|
||||
protected SlickException e = null;
|
||||
|
||||
/**
|
||||
* Create a new container wrapping a game
|
||||
*
|
||||
* @param game The game to be wrapped
|
||||
* @throws SlickException Indicates a failure to initialise the display
|
||||
*/
|
||||
public Container(Game game) throws SlickException {
|
||||
super(game);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new container wrapping a game
|
||||
*
|
||||
* @param game The game to be wrapped
|
||||
* @param width The width of the display required
|
||||
* @param height The height of the display required
|
||||
* @param fullscreen True if we want fullscreen mode
|
||||
* @throws SlickException Indicates a failure to initialise the display
|
||||
*/
|
||||
public Container(Game game, int width, int height, boolean fullscreen) throws SlickException {
|
||||
super(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws SlickException {
|
||||
try {
|
||||
setup();
|
||||
getDelta();
|
||||
while (running())
|
||||
gameLoop();
|
||||
} finally {
|
||||
MusicController.reset(); // prevent loading tracks from re-initializing OpenAL
|
||||
destroy();
|
||||
if (e != null) {
|
||||
ErrorHandler.error(null, e, true);
|
||||
e = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (forceExit)
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateAndRender(int delta) throws SlickException {
|
||||
try {
|
||||
super.updateAndRender(delta);
|
||||
} catch (SlickException e) {
|
||||
this.e = e;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,7 +34,6 @@ import java.io.IOException;
|
|||
import java.io.PrintStream;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.newdawn.slick.AppGameContainer;
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.GameContainer;
|
||||
import org.newdawn.slick.SlickException;
|
||||
|
@ -140,7 +139,7 @@ public class Opsu extends StateBasedGame {
|
|||
// start the game
|
||||
Opsu opsu = new Opsu("opsu!");
|
||||
try {
|
||||
AppGameContainer app = new AppGameContainer(opsu);
|
||||
Container app = new Container(opsu);
|
||||
|
||||
// basic game settings
|
||||
Options.setDisplayMode(app);
|
||||
|
@ -173,7 +172,7 @@ public class Opsu extends StateBasedGame {
|
|||
}
|
||||
|
||||
Options.saveOptions();
|
||||
((AppGameContainer) this.getContainer()).destroy();
|
||||
((Container) this.getContainer()).destroy();
|
||||
closeSocket();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -82,24 +82,11 @@ public class MusicController {
|
|||
/**
|
||||
* Plays an audio file at the preview position.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void play(final OsuFile osu, final boolean loop) {
|
||||
boolean play = (lastOsu == null || !osu.audioFilename.equals(lastOsu.audioFilename));
|
||||
lastOsu = osu;
|
||||
if (play) {
|
||||
themePlaying = false;
|
||||
|
||||
// TODO: properly interrupt instead of using deprecated Thread.stop();
|
||||
// interrupt the conversion/track loading
|
||||
if (isTrackLoading())
|
||||
// trackLoader.interrupt();
|
||||
trackLoader.stop();
|
||||
|
||||
if (wavFile != null)
|
||||
wavFile.delete();
|
||||
|
||||
// releases all sources from previous tracks
|
||||
destroyOpenAL();
|
||||
reset();
|
||||
System.gc();
|
||||
|
||||
switch (OsuParser.getExtension(osu.audioFilename.getName())) {
|
||||
|
@ -152,8 +139,6 @@ public class MusicController {
|
|||
player.loop();
|
||||
else
|
||||
player.play();
|
||||
pauseTime = 0f;
|
||||
trackDimmed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,6 +307,38 @@ public class MusicController {
|
|||
trackDimmed = !trackDimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely resets MusicController state.
|
||||
* <p>
|
||||
* Stops the current track, cancels track conversions, erases
|
||||
* temporary files, releases OpenAL sources, and resets state.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void reset() {
|
||||
stop();
|
||||
|
||||
// TODO: properly interrupt instead of using deprecated Thread.stop();
|
||||
// interrupt the conversion/track loading
|
||||
if (isTrackLoading())
|
||||
// trackLoader.interrupt();
|
||||
trackLoader.stop();
|
||||
trackLoader = null;
|
||||
|
||||
// delete temporary WAV file
|
||||
if (wavFile != null) {
|
||||
wavFile.delete();
|
||||
wavFile = null;
|
||||
}
|
||||
|
||||
// reset state
|
||||
themePlaying = false;
|
||||
pauseTime = 0f;
|
||||
trackDimmed = false;
|
||||
|
||||
// releases all sources from previous tracks
|
||||
destroyOpenAL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops and releases all sources, clears each of the specified Audio
|
||||
* buffers, destroys the OpenAL context, and resets SoundStore for future use.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package itdelatrisu.opsu.states;
|
||||
|
||||
import itdelatrisu.opsu.Container;
|
||||
import itdelatrisu.opsu.ErrorHandler;
|
||||
import itdelatrisu.opsu.GameImage;
|
||||
import itdelatrisu.opsu.GameMod;
|
||||
|
@ -43,7 +44,6 @@ import java.util.Locale;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.newdawn.slick.AppGameContainer;
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.GameContainer;
|
||||
import org.newdawn.slick.Graphics;
|
||||
|
@ -1083,10 +1083,10 @@ public class Options extends BasicGameState {
|
|||
* @param app the game container
|
||||
* @throws SlickException failure to set display mode
|
||||
*/
|
||||
public static void setDisplayMode(AppGameContainer app) throws SlickException {
|
||||
public static void setDisplayMode(Container app) throws SlickException {
|
||||
int screenWidth = app.getScreenWidth();
|
||||
int screenHeight = app.getScreenHeight();
|
||||
|
||||
|
||||
// check for larger-than-screen dimensions
|
||||
if (screenWidth < resolution.getWidth() || screenHeight < resolution.getHeight())
|
||||
resolution = Resolution.RES_800_600;
|
||||
|
|
Loading…
Reference in New Issue
Block a user