Added init tasks for resources.
This commit is contained in:
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mightypork.gamecore.core.AppBackend;
|
||||
import mightypork.gamecore.resources.ResourceSetup;
|
||||
import mightypork.gamecore.resources.ResourceInitializer;
|
||||
import mightypork.gamecore.resources.loading.AsyncResourceLoader;
|
||||
import mightypork.gamecore.resources.loading.ResourceLoader;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class AppInitOptions {
|
||||
String configFile = "settings.cfg";
|
||||
String configComment = "Main config file";
|
||||
|
||||
final List<ResourceSetup> resourceLists = new ArrayList<>();
|
||||
final List<ResourceInitializer> resourceLists = new ArrayList<>();
|
||||
final List<KeySetup> keyLists = new ArrayList<>();
|
||||
final List<ConfigSetup> configLists = new ArrayList<>();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class AppInitOptions {
|
||||
}
|
||||
|
||||
|
||||
public void addResources(ResourceSetup res)
|
||||
public void addResources(ResourceInitializer res)
|
||||
{
|
||||
resourceLists.add(res);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import mightypork.gamecore.core.config.Config;
|
||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||
import mightypork.gamecore.gui.screens.impl.CrossfadeOverlay;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.ResourceSetup;
|
||||
import mightypork.gamecore.resources.ResourceInitializer;
|
||||
import mightypork.utils.files.WorkDir;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
@@ -140,7 +140,7 @@ public abstract class BaseApp extends App implements UncaughtExceptionHandler {
|
||||
|
||||
Res.setBaseDir(this);
|
||||
|
||||
for (final ResourceSetup rl : opt.resourceLists) {
|
||||
for (final ResourceInitializer rl : opt.resourceLists) {
|
||||
Res.load(rl);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ public abstract class DeferredAudio extends BaseDeferredResource implements IAud
|
||||
@Override
|
||||
public void play(double gain, double pitch, boolean loop)
|
||||
{
|
||||
play(gain, pitch, loop, App.audio().getListenerPos());
|
||||
play(gain, pitch, loop, App.sound().getListenerPos());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double gain, double pitch, boolean loop, double x, double y)
|
||||
{
|
||||
play(gain, pitch, loop, x, y, App.audio().getListenerPos().z());
|
||||
play(gain, pitch, loop, x, y, App.sound().getListenerPos().z());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface IAudio extends Destroyable {
|
||||
|
||||
|
||||
/**
|
||||
* Resume loop (if was paused)
|
||||
* Resume loop (if was looping and paused)
|
||||
*/
|
||||
void resumeLoop();
|
||||
|
||||
@@ -34,7 +34,8 @@ public interface IAudio extends Destroyable {
|
||||
|
||||
|
||||
/**
|
||||
* Stop audio playback, free source.
|
||||
* Stop audio playback, free source. Meaningful for loops, may not work
|
||||
* properly for effects.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.audio.players.LoopPlayer;
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.utils.exceptions.KeyAlreadyExistsException;
|
||||
|
||||
|
||||
/**
|
||||
@@ -19,6 +21,28 @@ public class SoundRegistry {
|
||||
private final Map<String, LoopPlayer> loops = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Register effect resource
|
||||
*
|
||||
* @param key sound key
|
||||
* @param resourcePath path to the effect resource
|
||||
* @param gain gain adjustment
|
||||
* @param pitch pitch adjustment
|
||||
* @return the just created effect player
|
||||
*/
|
||||
public EffectPlayer addEffect(String key, String resourcePath, double gain, double pitch)
|
||||
{
|
||||
final EffectPlayer effect = App.sound().createEffect(resourcePath);
|
||||
|
||||
effect.setPitch(pitch);
|
||||
effect.setGain(gain);
|
||||
|
||||
addEffect(key, effect);
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register effect resource
|
||||
*
|
||||
@@ -27,10 +51,37 @@ public class SoundRegistry {
|
||||
*/
|
||||
public void addEffect(String key, EffectPlayer effect)
|
||||
{
|
||||
if (effects.containsKey(key)) throw new KeyAlreadyExistsException();
|
||||
|
||||
effects.put(key, effect);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
* @param key sound key
|
||||
* @param resourcePath path to the effect resource
|
||||
* @param gain gain adjustment
|
||||
* @param pitch pitch adjustment
|
||||
* @param fadeIn fadeIn time (s)
|
||||
* @param fadeOut fadeOut time (s)
|
||||
* @return the just created loop player
|
||||
*/
|
||||
public LoopPlayer addLoop(String key, String resourcePath, double gain, double pitch, double fadeIn, double fadeOut)
|
||||
{
|
||||
final LoopPlayer loop = App.sound().createLoop(resourcePath);
|
||||
|
||||
loop.setPitch(pitch);
|
||||
loop.setGain(gain);
|
||||
loop.setFadeTimes(fadeIn, fadeOut);
|
||||
|
||||
addLoop(key, loop);
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
@@ -39,6 +90,8 @@ public class SoundRegistry {
|
||||
*/
|
||||
public void addLoop(String key, LoopPlayer loop)
|
||||
{
|
||||
if (loops.containsKey(key)) throw new KeyAlreadyExistsException();
|
||||
|
||||
loops.put(key, loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,20 +12,20 @@ import mightypork.utils.interfaces.Destroyable;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class AudioPlayer implements Destroyable {
|
||||
|
||||
|
||||
/** the track */
|
||||
private final IAudio audio;
|
||||
|
||||
|
||||
/** base gain for sfx */
|
||||
private double baseGain;
|
||||
|
||||
|
||||
/** base pitch for sfx */
|
||||
private double basePitch;
|
||||
|
||||
|
||||
/** dedicated volume control */
|
||||
private final Volume gainMultiplier;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param track audio resource
|
||||
* @param volume colume control
|
||||
@@ -33,20 +33,20 @@ public abstract class AudioPlayer implements Destroyable {
|
||||
public AudioPlayer(IAudio track, Volume volume)
|
||||
{
|
||||
this.audio = track;
|
||||
|
||||
|
||||
if (volume == null) volume = new Volume(1D);
|
||||
|
||||
|
||||
this.gainMultiplier = volume;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
audio.destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return audio resource
|
||||
*/
|
||||
@@ -54,8 +54,8 @@ public abstract class AudioPlayer implements Destroyable {
|
||||
{
|
||||
return audio;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get play gain, computed based on volume and given multiplier
|
||||
*
|
||||
@@ -66,8 +66,8 @@ public abstract class AudioPlayer implements Destroyable {
|
||||
{
|
||||
return baseGain * gainMultiplier.get() * multiplier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get pitch
|
||||
*
|
||||
@@ -78,8 +78,8 @@ public abstract class AudioPlayer implements Destroyable {
|
||||
{
|
||||
return basePitch * multiplier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get if audio is valid
|
||||
*
|
||||
@@ -89,27 +89,27 @@ public abstract class AudioPlayer implements Destroyable {
|
||||
{
|
||||
return (audio != null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set base gain. 1 is original volume, 0 is silence.
|
||||
*
|
||||
* @param baseGain base gain
|
||||
* @param gain base gain
|
||||
*/
|
||||
public void setGain(double baseGain)
|
||||
public void setGain(double gain)
|
||||
{
|
||||
this.baseGain = baseGain;
|
||||
this.baseGain = gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set base pitch. 1 is original pitch, less is deeper, more is higher.
|
||||
*
|
||||
* @param basePitch base pitch
|
||||
* @param pitch base pitch
|
||||
*/
|
||||
public void setPitch(double basePitch)
|
||||
public void setPitch(double pitch)
|
||||
{
|
||||
this.basePitch = basePitch;
|
||||
this.basePitch = pitch;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,27 +9,27 @@ import mightypork.utils.math.animation.NumAnimated;
|
||||
|
||||
|
||||
/**
|
||||
* Audio loop player (with fading, good for music)
|
||||
* Audio loop player (with fading, for music)
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
|
||||
|
||||
/** animator for fade in and fade out */
|
||||
private final NumAnimated fadeAnim = new NumAnimated(0);
|
||||
|
||||
|
||||
private double lastUpdateGain = 0;
|
||||
|
||||
|
||||
/** flag that track is paused */
|
||||
private boolean paused = true;
|
||||
|
||||
|
||||
/** Default fadeIn time */
|
||||
private double inTime = 1;
|
||||
|
||||
|
||||
/** Default fadeOut time */
|
||||
private double outTime = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param track audio resource
|
||||
* @param volume volume control
|
||||
@@ -37,11 +37,11 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
public LoopPlayer(DeferredAudio track, Volume volume)
|
||||
{
|
||||
super(track, volume);
|
||||
|
||||
|
||||
paused = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set fading duration (seconds)
|
||||
*
|
||||
@@ -53,8 +53,8 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
inTime = in;
|
||||
outTime = out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void initLoop()
|
||||
{
|
||||
if (hasAudio() && !getAudio().isActive()) {
|
||||
@@ -62,27 +62,27 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
getAudio().pauseLoop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
if (!hasAudio() || paused) return;
|
||||
|
||||
|
||||
initLoop();
|
||||
|
||||
|
||||
getAudio().pauseLoop();
|
||||
paused = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
return paused;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Alias to resume (more meaningful name)
|
||||
*/
|
||||
@@ -90,40 +90,40 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
{
|
||||
resume();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
if (!hasAudio() || !paused) return;
|
||||
|
||||
|
||||
initLoop();
|
||||
|
||||
|
||||
paused = false;
|
||||
|
||||
|
||||
getAudio().adjustGain(computeGain(fadeAnim.value()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
if (!hasAudio() || paused) return;
|
||||
|
||||
|
||||
initLoop();
|
||||
|
||||
|
||||
fadeAnim.update(delta);
|
||||
|
||||
|
||||
final double gain = computeGain(fadeAnim.value());
|
||||
if (!paused && gain != lastUpdateGain) {
|
||||
getAudio().adjustGain(gain);
|
||||
lastUpdateGain = gain;
|
||||
}
|
||||
|
||||
|
||||
if (gain == 0 && !paused) pause(); // pause on zero volume
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resume if paused, and fade in (pick up from current volume).
|
||||
*
|
||||
@@ -132,13 +132,13 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
public void fadeIn(double fadeTime)
|
||||
{
|
||||
if (!hasAudio()) return;
|
||||
|
||||
|
||||
if (isPaused()) fadeAnim.setTo(0);
|
||||
resume();
|
||||
fadeAnim.fadeIn(fadeTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fade out and pause when reached zero volume
|
||||
*
|
||||
@@ -150,8 +150,8 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
if (isPaused()) return;
|
||||
fadeAnim.fadeOut(fadeTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fade in with default duration
|
||||
*/
|
||||
@@ -159,8 +159,8 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
{
|
||||
fadeIn(inTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fade out with default duration
|
||||
*/
|
||||
@@ -168,5 +168,5 @@ public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
{
|
||||
fadeOut(outTime);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import java.util.List;
|
||||
import mightypork.gamecore.audio.AudioModule;
|
||||
import mightypork.gamecore.core.config.Config;
|
||||
import mightypork.gamecore.core.events.ShutdownEvent;
|
||||
import mightypork.gamecore.core.init.InitTask;
|
||||
import mightypork.gamecore.core.plugins.AppPlugin;
|
||||
import mightypork.gamecore.graphics.GraphicsModule;
|
||||
import mightypork.gamecore.input.InputModule;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
@@ -23,19 +25,19 @@ import mightypork.utils.logging.Log;
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class App extends BusNode {
|
||||
|
||||
|
||||
private static App instance;
|
||||
|
||||
|
||||
private final AppBackend backend;
|
||||
private final EventBus eventBus = new EventBus();
|
||||
private boolean started = false;
|
||||
|
||||
|
||||
/** List of installed App plugins */
|
||||
protected final DelegatingList plugins = new DelegatingList();
|
||||
/** List of initializers */
|
||||
protected final List<InitTask> initializers = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create an app with given backend.
|
||||
*
|
||||
@@ -46,24 +48,24 @@ public class App extends BusNode {
|
||||
if (App.instance != null) {
|
||||
throw new IllegalStateException("App already initialized");
|
||||
}
|
||||
|
||||
|
||||
// store current instance in static field
|
||||
App.instance = this;
|
||||
|
||||
|
||||
// join the bus
|
||||
this.eventBus.subscribe(this);
|
||||
|
||||
|
||||
// create plugin registry attached to bus
|
||||
this.eventBus.subscribe(this.plugins);
|
||||
|
||||
|
||||
// initialize and use backend
|
||||
this.backend = backend;
|
||||
this.backend.bind(this);
|
||||
this.eventBus.subscribe(backend);
|
||||
this.backend.initialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a plugin to the app. Plugins can eg. listen to bus events and react
|
||||
* to them.
|
||||
@@ -75,14 +77,14 @@ public class App extends BusNode {
|
||||
if (started) {
|
||||
throw new IllegalStateException("App already started, cannot add plugins.");
|
||||
}
|
||||
|
||||
|
||||
// attach to event bus
|
||||
plugins.add(plugin);
|
||||
plugin.bind(this);
|
||||
plugin.initialize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add an initializer to the app.
|
||||
*
|
||||
@@ -93,11 +95,11 @@ public class App extends BusNode {
|
||||
if (started) {
|
||||
throw new IllegalStateException("App already started, cannot add initializers.");
|
||||
}
|
||||
|
||||
|
||||
initializers.add(initializer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get current backend
|
||||
*
|
||||
@@ -107,8 +109,8 @@ public class App extends BusNode {
|
||||
{
|
||||
return backend;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the App and start operating.<br>
|
||||
* This method should be called after adding all required initializers and
|
||||
@@ -120,41 +122,41 @@ public class App extends BusNode {
|
||||
throw new IllegalStateException("Already started.");
|
||||
}
|
||||
started = true;
|
||||
|
||||
|
||||
// pre-init hook, just in case anyone wanted to have one.
|
||||
Log.f2("Calling pre-init hook...");
|
||||
preInit();
|
||||
|
||||
|
||||
Log.i("=== Starting initialization sequence ===");
|
||||
|
||||
|
||||
// sort initializers by order.
|
||||
final List<InitTask> orderedInitializers = InitTask.inOrder(initializers);
|
||||
|
||||
|
||||
for (final InitTask initTask : orderedInitializers) {
|
||||
Log.f1("Running init task \"" + initTask.getName() + "\"...");
|
||||
|
||||
|
||||
initTask.bind(this);
|
||||
|
||||
|
||||
// set the task options
|
||||
initTask.init();
|
||||
|
||||
|
||||
initTask.before();
|
||||
|
||||
|
||||
// main task action
|
||||
initTask.run();
|
||||
|
||||
|
||||
// after hook for extra actions immeditaely after the task completes
|
||||
initTask.after();
|
||||
}
|
||||
|
||||
|
||||
Log.i("=== Initialization sequence completed ===");
|
||||
|
||||
|
||||
// user can now start the main loop etc.
|
||||
Log.f2("Calling post-init hook...");
|
||||
postInit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hook called before the initialization sequence starts.
|
||||
*/
|
||||
@@ -162,8 +164,8 @@ public class App extends BusNode {
|
||||
protected void preInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hook called after the initialization sequence is finished.
|
||||
*/
|
||||
@@ -171,8 +173,8 @@ public class App extends BusNode {
|
||||
protected void postInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Shut down the running instance.<br>
|
||||
* Deinitialize backend modules and terminate the JVM.
|
||||
@@ -181,9 +183,9 @@ public class App extends BusNode {
|
||||
{
|
||||
if (instance != null) {
|
||||
Log.i("Dispatching Shutdown event...");
|
||||
|
||||
|
||||
bus().send(new ShutdownEvent(new Runnable() {
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@@ -196,19 +198,19 @@ public class App extends BusNode {
|
||||
} catch (final Throwable e) {
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
|
||||
Log.i("Shutdown completed.");
|
||||
System.exit(0);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
} else {
|
||||
Log.w("App is not running.");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the currently running App instance.
|
||||
*
|
||||
@@ -218,8 +220,8 @@ public class App extends BusNode {
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get graphics module from the running app's backend
|
||||
*
|
||||
@@ -229,19 +231,19 @@ public class App extends BusNode {
|
||||
{
|
||||
return instance.backend.getGraphics();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get audio module from the running app's backend
|
||||
*
|
||||
* @return audio module
|
||||
*/
|
||||
public static AudioModule audio()
|
||||
public static AudioModule sound()
|
||||
{
|
||||
return instance.backend.getAudio();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get input module from the running app's backend
|
||||
*
|
||||
@@ -251,8 +253,8 @@ public class App extends BusNode {
|
||||
{
|
||||
return instance.backend.getInput();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get event bus instance.
|
||||
*
|
||||
@@ -262,8 +264,8 @@ public class App extends BusNode {
|
||||
{
|
||||
return instance.eventBus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the main config, if initialized.
|
||||
*
|
||||
@@ -274,8 +276,8 @@ public class App extends BusNode {
|
||||
{
|
||||
return cfg("main");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a config by alias.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.gamecore.core.config;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.gamecore.core.init.InitTask;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
|
||||
|
||||
|
||||
+36
-35
@@ -1,4 +1,4 @@
|
||||
package mightypork.gamecore.core;
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -7,6 +7,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.utils.Reflect;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.logging.Log;
|
||||
@@ -20,22 +21,22 @@ import mightypork.utils.logging.Log;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class InitTask {
|
||||
|
||||
|
||||
/** App instance assigned using <code>bind()</code> */
|
||||
protected App app;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assign the initialized app instance to an "app" field.
|
||||
*
|
||||
* @param app app
|
||||
*/
|
||||
final void bind(App app)
|
||||
public final void bind(App app)
|
||||
{
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An init method that is called before the <code>run()</code> method.<br>
|
||||
* This method should be left unimplemented in the task, and can be used to
|
||||
@@ -46,8 +47,8 @@ public abstract class InitTask {
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hook for extra action before the main task action.<br>
|
||||
* Can be overridden during app configuration to "bake-in" extra actions.
|
||||
@@ -57,14 +58,14 @@ public abstract class InitTask {
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Run the initializer on app.
|
||||
*/
|
||||
public abstract void run();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hook executed after the "run()" method.<br>
|
||||
* Can be overridden during app configuration to "bake-in" extra actions.
|
||||
@@ -74,8 +75,8 @@ public abstract class InitTask {
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get name of this initializer (for dependency resolver).<br>
|
||||
* The name should be short, snake_case and precise.
|
||||
@@ -83,8 +84,8 @@ public abstract class InitTask {
|
||||
* @return name
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get what other initializers must be already loaded before this can load.<br>
|
||||
* Depending on itself or creating a circular dependency will cause error.<br>
|
||||
@@ -98,8 +99,8 @@ public abstract class InitTask {
|
||||
{
|
||||
return new String[] {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Order init tasks so that all dependencies are loaded before thye are
|
||||
* needed by the tasks.
|
||||
@@ -110,25 +111,25 @@ public abstract class InitTask {
|
||||
public static List<InitTask> inOrder(List<InitTask> tasks)
|
||||
{
|
||||
final List<InitTask> remaining = new ArrayList<>(tasks);
|
||||
|
||||
|
||||
final List<InitTask> ordered = new ArrayList<>();
|
||||
final Set<String> loaded = new HashSet<>();
|
||||
|
||||
|
||||
// resolve task order
|
||||
int addedThisIteration = 0;
|
||||
do {
|
||||
for (final Iterator<InitTask> i = remaining.iterator(); i.hasNext();) {
|
||||
final InitTask task = i.next();
|
||||
|
||||
|
||||
String[] deps = task.getDependencies();
|
||||
if (deps == null) deps = new String[] {};
|
||||
|
||||
|
||||
int unmetDepsCount = deps.length;
|
||||
|
||||
|
||||
for (final String d : deps) {
|
||||
if (loaded.contains(d)) unmetDepsCount--;
|
||||
}
|
||||
|
||||
|
||||
if (unmetDepsCount == 0) {
|
||||
ordered.add(task);
|
||||
loaded.add(task.getName());
|
||||
@@ -137,38 +138,38 @@ public abstract class InitTask {
|
||||
}
|
||||
}
|
||||
} while (addedThisIteration > 0);
|
||||
|
||||
|
||||
// check if any tasks are left out
|
||||
if (remaining.size() > 0) {
|
||||
|
||||
|
||||
// build error message for each bad task
|
||||
int badInitializers = 0;
|
||||
for (final InitTask task : remaining) {
|
||||
if (Reflect.hasAnnotation(task.getClass(), OptionalInitTask.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
badInitializers++;
|
||||
|
||||
|
||||
String notSatisfied = "";
|
||||
|
||||
|
||||
for (final String d : task.getDependencies()) {
|
||||
if (!loaded.contains(d)) {
|
||||
|
||||
|
||||
if (!notSatisfied.isEmpty()) {
|
||||
notSatisfied += ", ";
|
||||
}
|
||||
|
||||
|
||||
notSatisfied += d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Log.w("InitTask \"" + task.getName() + "\" - missing dependencies: " + notSatisfied);
|
||||
}
|
||||
|
||||
|
||||
if (badInitializers > 0) throw new RuntimeException("Some InitTask dependencies could not be satisfied.");
|
||||
}
|
||||
|
||||
|
||||
return ordered;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ package mightypork.gamecore.core.init;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.gamecore.graphics.GraphicsModule;
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package mightypork.gamecore.core.init;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.utils.ion.Ion;
|
||||
import mightypork.utils.ion.IonInput;
|
||||
import mightypork.utils.ion.IonOutput;
|
||||
|
||||
@@ -4,7 +4,6 @@ package mightypork.gamecore.core.init;
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.utils.files.WorkDir;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.writers.LogWriter;
|
||||
|
||||
@@ -3,8 +3,6 @@ package mightypork.gamecore.core.init;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.gamecore.core.OptionalInitTask;
|
||||
import mightypork.utils.files.WorkDir;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.loading.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Task to add a resource loader.<br>
|
||||
* By default the async resource loader is used
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class InitTaskResourceLoader extends InitTask {
|
||||
|
||||
/** The loader. */
|
||||
protected ResourceLoader loader;
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
loader = getLoaderImpl();
|
||||
if (loader != null) loader.init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a loader impl
|
||||
*
|
||||
* @return loader
|
||||
*/
|
||||
protected abstract ResourceLoader getLoaderImpl();
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "resource_loader";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.loading.AsyncResourceLoader;
|
||||
import mightypork.gamecore.resources.loading.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Task to add a resource loader.<br>
|
||||
* By default the async resource loader is used
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskResourceLoaderAsync extends InitTaskResourceLoader {
|
||||
|
||||
/**
|
||||
* Create a loader impl
|
||||
*
|
||||
* @return loader
|
||||
*/
|
||||
@Override
|
||||
protected ResourceLoader getLoaderImpl()
|
||||
{
|
||||
final AsyncResourceLoader loader = new AsyncResourceLoader();
|
||||
|
||||
// could now configure the loader
|
||||
|
||||
return loader;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.loading.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Task to add a resource loader.<br>
|
||||
* By default the async resource loader is used
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskResourceLoaderNone extends InitTaskResourceLoader {
|
||||
|
||||
|
||||
@Override
|
||||
protected ResourceLoader getLoaderImpl()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.ResourceInitializer;
|
||||
|
||||
|
||||
/**
|
||||
* Task to initialize resources
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class InitTaskResources extends InitTask implements ResourceInitializer {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Res.load(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "resources";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String[] getDependencies()
|
||||
{
|
||||
return new String[] { "resource_loader" };
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import java.util.Map.Entry;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.files.InstanceLock;
|
||||
import mightypork.utils.files.WorkDir;
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package mightypork.gamecore.core;
|
||||
package mightypork.gamecore.core.init;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -20,5 +20,5 @@ import java.lang.annotation.Target;
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface OptionalInitTask {
|
||||
|
||||
//
|
||||
}
|
||||
+8
-7
@@ -1,6 +1,7 @@
|
||||
package mightypork.gamecore.core;
|
||||
package mightypork.gamecore.core.plugins;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
|
||||
@@ -13,22 +14,22 @@ import mightypork.utils.eventbus.clients.BusNode;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class AppPlugin extends BusNode {
|
||||
|
||||
|
||||
/** App instance assigned using <code>bind()</code> */
|
||||
protected App app;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Assign the initialized app instance to an "app" field.
|
||||
*
|
||||
* @param app app
|
||||
*/
|
||||
void bind(App app)
|
||||
public void bind(App app)
|
||||
{
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the plugin for the given App.<br>
|
||||
* The plugin is already attached to the event bus.
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.gamecore.core.plugins.screenshot;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.InitTask;
|
||||
import mightypork.gamecore.core.init.InitTask;
|
||||
import mightypork.utils.files.WorkDir;
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ package mightypork.gamecore.core.plugins.screenshot;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.App;
|
||||
import mightypork.gamecore.core.AppPlugin;
|
||||
import mightypork.gamecore.core.events.MainLoopRequest;
|
||||
import mightypork.gamecore.core.plugins.AppPlugin;
|
||||
import mightypork.utils.Support;
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@ import mightypork.utils.Support;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class ScreenshotPlugin extends AppPlugin {
|
||||
|
||||
|
||||
/**
|
||||
* Take screenshot. Called by the trigger event.
|
||||
*/
|
||||
void takeScreenshot()
|
||||
{
|
||||
App.bus().send(new MainLoopRequest(new Runnable() {
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
||||
@@ -12,36 +12,6 @@ import mightypork.gamecore.resources.BaseDeferredResource;
|
||||
*/
|
||||
public abstract class DeferredFont extends BaseDeferredResource implements IFont {
|
||||
|
||||
/**
|
||||
* Font style enum
|
||||
*/
|
||||
public static enum FontStyle
|
||||
{
|
||||
/** Plan style */
|
||||
PLAIN(0),
|
||||
/** Bold style */
|
||||
BOLD(1),
|
||||
/** Italic style */
|
||||
ITALIC(2),
|
||||
/** Bond and italic together */
|
||||
BOLD_ITALIC(1 + 2);
|
||||
|
||||
/** Number associated with the style */
|
||||
public int numval;
|
||||
|
||||
|
||||
/**
|
||||
* Font style
|
||||
*
|
||||
* @param style style index as in awt Font. Not using constants to be
|
||||
* independent on awt.
|
||||
*/
|
||||
private FontStyle(int style)
|
||||
{
|
||||
this.numval = style;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requested font size. For bitmap fonts, this should match the actual font
|
||||
* size (in pixels). The font can be scaled after loaded, but it may be
|
||||
|
||||
@@ -14,11 +14,11 @@ import mightypork.utils.eventbus.clients.BusNode;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class FontRegistry extends BusNode {
|
||||
|
||||
|
||||
private final HashMap<String, IFont> fonts = new HashMap<>();
|
||||
private final HashMap<String, String> aliases = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load a {@link DeferredFont}
|
||||
*
|
||||
@@ -28,11 +28,11 @@ public class FontRegistry extends BusNode {
|
||||
public void addFont(String key, DeferredFont font)
|
||||
{
|
||||
App.bus().send(new ResourceLoadRequest(font));
|
||||
|
||||
|
||||
fonts.put(key, font);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a {@link IFont} to the bank.
|
||||
*
|
||||
@@ -43,10 +43,13 @@ public class FontRegistry extends BusNode {
|
||||
{
|
||||
fonts.put(key, font);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a font alias.
|
||||
* Add a font alias. Useful to specify fonts to use for various parts of the
|
||||
* app, without having to change the aliases throughout the app whenever the
|
||||
* font alias is changed.<br>
|
||||
* It is, however, NOT possible to make alias to alias.
|
||||
*
|
||||
* @param alias_key alias key
|
||||
* @param font_key font key
|
||||
@@ -55,8 +58,8 @@ public class FontRegistry extends BusNode {
|
||||
{
|
||||
aliases.put(alias_key, font_key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a loaded {@link IFont}
|
||||
*
|
||||
@@ -66,14 +69,14 @@ public class FontRegistry extends BusNode {
|
||||
public IFont getFont(String key)
|
||||
{
|
||||
IFont f = fonts.get(key);
|
||||
|
||||
|
||||
if (f == null) f = fonts.get(aliases.get(key));
|
||||
|
||||
|
||||
if (f == null) {
|
||||
throw new RuntimeException("There's no font called " + key + "!");
|
||||
}
|
||||
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package mightypork.gamecore.graphics.fonts;
|
||||
|
||||
/**
|
||||
* Font style enum
|
||||
*/
|
||||
public enum FontStyle
|
||||
{
|
||||
/** Plan style */
|
||||
PLAIN(0),
|
||||
/** Bold style */
|
||||
BOLD(1),
|
||||
/** Italic style */
|
||||
ITALIC(2),
|
||||
/** Bond and italic together */
|
||||
BOLD_ITALIC(1 + 2);
|
||||
|
||||
/** Number associated with the style */
|
||||
public int numval;
|
||||
|
||||
|
||||
/**
|
||||
* Font style
|
||||
*
|
||||
* @param style style index as in awt Font. Not using constants to be
|
||||
* independent on awt.
|
||||
*/
|
||||
private FontStyle(int style)
|
||||
{
|
||||
this.numval = style;
|
||||
}
|
||||
}
|
||||
@@ -20,20 +20,25 @@ public class TextureRegistry {
|
||||
|
||||
private final Map<String, ITexture> textures = new HashMap<>();
|
||||
private final Map<String, TxSheet> sheets = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load a texture from resource, without a key. This texture will not be
|
||||
* added to the bank.
|
||||
* Load a texture from resource.
|
||||
*
|
||||
* @param resourcePath resource path of the texture
|
||||
* @param filter filtering mode
|
||||
* @param wrap wrapping mode
|
||||
* @return texture reference
|
||||
*/
|
||||
public ITexture addTexture(String resourcePath, FilterMode filter, WrapMode wrap)
|
||||
public ITexture loadTexture(String resourcePath, FilterMode filter, WrapMode wrap)
|
||||
{
|
||||
return addTexture(resourcePath, resourcePath, filter, wrap);
|
||||
final DeferredTexture texture = App.gfx().createTextureResource(resourcePath);
|
||||
texture.setFilter(filter);
|
||||
texture.setWrap(wrap);
|
||||
|
||||
App.bus().send(new ResourceLoadRequest(texture));
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +56,7 @@ public class TextureRegistry {
|
||||
{
|
||||
if (key != null) if (textures.containsKey(key)) throw new KeyAlreadyExistsException();
|
||||
|
||||
final DeferredTexture texture = App.gfx().createTextureResource(resourcePath);
|
||||
texture.setFilter(filter);
|
||||
texture.setWrap(wrap);
|
||||
|
||||
App.bus().send(new ResourceLoadRequest(texture));
|
||||
final ITexture texture = loadTexture(resourcePath, filter, wrap);
|
||||
|
||||
if (key != null) {
|
||||
textures.put(key, texture);
|
||||
|
||||
@@ -76,7 +76,7 @@ public class CrossfadeOverlay extends Overlay {
|
||||
|
||||
if (screen == null) {
|
||||
// going for halt
|
||||
App.audio().fadeOutAllLoops();
|
||||
App.sound().fadeOutAllLoops();
|
||||
}
|
||||
|
||||
if (fromDark) {
|
||||
|
||||
@@ -18,83 +18,127 @@ import mightypork.gamecore.graphics.textures.TxSheet;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public final class Res {
|
||||
|
||||
private static TextureRegistry textures;
|
||||
private static SoundRegistry sounds;
|
||||
private static FontRegistry fonts;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
|
||||
|
||||
private static TextureRegistry textures = new TextureRegistry();
|
||||
private static SoundRegistry sounds = new SoundRegistry();
|
||||
private static FontRegistry fonts = new FontRegistry();
|
||||
|
||||
|
||||
/**
|
||||
* Load on behalf of given base app
|
||||
* Get a texture by key
|
||||
*
|
||||
* @param app app access
|
||||
* @param key the key
|
||||
* @return texture
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
textures = new TextureRegistry();
|
||||
sounds = new SoundRegistry();
|
||||
fonts = new FontRegistry();
|
||||
}
|
||||
|
||||
|
||||
public static ITexture getTexture(String key)
|
||||
public static ITexture texture(String key)
|
||||
{
|
||||
return textures.getTexture(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a texture sheet by key
|
||||
*
|
||||
* @param key
|
||||
* @param key the key
|
||||
* @return sheet
|
||||
*/
|
||||
public static TxSheet getTxSheet(String key)
|
||||
public static TxSheet txSheet(String key)
|
||||
{
|
||||
return textures.getSheet(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a texture quad by key
|
||||
*
|
||||
* @param key
|
||||
* @param key the key
|
||||
* @return quad
|
||||
*/
|
||||
public static TxQuad getTxQuad(String key)
|
||||
public static TxQuad txQuad(String key)
|
||||
{
|
||||
return textures.getQuad(key);
|
||||
}
|
||||
|
||||
|
||||
public static LoopPlayer getSoundLoop(String key)
|
||||
|
||||
|
||||
/**
|
||||
* Get a sound loop player by key
|
||||
*
|
||||
* @param key the key
|
||||
* @return loop player
|
||||
*/
|
||||
public static LoopPlayer loop(String key)
|
||||
{
|
||||
return sounds.getLoop(key);
|
||||
}
|
||||
|
||||
|
||||
public static EffectPlayer getSoundEffect(String key)
|
||||
|
||||
|
||||
/**
|
||||
* Get a sound effect player by key
|
||||
*
|
||||
* @param key the key
|
||||
* @return effect player
|
||||
*/
|
||||
public static EffectPlayer sound(String key)
|
||||
{
|
||||
return sounds.getEffect(key);
|
||||
}
|
||||
|
||||
|
||||
public static IFont getFont(String key)
|
||||
/**
|
||||
* Get a font by key
|
||||
*
|
||||
* @param key the key
|
||||
* @return font
|
||||
*/
|
||||
public static IFont font(String key)
|
||||
{
|
||||
return fonts.getFont(key);
|
||||
}
|
||||
|
||||
|
||||
public static void load(ResourceSetup binder)
|
||||
|
||||
|
||||
/**
|
||||
* Get internal texture registry
|
||||
*
|
||||
* @return registry
|
||||
*/
|
||||
public static TextureRegistry getTextureRegistry()
|
||||
{
|
||||
binder.addFonts(fonts);
|
||||
binder.addTextures(textures);
|
||||
binder.addSounds(sounds);
|
||||
return textures;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get internal font registry
|
||||
*
|
||||
* @return registry
|
||||
*/
|
||||
public static FontRegistry getFontRegistry()
|
||||
{
|
||||
return fonts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get internal sound registry
|
||||
*
|
||||
* @return registry
|
||||
*/
|
||||
public static SoundRegistry getSoundRegistry()
|
||||
{
|
||||
return sounds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load resources by a resource initializer.
|
||||
*
|
||||
* @param initializer the resource initializer
|
||||
*/
|
||||
public static void load(ResourceInitializer initializer)
|
||||
{
|
||||
initializer.addFonts(fonts);
|
||||
initializer.addTextures(textures);
|
||||
initializer.addSounds(sounds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import mightypork.gamecore.graphics.textures.TextureRegistry;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface ResourceSetup {
|
||||
public interface ResourceInitializer {
|
||||
|
||||
/**
|
||||
* Add fonts to load.
|
||||
@@ -20,50 +20,60 @@ import mightypork.utils.logging.Log;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class AsyncResourceLoader extends Thread implements ResourceLoader, Destroyable {
|
||||
|
||||
|
||||
private final ExecutorService exs = Executors.newFixedThreadPool(2);
|
||||
|
||||
|
||||
private final LinkedBlockingQueue<DeferredResource> toLoad = new LinkedBlockingQueue<>();
|
||||
private volatile boolean stopped;
|
||||
private volatile boolean mainLoopQueuing = true;
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void init()
|
||||
{
|
||||
App.bus().subscribe(this); // FIXME bad
|
||||
setDaemon(true);
|
||||
super.start();
|
||||
}
|
||||
|
||||
|
||||
public void enableMainLoopQueuing(boolean yes)
|
||||
{
|
||||
mainLoopQueuing = yes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a resource loader.
|
||||
*/
|
||||
public AsyncResourceLoader()
|
||||
{
|
||||
super("Deferred loader");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void init()
|
||||
{
|
||||
App.bus().subscribe(this);
|
||||
setDaemon(true);
|
||||
super.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* True to queue resources that must load in rendering context to main loop.
|
||||
* May cause lag at the beginning, but results in smoother performance later
|
||||
* (better than load-on-demand)
|
||||
*
|
||||
* @param yes true to allow queuing
|
||||
*/
|
||||
public void enableMainLoopQueuing(boolean yes)
|
||||
{
|
||||
mainLoopQueuing = yes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadResource(final DeferredResource resource)
|
||||
{
|
||||
if (resource.isLoaded()) return;
|
||||
|
||||
|
||||
// textures & fonts needs to be loaded in main thread
|
||||
if (Reflect.hasAnnotation(resource, MustLoadInRenderingContext.class)) {
|
||||
|
||||
|
||||
if (!mainLoopQueuing) {
|
||||
// just let it be
|
||||
} else {
|
||||
Log.f3("(loader) Delegating to main thread: " + Support.str(resource));
|
||||
|
||||
|
||||
App.bus().send(new MainLoopRequest(new Runnable() {
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@@ -71,31 +81,31 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
}
|
||||
}, false));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
toLoad.add(resource);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Log.f3("Asynchronous resource loader started.");
|
||||
|
||||
|
||||
while (!stopped) {
|
||||
|
||||
|
||||
try {
|
||||
final DeferredResource def = toLoad.take();
|
||||
if (def == null) continue;
|
||||
|
||||
|
||||
if (!def.isLoaded()) {
|
||||
|
||||
|
||||
Log.f3("(loader) Scheduling... " + Support.str(def));
|
||||
|
||||
|
||||
exs.submit(new Runnable() {
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
@@ -105,15 +115,15 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} catch (final InterruptedException ignored) {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// apparently, destroy method exists on thread :/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
@@ -123,5 +133,5 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
stopped = true;
|
||||
exs.shutdownNow();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,17 +10,17 @@ import mightypork.gamecore.resources.DeferredResource;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface ResourceLoader {
|
||||
|
||||
|
||||
/**
|
||||
* Load a resource
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
void loadResource(DeferredResource resource);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the loader (Join the bus, start a stread etc)
|
||||
* Initialize the loader (Join the bus, start a thread etc)
|
||||
*
|
||||
* @param app app the loader works for. The event bus must already be
|
||||
* initialized.
|
||||
|
||||
Reference in New Issue
Block a user