From 8e9a6580987f39025b699236762368e30463f247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 29 Jul 2014 14:12:59 +0200 Subject: [PATCH] improved initializer resolver --- .../gamecore/audio/AudioModule.java | 74 +++--- .../gamecore/audio/DeferredAudio.java | 14 +- src/mightypork/gamecore/audio/IAudio.java | 44 ++-- .../gamecore/audio/JointVolume.java | 16 +- .../gamecore/audio/SoundRegistry.java | 42 ++-- src/mightypork/gamecore/audio/Volume.java | 8 +- .../gamecore/audio/players/AudioPlayer.java | 46 ++-- .../gamecore/audio/players/EffectPlayer.java | 24 +- .../gamecore/audio/players/LoopPlayer.java | 82 +++--- src/mightypork/gamecore/core/App.java | 236 +++++++++++------- src/mightypork/gamecore/core/AppBackend.java | 36 ++- .../gamecore/core/BackendModule.java | 6 +- ...{DeltaMainLoop.java => BasicMainLoop.java} | 57 +++-- src/mightypork/gamecore/core/MainLoop.java | 16 +- .../gamecore/core/config/Config.java | 100 ++++---- .../core/config/KeyStrokeProperty.java | 18 +- .../gamecore/core/events/MainLoopRequest.java | 14 +- ...hutdownEvent.java => ShutdownRequest.java} | 21 +- ...ener.java => ShutdownRequestListener.java} | 8 +- .../gamecore/core/init/InitSequence.java | 168 +++++++++++++ .../gamecore/core/init/InitTask.java | 121 +++------ .../gamecore/core/init/InitTaskBackend.java | 41 +++ .../core/{config => init}/InitTaskConfig.java | 11 +- .../core/init/InitTaskCrashHandler.java | 17 +- .../gamecore/core/init/InitTaskCustom.java | 24 +- .../gamecore/core/init/InitTaskDisplay.java | 2 +- .../core/init/InitTaskIonizables.java | 37 +-- .../gamecore/core/init/InitTaskLog.java | 50 ++-- .../gamecore/core/init/InitTaskLogHeader.java | 7 + .../gamecore/core/init/InitTaskMainLoop.java | 38 ++- .../core/init/InitTaskResourceLoader.java | 1 + .../init/InitTaskResourceLoaderAsync.java | 11 +- .../core/init/InitTaskResourceLoaderNone.java | 8 +- .../gamecore/core/init/InitTaskResources.java | 14 +- .../gamecore/core/init/InitTaskScreens.java | 42 ---- .../gamecore/core/init/InitTaskUI.java | 51 ++++ .../gamecore/core/init/InitTaskWorkdir.java | 7 + .../gamecore/core/plugins/AppPlugin.java | 10 +- .../screenshot/InitTaskPluginScreenshot.java | 32 +-- .../plugins/screenshot/ScreenshotPlugin.java | 4 +- .../plugins/screenshot/ScreenshotRequest.java | 4 +- .../screenshot/ScreenshotRequestListener.java | 2 +- .../screenshot/TaskTakeScreenshot.java | 32 +-- .../graphics/FullscreenToggleRequest.java | 2 +- .../gamecore/graphics/GraphicsModule.java | 204 +++++++-------- .../gamecore/graphics/Renderable.java | 4 +- .../gamecore/graphics/Screenshot.java | 2 +- .../gamecore/graphics/fonts/DeferredFont.java | 52 ++-- .../gamecore/graphics/fonts/FontRegistry.java | 28 +-- .../gamecore/graphics/fonts/FontRenderer.java | 82 +++--- .../gamecore/graphics/fonts/FontStyle.java | 6 +- .../gamecore/graphics/fonts/Glyphs.java | 22 +- .../gamecore/graphics/fonts/IFont.java | 30 +-- .../graphics/textures/DeferredTexture.java | 22 +- .../gamecore/graphics/textures/ITexture.java | 26 +- .../gamecore/graphics/textures/QuadGrid.java | 28 +-- .../graphics/textures/TextureRegistry.java | 54 ++-- .../gamecore/graphics/textures/TxQuad.java | 54 ++-- .../gamecore/graphics/textures/TxSheet.java | 44 ++-- src/mightypork/gamecore/gui/Action.java | 20 +- src/mightypork/gamecore/gui/ActionGroup.java | 22 +- src/mightypork/gamecore/gui/HasAction.java | 2 +- .../gui/components/BaseComponent.java | 82 +++--- .../gamecore/gui/components/Component.java | 38 +-- .../gui/components/DynamicWidthComponent.java | 2 +- .../gui/components/InputComponent.java | 2 +- .../gui/components/LayoutComponent.java | 56 ++--- .../gui/components/LinearComponent.java | 36 +-- .../gui/components/PluggableRenderable.java | 12 +- .../components/input/ClickableComponent.java | 22 +- .../components/input/ClickableWrapper.java | 30 +-- .../gui/components/input/TextButton.java | 32 +-- .../gui/components/layout/ColumnLayout.java | 24 +- .../components/layout/ConstraintLayout.java | 12 +- .../components/layout/FlowColumnLayout.java | 30 +-- .../gui/components/layout/FlowRowLayout.java | 28 +-- .../gui/components/layout/GridLayout.java | 28 +-- .../gui/components/layout/NullComponent.java | 2 +- .../gui/components/layout/RowLayout.java | 24 +- .../layout/linear/AbstractLinearWrapper.java | 28 +-- .../components/layout/linear/LinearGap.java | 6 +- .../layout/linear/LinearLayout.java | 34 +-- .../layout/linear/LinearRectangle.java | 16 +- .../layout/linear/LinearSquare.java | 8 +- .../layout/linear/LinearWrapper.java | 8 +- .../gui/components/painters/ImagePainter.java | 18 +- .../gui/components/painters/QuadPainter.java | 20 +- .../gui/components/painters/TextPainter.java | 90 +++---- .../gui/events/LayoutChangeEvent.java | 2 +- .../gui/events/LayoutChangeListener.java | 2 +- .../gamecore/gui/events/ScreenRequest.java | 12 +- .../gui/events/ScreenRequestListener.java | 2 +- .../gui/events/ViewportChangeEvent.java | 14 +- .../gui/events/ViewportChangeListener.java | 2 +- .../gamecore/gui/screens/LayeredScreen.java | 48 ++-- .../gamecore/gui/screens/Overlay.java | 98 ++++---- .../gamecore/gui/screens/Screen.java | 76 +++--- .../gamecore/gui/screens/ScreenLayer.java | 18 +- .../gamecore/gui/screens/ScreenRegistry.java | 40 +-- .../gui/screens/impl/CrossfadeOverlay.java | 32 +-- .../gui/screens/impl/CrossfadeRequest.java | 16 +- .../gui/screens/impl/FadingLayer.java | 58 ++--- .../gamecore/gui/screens/impl/LayerColor.java | 14 +- .../gamecore/input/InputModule.java | 44 ++-- src/mightypork/gamecore/input/Key.java | 40 +-- src/mightypork/gamecore/input/KeyBinder.java | 8 +- src/mightypork/gamecore/input/KeyBinding.java | 22 +- .../gamecore/input/KeyBindingPool.java | 18 +- src/mightypork/gamecore/input/KeyStroke.java | 64 ++--- src/mightypork/gamecore/input/Keys.java | 128 +++++----- .../gamecore/input/events/KeyEvent.java | 32 +-- .../input/events/KeyEventHandler.java | 2 +- .../input/events/MouseButtonEvent.java | 44 ++-- .../input/events/MouseButtonHandler.java | 2 +- .../input/events/MouseMotionEvent.java | 20 +- .../input/events/MouseMotionHandler.java | 2 +- .../resources/BaseDeferredResource.java | 56 ++--- .../gamecore/resources/DeferredResource.java | 6 +- src/mightypork/gamecore/resources/Res.java | 44 ++-- .../resources/ResourceInitializer.java | 10 +- .../loading/AsyncResourceLoader.java | 65 +++-- .../loading/ResourceLoadRequest.java | 10 +- .../resources/loading/ResourceLoader.java | 6 +- 123 files changed, 2154 insertions(+), 1891 deletions(-) rename src/mightypork/gamecore/core/{DeltaMainLoop.java => BasicMainLoop.java} (93%) rename src/mightypork/gamecore/core/events/{ShutdownEvent.java => ShutdownRequest.java} (62%) rename src/mightypork/gamecore/core/events/{ShutdownListener.java => ShutdownRequestListener.java} (52%) create mode 100644 src/mightypork/gamecore/core/init/InitSequence.java create mode 100644 src/mightypork/gamecore/core/init/InitTaskBackend.java rename src/mightypork/gamecore/core/{config => init}/InitTaskConfig.java (88%) delete mode 100644 src/mightypork/gamecore/core/init/InitTaskScreens.java create mode 100644 src/mightypork/gamecore/core/init/InitTaskUI.java diff --git a/src/mightypork/gamecore/audio/AudioModule.java b/src/mightypork/gamecore/audio/AudioModule.java index e182607..54e4165 100644 --- a/src/mightypork/gamecore/audio/AudioModule.java +++ b/src/mightypork/gamecore/audio/AudioModule.java @@ -19,50 +19,50 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public abstract class AudioModule extends BackendModule implements Updateable { - + /** * Set listener position * * @param pos listener position */ public abstract void setListenerPos(Vect pos); - - + + /** * Get current listener position * * @return listener position */ public abstract Vect getListenerPos(); - + // -- instance -- - + private final Volume masterVolume = new Volume(1D); private final Volume effectsVolume = new JointVolume(masterVolume); private final Volume loopsVolume = new JointVolume(masterVolume); - + private final List loopPlayers = new ArrayList<>(); private final List resources = new ArrayList<>(); - - + + @Override public void destroy() { for (final DeferredAudio r : resources) { r.destroy(); } - + deinitSoundSystem(); } - - + + /** * Deinitialize the soud system, release resources etc.
* Audio resources are already destroyed. */ protected abstract void deinitSoundSystem(); - - + + @Override public void update(double delta) { @@ -70,8 +70,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { lp.update(delta); } } - - + + /** * Create effect resource * @@ -82,8 +82,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { return new EffectPlayer(createAudioResource(resource), effectsVolume); } - - + + /** * Register loop resource (music / effect loop) * @@ -96,8 +96,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { loopPlayers.add(p); return p; } - - + + /** * Create {@link DeferredAudio} for a resource, request deferred load and * add to the resources list.
@@ -115,8 +115,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { resources.add(a); return a; } - - + + /** * Create a backend-specific deferred audio resource.
* The actual resource instance should be created here. Registering, loading @@ -126,8 +126,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { * @return Deferred Audio */ protected abstract DeferredAudio doCreateResource(String res); - - + + /** * Fade out all loops (= fade out the currently playing loops) */ @@ -137,8 +137,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { p.fadeOut(); } } - - + + /** * Pause all loops (leave volume unchanged) */ @@ -148,8 +148,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { p.pause(); } } - - + + /** * Set level of master volume (volume multiplier) * @@ -159,8 +159,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { masterVolume.set(volume); } - - + + /** * Set level of effects volume (volume multiplier) * @@ -170,8 +170,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { effectsVolume.set(volume); } - - + + /** * Set level of loops volume (volume multiplier) * @@ -181,8 +181,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { loopsVolume.set(volume); } - - + + /** * Get level of master volume (volume multiplier) * @@ -192,8 +192,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { return masterVolume.get(); } - - + + /** * Get level of effects volume (volume multiplier) * @@ -203,8 +203,8 @@ public abstract class AudioModule extends BackendModule implements Updateable { { return effectsVolume.get(); } - - + + /** * Get level of loops volume (volume multiplier) * diff --git a/src/mightypork/gamecore/audio/DeferredAudio.java b/src/mightypork/gamecore/audio/DeferredAudio.java index baf8b2c..4a18528 100644 --- a/src/mightypork/gamecore/audio/DeferredAudio.java +++ b/src/mightypork/gamecore/audio/DeferredAudio.java @@ -14,7 +14,7 @@ import mightypork.utils.math.constraints.vect.Vect; */ @Alias(name = "Audio") public abstract class DeferredAudio extends BaseDeferredResource implements IAudio { - + /** * Create audio * @@ -24,22 +24,22 @@ public abstract class DeferredAudio extends BaseDeferredResource implements IAud { super(resourceName); } - - + + @Override public void play(double gain, double pitch, boolean loop) { 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.sound().getListenerPos().z()); } - - + + @Override public void play(double gain, double pitch, boolean loop, Vect pos) { diff --git a/src/mightypork/gamecore/audio/IAudio.java b/src/mightypork/gamecore/audio/IAudio.java index 09462a9..9105e3f 100644 --- a/src/mightypork/gamecore/audio/IAudio.java +++ b/src/mightypork/gamecore/audio/IAudio.java @@ -11,19 +11,19 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public interface IAudio extends Destroyable { - + /** * Pause loop (remember position and stop playing) - if was looping */ void pauseLoop(); - - + + /** * Resume loop (if was looping and paused) */ void resumeLoop(); - - + + /** * Adjust gain for the currently playing effect (can be used for fading * music) @@ -31,27 +31,27 @@ public interface IAudio extends Destroyable { * @param gain gain to set 0..1 */ void adjustGain(double gain); - - + + /** * Stop audio playback, free source. Meaningful for loops, may not work * properly for effects. */ void stop(); - - + + /** * @return true if the audio is playing */ boolean isPlaying(); - - + + /** * @return trie if the audio is paused */ boolean isPaused(); - - + + /** * Play as sound effect at listener position * @@ -60,8 +60,8 @@ public interface IAudio extends Destroyable { * @param loop looping */ void play(double gain, double pitch, boolean loop); - - + + /** * Play as sound effect at given position * @@ -73,8 +73,8 @@ public interface IAudio extends Destroyable { * @param z */ void play(double gain, double pitch, boolean loop, double x, double y, double z); - - + + /** * Play as sound effect at given X-Y position * @@ -85,8 +85,8 @@ public interface IAudio extends Destroyable { * @param y */ void play(double gain, double pitch, boolean loop, double x, double y); - - + + /** * Play as sound effect at given position * @@ -96,8 +96,8 @@ public interface IAudio extends Destroyable { * @param pos coord */ void play(double gain, double pitch, boolean loop, Vect pos); - - + + /** * Check if this audio is currently active (ie. playing or paused, not * stopped) @@ -105,5 +105,5 @@ public interface IAudio extends Destroyable { * @return is active */ boolean isActive(); - + } diff --git a/src/mightypork/gamecore/audio/JointVolume.java b/src/mightypork/gamecore/audio/JointVolume.java index 4a44e26..ba79708 100644 --- a/src/mightypork/gamecore/audio/JointVolume.java +++ b/src/mightypork/gamecore/audio/JointVolume.java @@ -10,10 +10,10 @@ import mightypork.utils.math.Calc; * @author Ondřej Hruška (MightyPork) */ public class JointVolume extends Volume { - + private final Volume[] volumes; - - + + /** * Create joint volume with master gain of 1 * @@ -25,8 +25,8 @@ public class JointVolume extends Volume { super(1D); this.volumes = volumes; } - - + + /** * Get combined gain (multiplied) */ @@ -36,11 +36,11 @@ public class JointVolume extends Volume { double d = super.get(); for (final Volume v : volumes) d *= v.get(); - + return Calc.clamp(d, 0, 1); } - - + + /** * Set master gain */ diff --git a/src/mightypork/gamecore/audio/SoundRegistry.java b/src/mightypork/gamecore/audio/SoundRegistry.java index 3d3c186..00581b4 100644 --- a/src/mightypork/gamecore/audio/SoundRegistry.java +++ b/src/mightypork/gamecore/audio/SoundRegistry.java @@ -16,11 +16,11 @@ import mightypork.utils.exceptions.KeyAlreadyExistsException; * @author Ondřej Hruška (MightyPork) */ public class SoundRegistry { - + private final Map effects = new HashMap<>(); private final Map loops = new HashMap<>(); - - + + /** * Register effect resource * @@ -33,16 +33,16 @@ public class SoundRegistry { 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 * @@ -52,11 +52,11 @@ 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) * @@ -71,17 +71,17 @@ public class SoundRegistry { 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) * @@ -91,11 +91,11 @@ public class SoundRegistry { public void addLoop(String key, LoopPlayer loop) { if (loops.containsKey(key)) throw new KeyAlreadyExistsException(); - + loops.put(key, loop); } - - + + /** * Get a loop player for key * @@ -110,8 +110,8 @@ public class SoundRegistry { } return p; } - - + + /** * Get a effect player for key * diff --git a/src/mightypork/gamecore/audio/Volume.java b/src/mightypork/gamecore/audio/Volume.java index b9f2fab..731a355 100644 --- a/src/mightypork/gamecore/audio/Volume.java +++ b/src/mightypork/gamecore/audio/Volume.java @@ -11,7 +11,7 @@ import mightypork.utils.struct.Mutable; * @author Ondřej Hruška (MightyPork) */ public class Volume extends Mutable { - + /** * @param d initial value */ @@ -19,12 +19,12 @@ public class Volume extends Mutable { { super(d); } - - + + @Override public void set(Double d) { super.set(Calc.clamp(d, 0, 1)); } - + } diff --git a/src/mightypork/gamecore/audio/players/AudioPlayer.java b/src/mightypork/gamecore/audio/players/AudioPlayer.java index 2d6b21c..51d0de1 100644 --- a/src/mightypork/gamecore/audio/players/AudioPlayer.java +++ b/src/mightypork/gamecore/audio/players/AudioPlayer.java @@ -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,8 +89,8 @@ public abstract class AudioPlayer implements Destroyable { { return (audio != null); } - - + + /** * Set base gain. 1 is original volume, 0 is silence. * @@ -100,8 +100,8 @@ public abstract class AudioPlayer implements Destroyable { { this.baseGain = gain; } - - + + /** * Set base pitch. 1 is original pitch, less is deeper, more is higher. * @@ -111,5 +111,5 @@ public abstract class AudioPlayer implements Destroyable { { this.basePitch = pitch; } - + } diff --git a/src/mightypork/gamecore/audio/players/EffectPlayer.java b/src/mightypork/gamecore/audio/players/EffectPlayer.java index 464be39..413c115 100644 --- a/src/mightypork/gamecore/audio/players/EffectPlayer.java +++ b/src/mightypork/gamecore/audio/players/EffectPlayer.java @@ -12,7 +12,7 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public class EffectPlayer extends AudioPlayer { - + /** * @param track audio resource * @param volume volume control @@ -21,8 +21,8 @@ public class EffectPlayer extends AudioPlayer { { super(track, volume); } - - + + /** * Play at listener * @@ -32,11 +32,11 @@ public class EffectPlayer extends AudioPlayer { public void play(double gain, double pitch) { if (!hasAudio()) return; - + getAudio().play(computeGain(gain), computePitch(pitch), false); } - - + + /** * Play at listener * @@ -46,8 +46,8 @@ public class EffectPlayer extends AudioPlayer { { play(gain, 1); } - - + + /** * Play at given position * @@ -58,8 +58,8 @@ public class EffectPlayer extends AudioPlayer { { play(gain, 1, pos); } - - + + /** * Play at given position * @@ -70,8 +70,8 @@ public class EffectPlayer extends AudioPlayer { public void play(double gain, double pitch, Vect pos) { if (!hasAudio()) return; - + getAudio().play(computeGain(gain), computePitch(pitch), false, pos); } - + } diff --git a/src/mightypork/gamecore/audio/players/LoopPlayer.java b/src/mightypork/gamecore/audio/players/LoopPlayer.java index 0f94bf9..3cc64c6 100644 --- a/src/mightypork/gamecore/audio/players/LoopPlayer.java +++ b/src/mightypork/gamecore/audio/players/LoopPlayer.java @@ -14,22 +14,22 @@ import mightypork.utils.math.animation.NumAnimated; * @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); } - + } diff --git a/src/mightypork/gamecore/core/App.java b/src/mightypork/gamecore/core/App.java index 9e0c1bf..fc77959 100644 --- a/src/mightypork/gamecore/core/App.java +++ b/src/mightypork/gamecore/core/App.java @@ -1,17 +1,29 @@ package mightypork.gamecore.core; -import java.util.ArrayList; +import java.io.File; +import java.util.Arrays; 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.events.MainLoopRequest; +import mightypork.gamecore.core.events.ShutdownRequest; +import mightypork.gamecore.core.init.InitSequence; import mightypork.gamecore.core.init.InitTask; +import mightypork.gamecore.core.init.InitTaskBackend; +import mightypork.gamecore.core.init.InitTaskCrashHandler; +import mightypork.gamecore.core.init.InitTaskIonizables; +import mightypork.gamecore.core.init.InitTaskLog; +import mightypork.gamecore.core.init.InitTaskLogHeader; +import mightypork.gamecore.core.init.InitTaskMainLoop; +import mightypork.gamecore.core.init.InitTaskResourceLoaderAsync; +import mightypork.gamecore.core.init.InitTaskWorkdir; import mightypork.gamecore.core.plugins.AppPlugin; import mightypork.gamecore.graphics.GraphicsModule; import mightypork.gamecore.graphics.Renderable; import mightypork.gamecore.input.InputModule; +import mightypork.utils.Str; import mightypork.utils.annotations.Stub; import mightypork.utils.eventbus.EventBus; import mightypork.utils.eventbus.clients.BusNode; @@ -26,25 +38,25 @@ 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; private boolean inited = false; - + /** List of installed App plugins */ protected final DelegatingList plugins = new DelegatingList(); /** List of initializers */ - protected final List initializers = new ArrayList<>(); - + protected final InitSequence initTasks = new InitSequence(); + /** The used main loop instance */ protected MainLoop mainLoop; - + private Renderable mainRenderable; - - + + /** * Create an app with given backend. * @@ -55,24 +67,39 @@ 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); - + addChildClient(this.plugins); + // initialize and use backend this.backend = backend; this.backend.bind(this); - this.eventBus.subscribe(backend); - this.backend.initialize(); + addChildClient(backend); + + addDefaultInitTasks(); + this.backend.addInitTasks(); + } + + + private void addDefaultInitTasks() + { + addInitTask(new InitTaskCrashHandler()); + addInitTask(new InitTaskWorkdir(new File("."), true)); + addInitTask(new InitTaskLog()); + addInitTask(new InitTaskBackend()); + addInitTask(new InitTaskIonizables()); + addInitTask(new InitTaskMainLoop()); + addInitTask(new InitTaskResourceLoaderAsync()); + addInitTask(new InitTaskLogHeader()); } - - + + /** * Add a plugin to the app. Plugins can eg. listen to bus events and react * to them. @@ -86,8 +113,8 @@ public class App extends BusNode { plugin.bind(this); plugin.initialize(); } - - + + /** * Add an initializer to the app. * @@ -98,11 +125,11 @@ public class App extends BusNode { if (started) { throw new IllegalStateException("App already started, cannot add initializers."); } - - initializers.add(initializer); + + initTasks.addTask(initializer); } - - + + /** * Set the main loop implementation * @@ -111,10 +138,10 @@ public class App extends BusNode { public void setMainLoop(MainLoop loop) { this.mainLoop = loop; - bus().subscribe(loop); // ? + addChildClient(loop); // ? } - - + + /** * Set the main renderable * @@ -124,8 +151,8 @@ public class App extends BusNode { { this.mainRenderable = renderable; } - - + + /** * Get current backend * @@ -135,8 +162,8 @@ public class App extends BusNode { { return backend; } - - + + /** * Initialize the App and start operating.
* This method should be called after adding all required initializers and @@ -148,60 +175,67 @@ public class App extends BusNode { throw new IllegalStateException("Already started."); } started = true; - + Log.i("Starting init..."); init(); - + if (mainLoop == null) { throw new IllegalStateException("The app has no main loop assigned."); } - + Log.i("Starting main loop..."); mainLoop.setRootRenderable(mainRenderable); mainLoop.start(); } - - + + private void init() { - + if (inited) { throw new IllegalStateException("Already inited."); } inited = true; - + // pre-init hook, just in case anyone wanted to have one. Log.f2("Calling pre-init hook..."); preInit(); - + Log.f2("Running init tasks..."); + + // sort initializers based on dependencies + final List orderedInitializers = initTasks.getSequence(); - // sort initializers by order. - final List orderedInitializers = InitTask.inOrder(initializers); - + // detailed logging + Log.f3("=== Task overview ==="); + for (final InitTask t : orderedInitializers) { + Log.f3("Task " + Str.pad(t.getName(), 20) + " class = " + Str.pad(Str.val(t), 30) + " prio = " + Str.pad("" + t.getPriority(), 12) + " deps = " + + Arrays.toString(t.getDependencies())); + } + 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(); } - + // user can now start the main loop etc. Log.f2("Calling post-init hook..."); postInit(); } - - + + /** * Hook called before the initialization sequence starts. */ @@ -209,8 +243,8 @@ public class App extends BusNode { protected void preInit() { } - - + + /** * Hook called after the initialization sequence is finished. */ @@ -218,44 +252,60 @@ public class App extends BusNode { protected void postInit() { } - - + + + /** + * Shut down the running instance.
+ * Deinitialize backend modules and terminate the JVM. + */ + public static void requestShutdown() + { + if (instance == null) { + Log.w("App is not running."); + System.exit(0); + } + + Log.i("Sending a shutdown request..."); + bus().send(new ShutdownRequest()); + } + + /** * Shut down the running instance.
* Deinitialize backend modules and terminate the JVM. */ public static void shutdown() { - if (instance != null) { - Log.i("Dispatching Shutdown event..."); - - bus().send(new ShutdownEvent(new Runnable() { - - @Override - public void run() - { - try { - final EventBus bus = bus(); - if (bus != null) { - bus.send(new DestroyEvent()); - bus.destroy(); - } - } catch (final Throwable e) { - Log.e(e); - } - - Log.i("Shutdown completed."); - System.exit(0); - } - })); - - } else { + if (instance == null) { Log.w("App is not running."); System.exit(0); } + + // It's safer to shutdown in rendering context + // (LWJGL backend has problems otherwise) + + App.bus().send(new MainLoopRequest(new Runnable() { + + @Override + public void run() + { + try { + final EventBus bus = bus(); + if (bus != null) { + bus.send(new DestroyEvent()); + } + } catch (final Throwable e) { + Log.e(e); + } + } + }, true)); + + + Log.i("Shutdown completed."); + System.exit(0); } - - + + /** * Get the currently running App instance. * @@ -265,8 +315,8 @@ public class App extends BusNode { { return instance; } - - + + /** * Get graphics module from the running app's backend * @@ -276,8 +326,8 @@ public class App extends BusNode { { return instance.backend.getGraphics(); } - - + + /** * Get audio module from the running app's backend * @@ -287,8 +337,8 @@ public class App extends BusNode { { return instance.backend.getAudio(); } - - + + /** * Get input module from the running app's backend * @@ -298,8 +348,8 @@ public class App extends BusNode { { return instance.backend.getInput(); } - - + + /** * Get event bus instance. * @@ -309,8 +359,8 @@ public class App extends BusNode { { return instance.eventBus; } - - + + /** * Get the main config, if initialized. * @@ -321,8 +371,8 @@ public class App extends BusNode { { return cfg("main"); } - - + + /** * Get a config by alias. * diff --git a/src/mightypork/gamecore/core/AppBackend.java b/src/mightypork/gamecore/core/AppBackend.java index ed2a100..f5a8037 100644 --- a/src/mightypork/gamecore/core/AppBackend.java +++ b/src/mightypork/gamecore/core/AppBackend.java @@ -2,8 +2,10 @@ package mightypork.gamecore.core; import mightypork.gamecore.audio.AudioModule; +import mightypork.gamecore.core.init.InitTaskBackend; import mightypork.gamecore.graphics.GraphicsModule; import mightypork.gamecore.input.InputModule; +import mightypork.utils.annotations.Stub; import mightypork.utils.eventbus.clients.BusNode; @@ -11,16 +13,17 @@ import mightypork.utils.eventbus.clients.BusNode; * Application backend interface (set of core modules).
* The goal of this abstraction is to allow easy migration to different * environment with different libraries etc. It should be as simple as using - * different backend. + * different backend.
+ * The backend is initialized using {@link InitTaskBackend}. * * @author MightyPork */ public abstract class AppBackend extends BusNode { - + /** App instance assigned using bind() */ protected App app; - - + + /** * Assign the initialized app instance to an "app" field. * @@ -35,28 +38,41 @@ public abstract class AppBackend extends BusNode { } + /** + * Add backend-specific init tasks or init task configurations.
+ * This is run after default init tasks have been added, and before the init + * sequence is started.
+ * The backend is already binded to the app. + */ + @Stub + public void addInitTasks() + { + // + } + + /** * Initialize backend modules, add them to event bus. */ public abstract void initialize(); - - + + /** * Get graphics module (screen manager, texture and font loader, renderer) * * @return graphics module */ public abstract GraphicsModule getGraphics(); - - + + /** * Get audio module ( * * @return audio module */ public abstract AudioModule getAudio(); - - + + /** * Get input module * diff --git a/src/mightypork/gamecore/core/BackendModule.java b/src/mightypork/gamecore/core/BackendModule.java index 39a9deb..038343e 100644 --- a/src/mightypork/gamecore/core/BackendModule.java +++ b/src/mightypork/gamecore/core/BackendModule.java @@ -12,7 +12,7 @@ import mightypork.utils.interfaces.Destroyable; * @author MightyPork */ public abstract class BackendModule extends BusNode implements Destroyable { - + /** * Initialize the backend module.
* Any initialization that would normally be done in constructor shall be @@ -20,8 +20,8 @@ public abstract class BackendModule extends BusNode implements Destroyable { * "call to overridable method from constructor" */ public abstract void init(); - - + + @Override @Stub public void destroy() diff --git a/src/mightypork/gamecore/core/DeltaMainLoop.java b/src/mightypork/gamecore/core/BasicMainLoop.java similarity index 93% rename from src/mightypork/gamecore/core/DeltaMainLoop.java rename to src/mightypork/gamecore/core/BasicMainLoop.java index 0970a5d..8b02c33 100644 --- a/src/mightypork/gamecore/core/DeltaMainLoop.java +++ b/src/mightypork/gamecore/core/BasicMainLoop.java @@ -18,76 +18,79 @@ import mightypork.utils.math.timing.TimerDelta; * * @author Ondřej Hruška (MightyPork) */ -public class DeltaMainLoop extends BusNode implements MainLoop { - +public class BasicMainLoop extends BusNode implements MainLoop { + /** * Max time spent on main loop tasks per cycle (s) */ protected double MAX_TIME_TASKS = 1 / 30D; - + /** * Max delta time (s) per frame.
* If delta is larger than this, it's clamped to it. */ protected double MAX_DELTA = 1 / 20D; - + private final Deque tasks = new ConcurrentLinkedDeque<>(); private TimerDelta timer; private Renderable rootRenderable; private volatile boolean running = true; - - + + @Override public void setRootRenderable(Renderable rootRenderable) { this.rootRenderable = rootRenderable; } - - + + @Override public void start() { timer = new TimerDelta(); - + while (running) { App.gfx().beginFrame(); - + double delta = timer.getDelta(); if (delta > MAX_DELTA) { Log.f3("(timing) Clamping delta: was " + delta + " s, MAX_DELTA = " + MAX_DELTA + " s"); delta = MAX_DELTA; } - + // dispatch update event App.bus().sendDirect(new UpdateEvent(delta)); - + // run main loop tasks Runnable r; final long t = Profiler.begin(); - + while ((r = tasks.poll()) != null) { Log.f3(" * Main loop task."); r.run(); - + if (Profiler.end(t) > MAX_TIME_TASKS) { Log.f3("! Time's up, postponing task to next cycle."); break; } } - + + // halt if tasks terminated the app. + if (!running) break; + beforeRender(); - + if (rootRenderable != null) { rootRenderable.render(); } - + afterRender(); - + App.gfx().endFrame(); } } - - + + /** * Called before render */ @@ -96,8 +99,8 @@ public class DeltaMainLoop extends BusNode implements MainLoop { { // } - - + + /** * Called after render */ @@ -106,15 +109,15 @@ public class DeltaMainLoop extends BusNode implements MainLoop { { // } - - + + @Override public void destroy() { running = false; } - - + + @Override public synchronized void queueTask(Runnable task, boolean skipQueue) { @@ -124,5 +127,5 @@ public class DeltaMainLoop extends BusNode implements MainLoop { tasks.addLast(task); } } - + } diff --git a/src/mightypork/gamecore/core/MainLoop.java b/src/mightypork/gamecore/core/MainLoop.java index 79ab64d..f47dcaf 100644 --- a/src/mightypork/gamecore/core/MainLoop.java +++ b/src/mightypork/gamecore/core/MainLoop.java @@ -12,7 +12,7 @@ import mightypork.utils.interfaces.Destroyable; * @author Ondřej Hruška (MightyPork) */ public interface MainLoop extends Destroyable { - + /** * Set primary renderable * @@ -20,19 +20,19 @@ public interface MainLoop extends Destroyable { * {@link ScreenRegistry} */ public abstract void setRootRenderable(Renderable rootRenderable); - - + + /** * Start the loop. The loop should be terminated when the destroy() method * is called. */ public abstract void start(); - - + + @Override public abstract void destroy(); - - + + /** * Add a task to queue to be executed in the main loop (in rendering * context). This may be eg. loading textures. @@ -41,5 +41,5 @@ public interface MainLoop extends Destroyable { * @param skipQueue true to skip the queue */ public abstract void queueTask(Runnable task, boolean skipQueue); - + } diff --git a/src/mightypork/gamecore/core/config/Config.java b/src/mightypork/gamecore/core/config/Config.java index 50376e4..93b23ec 100644 --- a/src/mightypork/gamecore/core/config/Config.java +++ b/src/mightypork/gamecore/core/config/Config.java @@ -4,8 +4,8 @@ package mightypork.gamecore.core.config; import java.util.HashMap; import java.util.Map; -import mightypork.gamecore.core.events.ShutdownEvent; -import mightypork.gamecore.core.events.ShutdownListener; +import mightypork.gamecore.core.events.ShutdownRequest; +import mightypork.gamecore.core.events.ShutdownRequestListener; import mightypork.gamecore.input.Key; import mightypork.gamecore.input.KeyStroke; import mightypork.utils.config.propmgr.Property; @@ -21,16 +21,16 @@ import mightypork.utils.logging.Log; * * @author Ondřej Hruška (MightyPork) */ -public class Config implements ShutdownListener { - +public class Config implements ShutdownRequestListener { + /** Array of configs registered for the app */ protected static Map configs = new HashMap<>(); - + private final Map strokes = new HashMap<>(); - + private final PropertyManager propertyManager; - - + + /** * Get a config from the static map, by given alias * @@ -40,15 +40,15 @@ public class Config implements ShutdownListener { public static Config forAlias(String alias) { final Config c = configs.get(alias); - + if (c == null) { throw new IllegalArgumentException("There is no config with alias \"" + alias + "\""); } - + return c; } - - + + /** * Register a config by alias. * @@ -60,11 +60,11 @@ public class Config implements ShutdownListener { if (configs.get(alias) != null) { throw new IllegalArgumentException("The alias \"" + alias + "\" is already used."); } - + configs.put(alias, config); } - - + + /** * Initialize property manager for a file * @@ -75,8 +75,8 @@ public class Config implements ShutdownListener { { this(new PropertyFile(WorkDir.getFile(file), headComment)); } - - + + /** * Initialize property manager for a given store * @@ -86,8 +86,8 @@ public class Config implements ShutdownListener { { propertyManager = new PropertyManager(store); } - - + + /** * Add a keystroke property * @@ -101,8 +101,8 @@ public class Config implements ShutdownListener { strokes.put(prefixKeyStroke(key), kprop); propertyManager.addProperty(kprop); } - - + + /** * Add a boolean property (flag) * @@ -114,8 +114,8 @@ public class Config implements ShutdownListener { { propertyManager.addBoolean(key, defval, comment); } - - + + /** * Add an integer property * @@ -127,8 +127,8 @@ public class Config implements ShutdownListener { { propertyManager.addInteger(key, defval, comment); } - - + + /** * Add a double property * @@ -140,8 +140,8 @@ public class Config implements ShutdownListener { { propertyManager.addDouble(key, defval, comment); } - - + + /** * Add a string property * @@ -153,8 +153,8 @@ public class Config implements ShutdownListener { { propertyManager.addString(key, defval, comment); } - - + + /** * Add an arbitrary property (can be custom type) * @@ -164,8 +164,8 @@ public class Config implements ShutdownListener { { propertyManager.addProperty(prop); } - - + + /** * Load config from file */ @@ -173,8 +173,8 @@ public class Config implements ShutdownListener { { propertyManager.load(); } - - + + /** * Save config to file */ @@ -183,8 +183,8 @@ public class Config implements ShutdownListener { Log.f3("Saving config."); propertyManager.save(); } - - + + /** * Get an option for key * @@ -197,14 +197,14 @@ public class Config implements ShutdownListener { if (propertyManager.getProperty(key) == null) { throw new IllegalArgumentException("No such property: " + key); } - + return propertyManager.getValue(key); } catch (final ClassCastException cce) { throw new RuntimeException("Property of incompatible type: " + key); } } - - + + /** * Set option to a value. Call the save() method to make the change * permanent. @@ -217,11 +217,11 @@ public class Config implements ShutdownListener { if (propertyManager.getProperty(key) == null) { throw new IllegalArgumentException("No such property: " + key); } - + propertyManager.setValue(key, value); } - - + + /** * Add "key." before the given config file key * @@ -232,8 +232,8 @@ public class Config implements ShutdownListener { { return "key." + cfgKey; } - - + + /** * Get keystroke for name * @@ -246,11 +246,11 @@ public class Config implements ShutdownListener { if (kp == null) { throw new IllegalArgumentException("No such stroke: " + cfgKey); } - + return kp.getValue(); } - - + + /** * Set a keystroke for name * @@ -264,13 +264,13 @@ public class Config implements ShutdownListener { if (kp == null) { throw new IllegalArgumentException("No such stroke: " + cfgKey); } - + kp.getValue().setTo(key, mod); } - - + + @Override - public void onShutdown(ShutdownEvent event) + public void onShutdownRequested(ShutdownRequest event) { save(); // save changes done to the config } diff --git a/src/mightypork/gamecore/core/config/KeyStrokeProperty.java b/src/mightypork/gamecore/core/config/KeyStrokeProperty.java index 2f3c49d..381266d 100644 --- a/src/mightypork/gamecore/core/config/KeyStrokeProperty.java +++ b/src/mightypork/gamecore/core/config/KeyStrokeProperty.java @@ -16,7 +16,7 @@ import mightypork.utils.config.propmgr.Property; * @author Ondřej Hruška (MightyPork) */ public class KeyStrokeProperty extends Property { - + /** * Make a keystroke property * @@ -28,32 +28,32 @@ public class KeyStrokeProperty extends Property { { super(key, defaultValue, comment); } - - + + @Override public void fromString(String string) { if (string != null) { // keep the same instance - + final Key backup_key = value.getKey(); final int backup_mod = value.getMod(); - + value.loadFromString(string); if (value.getKey() == Keys.NONE) { value.setTo(backup_key, backup_mod); } } } - - + + @Override public String toString() { return value.saveToString(); } - - + + @Override public void setValue(Object value) { diff --git a/src/mightypork/gamecore/core/events/MainLoopRequest.java b/src/mightypork/gamecore/core/events/MainLoopRequest.java index e21a64e..8fa4abe 100644 --- a/src/mightypork/gamecore/core/events/MainLoopRequest.java +++ b/src/mightypork/gamecore/core/events/MainLoopRequest.java @@ -13,11 +13,11 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class MainLoopRequest extends BusEvent { - + private final Runnable task; private final boolean priority; - - + + /** * @param task task to run on main thread in rendering context */ @@ -25,8 +25,8 @@ public class MainLoopRequest extends BusEvent { { this(task, false); } - - + + /** * @param task task to run on main thread in rendering context * @param priority if true, skip other tasks in queue @@ -36,8 +36,8 @@ public class MainLoopRequest extends BusEvent { this.task = task; this.priority = priority; } - - + + @Override public void handleBy(MainLoop handler) { diff --git a/src/mightypork/gamecore/core/events/ShutdownEvent.java b/src/mightypork/gamecore/core/events/ShutdownRequest.java similarity index 62% rename from src/mightypork/gamecore/core/events/ShutdownEvent.java rename to src/mightypork/gamecore/core/events/ShutdownRequest.java index cef66a3..f346dea 100644 --- a/src/mightypork/gamecore/core/events/ShutdownEvent.java +++ b/src/mightypork/gamecore/core/events/ShutdownRequest.java @@ -15,26 +15,13 @@ import mightypork.utils.logging.Log; * * @author Ondřej Hruška (MightyPork) */ -public class ShutdownEvent extends BusEvent { - - private final Runnable shutdownTask; - - - /** - * Make a shutdown event - * - * @param doShutdown Task that does the actual shutdown - */ - public ShutdownEvent(Runnable doShutdown) - { - this.shutdownTask = doShutdown; - } +public class ShutdownRequest extends BusEvent { @Override - protected void handleBy(ShutdownListener handler) + protected void handleBy(ShutdownRequestListener handler) { - handler.onShutdown(this); + handler.onShutdownRequested(this); } @@ -44,7 +31,7 @@ public class ShutdownEvent extends BusEvent { if (!isConsumed()) { Log.i("Shutting down..."); - App.bus().send(new MainLoopRequest(shutdownTask, true)); + App.shutdown(); } else { Log.i("Shutdown aborted."); diff --git a/src/mightypork/gamecore/core/events/ShutdownListener.java b/src/mightypork/gamecore/core/events/ShutdownRequestListener.java similarity index 52% rename from src/mightypork/gamecore/core/events/ShutdownListener.java rename to src/mightypork/gamecore/core/events/ShutdownRequestListener.java index 26f6495..c836275 100644 --- a/src/mightypork/gamecore/core/events/ShutdownListener.java +++ b/src/mightypork/gamecore/core/events/ShutdownRequestListener.java @@ -6,13 +6,13 @@ package mightypork.gamecore.core.events; * * @author Ondřej Hruška (MightyPork) */ -public interface ShutdownListener { +public interface ShutdownRequestListener { /** - * Intercept quit request.
- * Consume the event to abort shutdown (ie. ask user to save) + * Intercept shutdown request.
+ * Consume the event to abort shutdown (ie. ask user to save). * * @param event quit request event. */ - void onShutdown(ShutdownEvent event); + void onShutdownRequested(ShutdownRequest event); } diff --git a/src/mightypork/gamecore/core/init/InitSequence.java b/src/mightypork/gamecore/core/init/InitSequence.java new file mode 100644 index 0000000..c19adef --- /dev/null +++ b/src/mightypork/gamecore/core/init/InitSequence.java @@ -0,0 +1,168 @@ +package mightypork.gamecore.core.init; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import mightypork.utils.Reflect; +import mightypork.utils.logging.Log; + + +/** + * initialization sequence that takes care of task dependencies and ordering. + * + * @author Ondřej Hruška (MightyPork) + */ +public class InitSequence { + + private final Map taskMap = new HashMap<>(); + + + /** + * Add a task. If a task with the name already exists, replace it. + * + * @param task task to add + */ + public void addTask(InitTask task) + { + final String name = task.getName(); + + // detailed logging +// if (taskMap.containsKey(name)) { +// Log.f3("REPL init " + Str.pad("\"" + name + "\"", 20) + " <" + Str.val(task) + ">"); +// } else { +// Log.f3("ADD init " + Str.pad("\"" + name + "\"", 20) + " <" + Str.val(task) + ">"); +// } + + taskMap.put(name, task); + } + + + /** + * Get task sequence in proper order. + * + * @return initialization sequence + */ + public List getSequence() + { + final List remainingTasks = new ArrayList<>(taskMap.values()); + + final List orderedTasks = new ArrayList<>(); + final Set loadedTaskNames = new HashSet<>(); + + // resolve task order + InitTask taskToAdd = null; + do { + taskToAdd = null; + + for (final InitTask task : remainingTasks) { + + String[] deps = task.getDependencies(); + if (deps == null) deps = new String[] {}; + + int missingDeps = deps.length; + + for (final String d : deps) { + if (loadedTaskNames.contains(d)) missingDeps--; + } + + if (missingDeps == 0) { + if (taskToAdd == null || taskToAdd.getPriority() < task.getPriority()) { + taskToAdd = task; + } + } + } + + if (taskToAdd != null) { + orderedTasks.add(taskToAdd); + loadedTaskNames.add(taskToAdd.getName()); + remainingTasks.remove(taskToAdd); + } + + } while (taskToAdd != null); + + checkLeftovers(loadedTaskNames, remainingTasks); + + return orderedTasks; + } + + + public List getSequenceOldImpl() + { + final List remainingTasks = new ArrayList<>(taskMap.values()); + + final List orderedTasks = new ArrayList<>(); + final Set loadedTaskNames = new HashSet<>(); + + // resolve task order + int addedThisIteration = 0; + do { + addedThisIteration = 0; + for (final Iterator i = remainingTasks.iterator(); i.hasNext();) { + final InitTask task = i.next(); + + String[] deps = task.getDependencies(); + if (deps == null) deps = new String[] {}; + + int missingDeps = deps.length; + + for (final String d : deps) { + if (loadedTaskNames.contains(d)) missingDeps--; + } + + if (missingDeps == 0) { + orderedTasks.add(task); + loadedTaskNames.add(task.getName()); + i.remove(); + addedThisIteration++; + } + } + } while (addedThisIteration > 0); + + checkLeftovers(loadedTaskNames, remainingTasks); + + return orderedTasks; + } + + + private void checkLeftovers(Collection loadedTaskNames, Collection remainingTasks) + { + // check if any tasks are left out + if (remainingTasks.size() > 0) { + + // build error message for each bad task + int badInitializers = 0; + for (final InitTask task : remainingTasks) { + + if (Reflect.hasAnnotation(task.getClass(), OptionalInitTask.class)) { + continue; + } + + badInitializers++; + + String notSatisfied = ""; + + for (final String d : task.getDependencies()) { + if (!loadedTaskNames.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."); + } + } +} diff --git a/src/mightypork/gamecore/core/init/InitTask.java b/src/mightypork/gamecore/core/init/InitTask.java index 142feed..740c094 100644 --- a/src/mightypork/gamecore/core/init/InitTask.java +++ b/src/mightypork/gamecore/core/init/InitTask.java @@ -1,16 +1,8 @@ package mightypork.gamecore.core.init; -import java.util.ArrayList; -import java.util.HashSet; -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; /** @@ -21,11 +13,17 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public abstract class InitTask { - - /** App instance assigned using bind() */ - protected App app; + protected static final int PRIO_FIRST = Integer.MAX_VALUE; + protected static final int PRIO_EARLY = 9000; + protected static final int PRIO_DEFAULT = 0; + protected static final int PRIO_LATE = -9000; + protected static final int PRIO_LAST = Integer.MIN_VALUE; + /** App instance assigned using bind() */ + protected App app; + + /** * Assign the initialized app instance to an "app" field. * @@ -35,8 +33,8 @@ public abstract class InitTask { { this.app = app; } - - + + /** * An init method that is called before the run() method.
* This method should be left unimplemented in the task, and can be used to @@ -47,8 +45,8 @@ public abstract class InitTask { { // } - - + + /** * Hook for extra action before the main task action.
* Can be overridden during app configuration to "bake-in" extra actions. @@ -58,14 +56,14 @@ public abstract class InitTask { { // } - - + + /** * Run the initializer on app. */ public abstract void run(); - - + + /** * Hook executed after the "run()" method.
* Can be overridden during app configuration to "bake-in" extra actions. @@ -75,8 +73,8 @@ public abstract class InitTask { { // } - - + + /** * Get name of this initializer (for dependency resolver).
* The name should be short, snake_case and precise. @@ -84,8 +82,8 @@ public abstract class InitTask { * @return name */ public abstract String getName(); - - + + /** * Get what other initializers must be already loaded before this can load.
* Depending on itself or creating a circular dependency will cause error.
@@ -99,78 +97,17 @@ public abstract class InitTask { { return new String[] {}; } - - + + /** - * Order init tasks so that all dependencies are loaded before thye are - * needed by the tasks. + * Get priority in the init sequence. Tasks with higher priority are loaded + * earlier (but only after their dependencies are loaded). * - * @param tasks task list - * @return task list ordered + * @return priority, higher = runs earlier */ - public static List inOrder(List tasks) + @Stub + public int getPriority() { - final List remaining = new ArrayList<>(tasks); - - final List ordered = new ArrayList<>(); - final Set loaded = new HashSet<>(); - - // resolve task order - int addedThisIteration = 0; - do { - addedThisIteration = 0; - for (final Iterator 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()); - i.remove(); - addedThisIteration++; - } - } - } 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; + return PRIO_DEFAULT; } } diff --git a/src/mightypork/gamecore/core/init/InitTaskBackend.java b/src/mightypork/gamecore/core/init/InitTaskBackend.java new file mode 100644 index 0000000..dc0c4e3 --- /dev/null +++ b/src/mightypork/gamecore/core/init/InitTaskBackend.java @@ -0,0 +1,41 @@ +package mightypork.gamecore.core.init; + + +import mightypork.gamecore.core.App; + + +/** + * Initialize backend. The main point of postponing this is to make sure the + * init is logged properly. + * + * @author Ondřej Hruška (MightyPork) + */ +public class InitTaskBackend extends InitTask { + + @Override + public void run() + { + App.instance().getBackend().initialize(); + } + + + @Override + public String getName() + { + return "backend"; + } + + + @Override + public String[] getDependencies() + { + return new String[] { "log" }; + } + + + @Override + public int getPriority() + { + return PRIO_EARLY; + } +} diff --git a/src/mightypork/gamecore/core/config/InitTaskConfig.java b/src/mightypork/gamecore/core/init/InitTaskConfig.java similarity index 88% rename from src/mightypork/gamecore/core/config/InitTaskConfig.java rename to src/mightypork/gamecore/core/init/InitTaskConfig.java index 22bd2d8..65de064 100644 --- a/src/mightypork/gamecore/core/config/InitTaskConfig.java +++ b/src/mightypork/gamecore/core/init/InitTaskConfig.java @@ -1,7 +1,7 @@ -package mightypork.gamecore.core.config; +package mightypork.gamecore.core.init; -import mightypork.gamecore.core.init.InitTask; +import mightypork.gamecore.core.config.Config; import mightypork.utils.annotations.Stub; @@ -72,4 +72,11 @@ public abstract class InitTaskConfig extends InitTask { return new String[] { "workdir" }; } + + @Override + public int getPriority() + { + return PRIO_FIRST; + } + } diff --git a/src/mightypork/gamecore/core/init/InitTaskCrashHandler.java b/src/mightypork/gamecore/core/init/InitTaskCrashHandler.java index a19966c..e5fd46e 100644 --- a/src/mightypork/gamecore/core/init/InitTaskCrashHandler.java +++ b/src/mightypork/gamecore/core/init/InitTaskCrashHandler.java @@ -16,14 +16,14 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public class InitTaskCrashHandler extends InitTask implements UncaughtExceptionHandler { - + @Override public void run() { Thread.setDefaultUncaughtExceptionHandler(this); } - - + + @Override @Stub public void uncaughtException(Thread thread, Throwable throwable) @@ -31,11 +31,18 @@ public class InitTaskCrashHandler extends InitTask implements UncaughtExceptionH Log.e("The game has crashed.", throwable); App.shutdown(); } - - + + @Override public String getName() { return "crash_handler"; } + + + @Override + public int getPriority() + { + return PRIO_FIRST; + } } diff --git a/src/mightypork/gamecore/core/init/InitTaskCustom.java b/src/mightypork/gamecore/core/init/InitTaskCustom.java index 105946e..492b076 100644 --- a/src/mightypork/gamecore/core/init/InitTaskCustom.java +++ b/src/mightypork/gamecore/core/init/InitTaskCustom.java @@ -8,39 +8,39 @@ package mightypork.gamecore.core.init; * @author Ondřej Hruška (MightyPork) */ public abstract class InitTaskCustom extends InitTask { - + private final String name; private final String[] deps; - - + + public InitTaskCustom(String name) { this(name, null); } - - + + public InitTaskCustom(String name, String[] dependencies) { this.name = name; this.deps = dependencies; } - - + + @Override public abstract void run(); - - + + @Override public String getName() { return name; } - - + + @Override public String[] getDependencies() { return deps; } - + } diff --git a/src/mightypork/gamecore/core/init/InitTaskDisplay.java b/src/mightypork/gamecore/core/init/InitTaskDisplay.java index 230860b..064bdf2 100644 --- a/src/mightypork/gamecore/core/init/InitTaskDisplay.java +++ b/src/mightypork/gamecore/core/init/InitTaskDisplay.java @@ -5,7 +5,7 @@ import mightypork.gamecore.graphics.GraphicsModule; /** - * Setup main window. + * Setup main window / display with rendering context. * * @author Ondřej Hruška (MightyPork) */ diff --git a/src/mightypork/gamecore/core/init/InitTaskIonizables.java b/src/mightypork/gamecore/core/init/InitTaskIonizables.java index db2de6f..fe46fbd 100644 --- a/src/mightypork/gamecore/core/init/InitTaskIonizables.java +++ b/src/mightypork/gamecore/core/init/InitTaskIonizables.java @@ -12,26 +12,26 @@ import mightypork.utils.math.algo.Move; /** - * Register extra ionizables added by the game library (non-native ION types).
- * This initializer can be called anywhere in the initialization sequence. + * Register extra ionizables. More ionizables can be registered ie. in the + * after() hook. * * @author Ondřej Hruška (MightyPork) */ public class InitTaskIonizables extends InitTask { - + @Override public void run() { Ion.registerIndirect(255, new IonizerBinary() { - + @Override public void save(Coord object, IonOutput out) throws IOException { out.writeInt(object.x); out.writeInt(object.y); } - - + + @Override public Coord load(IonInput in) throws IOException { @@ -39,19 +39,19 @@ public class InitTaskIonizables extends InitTask { final int y = in.readInt(); return new Coord(x, y); } - + }); - + Ion.registerIndirect(254, new IonizerBinary() { - + @Override public void save(Move object, IonOutput out) throws IOException { out.writeInt(object.x()); out.writeInt(object.y()); } - - + + @Override public Move load(IonInput in) throws IOException { @@ -59,15 +59,22 @@ public class InitTaskIonizables extends InitTask { final int y = in.readInt(); return new Move(x, y); } - + }); } - - + + @Override public String getName() { - return "ion"; + return "ionizables"; } + + @Override + public int getPriority() + { + return PRIO_EARLY; + } + } diff --git a/src/mightypork/gamecore/core/init/InitTaskLog.java b/src/mightypork/gamecore/core/init/InitTaskLog.java index a7991bb..33940e0 100644 --- a/src/mightypork/gamecore/core/init/InitTaskLog.java +++ b/src/mightypork/gamecore/core/init/InitTaskLog.java @@ -4,28 +4,27 @@ package mightypork.gamecore.core.init; import java.io.File; import java.util.logging.Level; +import mightypork.utils.Str; import mightypork.utils.files.WorkDir; import mightypork.utils.logging.Log; import mightypork.utils.logging.writers.LogWriter; -import mightypork.utils.string.StringUtil; /** - * Init main logger and console log printing.
- * Must be called after workdir is initialized. + * Init logging system. * * @author Ondřej Hruška (MightyPork) */ public class InitTaskLog extends InitTask { - - private String logDir = "log"; + + private String logDir = "."; private String logName = "runtime"; private int archiveCount = 5; - + private Level levelWrite = Level.ALL; private Level levelPrint = Level.ALL; - - + + /** * Set log directory (relative to workdir).
* Defaults to "log". @@ -36,8 +35,8 @@ public class InitTaskLog extends InitTask { { this.logDir = logDir; } - - + + /** * Set log name. This name is used as a prefix for archived log files.
* Should contain only valid filename characters.
@@ -47,14 +46,14 @@ public class InitTaskLog extends InitTask { */ public void setLogName(String logName) { - if (!StringUtil.isValidFilenameString(logName)) { + if (!Str.isValidFilenameString(logName)) { throw new IllegalArgumentException("Invalid log name."); } - + this.logName = logName; } - - + + /** * Set number of logs to keep in the logs directory.
* Set to 0 to keep just the last log, -1 to keep unlimited number of logs.
@@ -66,8 +65,8 @@ public class InitTaskLog extends InitTask { { this.archiveCount = archiveCount; } - - + + /** * Set logging levels (minimal level of message to be accepted)
* Defaults to ALL, ALL. @@ -80,8 +79,8 @@ public class InitTaskLog extends InitTask { this.levelWrite = levelWrite; this.levelPrint = levelPrint; } - - + + @Override public void run() { @@ -90,18 +89,25 @@ public class InitTaskLog extends InitTask { Log.setLevel(levelWrite); Log.setSysoutLevel(levelPrint); } - - + + @Override public String getName() { return "log"; } - - + + @Override public String[] getDependencies() { return new String[] { "workdir" }; } + + + @Override + public int getPriority() + { + return PRIO_FIRST; + } } diff --git a/src/mightypork/gamecore/core/init/InitTaskLogHeader.java b/src/mightypork/gamecore/core/init/InitTaskLogHeader.java index 7c38bf5..9790562 100644 --- a/src/mightypork/gamecore/core/init/InitTaskLogHeader.java +++ b/src/mightypork/gamecore/core/init/InitTaskLogHeader.java @@ -49,4 +49,11 @@ public class InitTaskLogHeader extends InitTask { { return new String[] { "log", "workdir" }; } + + + @Override + public int getPriority() + { + return PRIO_FIRST; + } } diff --git a/src/mightypork/gamecore/core/init/InitTaskMainLoop.java b/src/mightypork/gamecore/core/init/InitTaskMainLoop.java index 4a4b376..5729e2c 100644 --- a/src/mightypork/gamecore/core/init/InitTaskMainLoop.java +++ b/src/mightypork/gamecore/core/init/InitTaskMainLoop.java @@ -1,40 +1,52 @@ package mightypork.gamecore.core.init; +import mightypork.gamecore.core.BasicMainLoop; import mightypork.gamecore.core.MainLoop; +import mightypork.utils.annotations.Stub; /** - * Task to add a resource loader.
- * By default the async resource loader is used + * Task to add a main loop. * * @author Ondřej Hruška (MightyPork) */ -public abstract class InitTaskMainLoop extends InitTask { - - /** The loader. */ +public class InitTaskMainLoop extends InitTask { + + /** The loop, can be accessed in the after() method. */ protected MainLoop loop; - - + + @Override public void run() { loop = getLoopImpl(); app.setMainLoop(loop); } - - + + /** - * Create a loader impl + * Create a main loop * * @return loader */ - protected abstract MainLoop getLoopImpl(); - - + @Stub + protected MainLoop getLoopImpl() + { + return new BasicMainLoop(); + } + + @Override public String getName() { return "main_loop"; } + + + @Override + public int getPriority() + { + return PRIO_EARLY; + } } diff --git a/src/mightypork/gamecore/core/init/InitTaskResourceLoader.java b/src/mightypork/gamecore/core/init/InitTaskResourceLoader.java index 3ca32b8..124727b 100644 --- a/src/mightypork/gamecore/core/init/InitTaskResourceLoader.java +++ b/src/mightypork/gamecore/core/init/InitTaskResourceLoader.java @@ -21,6 +21,7 @@ public abstract class InitTaskResourceLoader extends InitTask { { loader = getLoaderImpl(); if (loader != null) loader.init(); + app.addChildClient(loader); } diff --git a/src/mightypork/gamecore/core/init/InitTaskResourceLoaderAsync.java b/src/mightypork/gamecore/core/init/InitTaskResourceLoaderAsync.java index 28a3b1a..6c906a4 100644 --- a/src/mightypork/gamecore/core/init/InitTaskResourceLoaderAsync.java +++ b/src/mightypork/gamecore/core/init/InitTaskResourceLoaderAsync.java @@ -6,13 +6,12 @@ import mightypork.gamecore.resources.loading.ResourceLoader; /** - * Task to add a resource loader.
- * By default the async resource loader is used + * Add Async resource loader. * * @author Ondřej Hruška (MightyPork) */ public class InitTaskResourceLoaderAsync extends InitTaskResourceLoader { - + /** * Create a loader impl * @@ -21,10 +20,6 @@ public class InitTaskResourceLoaderAsync extends InitTaskResourceLoader { @Override protected ResourceLoader getLoaderImpl() { - final AsyncResourceLoader loader = new AsyncResourceLoader(); - - // could now configure the loader - - return loader; + return new AsyncResourceLoader(); } } diff --git a/src/mightypork/gamecore/core/init/InitTaskResourceLoaderNone.java b/src/mightypork/gamecore/core/init/InitTaskResourceLoaderNone.java index 56d7b84..03a34ec 100644 --- a/src/mightypork/gamecore/core/init/InitTaskResourceLoaderNone.java +++ b/src/mightypork/gamecore/core/init/InitTaskResourceLoaderNone.java @@ -5,14 +5,14 @@ import mightypork.gamecore.resources.loading.ResourceLoader; /** - * Task to add a resource loader.
- * By default the async resource loader is used + * Add no resource loader. That will cause resources to be loaded on-demand. May + * cause lag if the resources are too large. * * @author Ondřej Hruška (MightyPork) */ public class InitTaskResourceLoaderNone extends InitTaskResourceLoader { - - + + @Override protected ResourceLoader getLoaderImpl() { diff --git a/src/mightypork/gamecore/core/init/InitTaskResources.java b/src/mightypork/gamecore/core/init/InitTaskResources.java index 4602a44..af7cff0 100644 --- a/src/mightypork/gamecore/core/init/InitTaskResources.java +++ b/src/mightypork/gamecore/core/init/InitTaskResources.java @@ -11,24 +11,28 @@ import mightypork.gamecore.resources.ResourceInitializer; * @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() { + // main loop handles resource load rewuests that run in rendering context + // must be before, otherwise the requests would get lost. return new String[] { "resource_loader", "main_loop" }; } + + } diff --git a/src/mightypork/gamecore/core/init/InitTaskScreens.java b/src/mightypork/gamecore/core/init/InitTaskScreens.java deleted file mode 100644 index 5d68f59..0000000 --- a/src/mightypork/gamecore/core/init/InitTaskScreens.java +++ /dev/null @@ -1,42 +0,0 @@ -package mightypork.gamecore.core.init; - - -import mightypork.gamecore.graphics.Renderable; - - -/** - * Task to init renderable screens (part of the main loop).
- * Resources must already be ready. - * - * @author Ondřej Hruška (MightyPork) - */ -public abstract class InitTaskScreens extends InitTask { - - @Override - public void run() - { - app.setMainRenderable(getMainRenderableImpl()); - } - - - /** - * Create a loader impl - * - * @return loader - */ - protected abstract Renderable getMainRenderableImpl(); - - - @Override - public String getName() - { - return "renderables"; - } - - - @Override - public String[] getDependencies() - { - return new String[] { "resources", "main_loop" }; - } -} diff --git a/src/mightypork/gamecore/core/init/InitTaskUI.java b/src/mightypork/gamecore/core/init/InitTaskUI.java new file mode 100644 index 0000000..4cecbb0 --- /dev/null +++ b/src/mightypork/gamecore/core/init/InitTaskUI.java @@ -0,0 +1,51 @@ +package mightypork.gamecore.core.init; + + +import mightypork.gamecore.graphics.Renderable; +import mightypork.gamecore.resources.Res; + + +/** + * Task to init main renderable (UI).
+ * Resources are already registered in {@link Res}. + * + * @author Ondřej Hruška (MightyPork) + */ +public abstract class InitTaskUI extends InitTask { + + @Override + public void run() + { + app.setMainRenderable(createMainRenderable()); + } + + + /** + * Create a loader impl + * + * @return loader + */ + protected abstract Renderable createMainRenderable(); + + + @Override + public String getName() + { + return "ui"; + } + + + @Override + public String[] getDependencies() + { + // main loop queues layout change events, would lose them otherwise + return new String[] { "resources", "main_loop" }; + } + + + @Override + public int getPriority() + { + return PRIO_LAST; + } +} diff --git a/src/mightypork/gamecore/core/init/InitTaskWorkdir.java b/src/mightypork/gamecore/core/init/InitTaskWorkdir.java index 131fbd2..a63ef76 100644 --- a/src/mightypork/gamecore/core/init/InitTaskWorkdir.java +++ b/src/mightypork/gamecore/core/init/InitTaskWorkdir.java @@ -133,4 +133,11 @@ public class InitTaskWorkdir extends InitTask { { return "workdir"; } + + + @Override + public int getPriority() + { + return PRIO_EARLY; + } } diff --git a/src/mightypork/gamecore/core/plugins/AppPlugin.java b/src/mightypork/gamecore/core/plugins/AppPlugin.java index f31e87c..0074f67 100644 --- a/src/mightypork/gamecore/core/plugins/AppPlugin.java +++ b/src/mightypork/gamecore/core/plugins/AppPlugin.java @@ -14,11 +14,11 @@ import mightypork.utils.eventbus.clients.BusNode; * @author Ondřej Hruška (MightyPork) */ public class AppPlugin extends BusNode { - + /** App instance assigned using bind() */ protected App app; - - + + /** * Assign the initialized app instance to an "app" field. * @@ -28,8 +28,8 @@ public class AppPlugin extends BusNode { { this.app = app; } - - + + /** * Initialize the plugin for the given App.
* The plugin is already attached to the event bus. diff --git a/src/mightypork/gamecore/core/plugins/screenshot/InitTaskPluginScreenshot.java b/src/mightypork/gamecore/core/plugins/screenshot/InitTaskPluginScreenshot.java index 8b3247f..42dbdc6 100644 --- a/src/mightypork/gamecore/core/plugins/screenshot/InitTaskPluginScreenshot.java +++ b/src/mightypork/gamecore/core/plugins/screenshot/InitTaskPluginScreenshot.java @@ -12,10 +12,10 @@ import mightypork.utils.files.WorkDir; * @author Ondřej Hruška (MightyPork) */ public class InitTaskPluginScreenshot extends InitTask { - + private String screenshotDir; - - + + /** * Initialize to use the "screenshots" directory */ @@ -23,8 +23,8 @@ public class InitTaskPluginScreenshot extends InitTask { { this("screenshots"); } - - + + /** * Initialize to use the given directory for saving. * @@ -34,8 +34,8 @@ public class InitTaskPluginScreenshot extends InitTask { { this.screenshotDir = dir; } - - + + /** * Set screenshot directory * @@ -45,33 +45,33 @@ public class InitTaskPluginScreenshot extends InitTask { { this.screenshotDir = dir; } - - + + @Override public void run() { WorkDir.addPath("_screenshot_dir", screenshotDir); app.addPlugin(getPluginImpl()); } - - + + protected AppPlugin getPluginImpl() { return new ScreenshotPlugin(); } - - + + @Override public String getName() { return "plugin_screenshot"; } - - + + @Override public String[] getDependencies() { return new String[] { "workdir" }; } - + } diff --git a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotPlugin.java b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotPlugin.java index 38060a0..e5cc5ab 100644 --- a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotPlugin.java +++ b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotPlugin.java @@ -15,7 +15,7 @@ import mightypork.utils.Support; * @author Ondřej Hruška (MightyPork) */ public class ScreenshotPlugin extends AppPlugin implements ScreenshotRequestListener { - + /** * Take screenshot. Called by the trigger event. */ @@ -23,7 +23,7 @@ public class ScreenshotPlugin extends AppPlugin implements ScreenshotRequestList public void onScreenshotRequest() { App.bus().send(new MainLoopRequest(new Runnable() { - + @Override public void run() { diff --git a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequest.java b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequest.java index c4f08f7..4c9707b 100644 --- a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequest.java +++ b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequest.java @@ -12,11 +12,11 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class ScreenshotRequest extends BusEvent { - + @Override protected void handleBy(ScreenshotRequestListener handler) { handler.onScreenshotRequest(); } - + } diff --git a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequestListener.java b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequestListener.java index b113914..715d142 100644 --- a/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequestListener.java +++ b/src/mightypork/gamecore/core/plugins/screenshot/ScreenshotRequestListener.java @@ -2,6 +2,6 @@ package mightypork.gamecore.core.plugins.screenshot; public interface ScreenshotRequestListener { - + void onScreenshotRequest(); } diff --git a/src/mightypork/gamecore/core/plugins/screenshot/TaskTakeScreenshot.java b/src/mightypork/gamecore/core/plugins/screenshot/TaskTakeScreenshot.java index 5f8e8d0..8c5051b 100644 --- a/src/mightypork/gamecore/core/plugins/screenshot/TaskTakeScreenshot.java +++ b/src/mightypork/gamecore/core/plugins/screenshot/TaskTakeScreenshot.java @@ -19,10 +19,10 @@ import mightypork.utils.logging.Log; * @author MightyPork */ public class TaskTakeScreenshot implements Runnable { - + private final Screenshot scr; - - + + /** * Take screenshot. Must be called in render thread. */ @@ -30,16 +30,16 @@ public class TaskTakeScreenshot implements Runnable { { scr = App.gfx().takeScreenshot(); } - - + + @Override public void run() { // generate unique filename final File file = getScreenshotFile(); - + Log.f3("Saving screenshot to file: " + file); - + // save to disk try { scr.save(file); @@ -47,8 +47,8 @@ public class TaskTakeScreenshot implements Runnable { Log.e("Failed to save screenshot.", e); } } - - + + /** * @return File to save the screenshot to. */ @@ -57,8 +57,8 @@ public class TaskTakeScreenshot implements Runnable { final String fname = getBaseFilename(); return findFreeFile(fname); } - - + + /** * @return directory for screenshots */ @@ -66,8 +66,8 @@ public class TaskTakeScreenshot implements Runnable { { return WorkDir.getDir("_screenshot_dir"); } - - + + /** * Get base filename for the screenshot, without extension. * @@ -77,8 +77,8 @@ public class TaskTakeScreenshot implements Runnable { { return Support.getTime("yyyy-MM-dd_HH-mm-ss"); } - - + + /** * Find first free filename for the screenshot, by adding -NUMBER after the * base filename and before extension. @@ -97,5 +97,5 @@ public class TaskTakeScreenshot implements Runnable { } return file; } - + } diff --git a/src/mightypork/gamecore/graphics/FullscreenToggleRequest.java b/src/mightypork/gamecore/graphics/FullscreenToggleRequest.java index d23325e..b49a6cf 100644 --- a/src/mightypork/gamecore/graphics/FullscreenToggleRequest.java +++ b/src/mightypork/gamecore/graphics/FullscreenToggleRequest.java @@ -13,7 +13,7 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class FullscreenToggleRequest extends BusEvent { - + @Override protected void handleBy(GraphicsModule handler) { diff --git a/src/mightypork/gamecore/graphics/GraphicsModule.java b/src/mightypork/gamecore/graphics/GraphicsModule.java index 895901d..72d1774 100644 --- a/src/mightypork/gamecore/graphics/GraphicsModule.java +++ b/src/mightypork/gamecore/graphics/GraphicsModule.java @@ -22,23 +22,23 @@ import mightypork.utils.math.timing.FpsMeter; * @author MightyPork */ public abstract class GraphicsModule extends BackendModule { - + /** X axis vector */ protected static final VectConst AXIS_X = Vect.make(1, 0, 0); /** Y axis vector */ protected static final VectConst AXIS_Y = Vect.make(0, 1, 0); /** Z axis vector */ protected static final VectConst AXIS_Z = Vect.make(0, 0, 1); - - + + /** * Set drawing color * * @param color color */ public abstract void setColor(Color color); - - + + /** * Set drawing color, adjust alpha * @@ -46,8 +46,8 @@ public abstract class GraphicsModule extends BackendModule { * @param alpha alpha multiplier */ public abstract void setColor(Color color, double alpha); - - + + /** * Translate by x, y * @@ -55,8 +55,8 @@ public abstract class GraphicsModule extends BackendModule { * @param y y offset */ public abstract void translate(double x, double y); - - + + /** * Translate by x, y, z * @@ -65,24 +65,24 @@ public abstract class GraphicsModule extends BackendModule { * @param z z offset */ public abstract void translate(double x, double y, double z); - - + + /** * Translate by offset vector * * @param offset offset coordinate */ public abstract void translate(Vect offset); - - + + /** * Translate by offset vector, ignore Z * * @param offset offset coordinate */ public abstract void translateXY(Vect offset); - - + + /** * Set scale for translations and coordinates * @@ -90,8 +90,8 @@ public abstract class GraphicsModule extends BackendModule { * @param y y scale */ public abstract void scale(double x, double y); - - + + /** * Set scale for translations and coordinates * @@ -100,72 +100,72 @@ public abstract class GraphicsModule extends BackendModule { * @param z z scale */ public abstract void scale(double x, double y, double z); - - + + /** * Set scale for translations and coordinates * * @param scale vector */ public abstract void scale(Vect scale); - - + + /** * Set scale for translations and coordinates (same value for X and Y scale) * * @param scale scaling factor */ public abstract void scaleXY(double scale); - - + + /** * Set X scale for translations and coordinates * * @param scale scaling factor */ public abstract void scaleX(double scale); - - + + /** * Set Y scale for translations and coordinates * * @param scale scaling factor */ public abstract void scaleY(double scale); - - + + /** * Set Z scale for translations and coordinates * * @param scale scaling factor */ public abstract void scaleZ(double scale); - - + + /** * Rotate coordinate system around X axis * * @param angle rotation (in degrees) */ public abstract void rotateX(double angle); - - + + /** * Rotate coordinate system around Y axis * * @param angle rotation (in degrees) */ public abstract void rotateY(double angle); - - + + /** * Rotate coordinate system around Z axis * * @param angle rotation (in degrees) */ public abstract void rotateZ(double angle); - - + + /** * Rotate coordinate system around given axis * @@ -173,54 +173,54 @@ public abstract class GraphicsModule extends BackendModule { * @param axis rotation axis (unit vector) */ public abstract void rotate(double angle, Vect axis); - - + + /** * Store render state on stack
* This includes pushGeometry and pushColor. */ public abstract void pushState(); - - + + /** * Restore state from stack (must be pushed first)
* This includes popColor and popGeometry. */ public abstract void popState(); - - + + /** * Store current rotation and translation on stack */ public abstract void pushGeometry(); - - + + /** * Restore rotation and translation from stack */ public abstract void popGeometry(); - - + + /** * Store color on stack (so it can later be restored) */ public abstract void pushColor(); - - + + /** * Restore color from stack (must be pushed first) */ public abstract void popColor(); - - + + /** * Render 2D quad with currently set color * * @param rect drawn rect */ public abstract void quad(Rect rect); - - + + /** * Render 2D quad with given color.
* This may change current drawing color. @@ -229,8 +229,8 @@ public abstract class GraphicsModule extends BackendModule { * @param color draw color */ public abstract void quad(Rect rect, Color color); - - + + /** * Render 2D quad with gradient.
* This may change current drawing color. @@ -239,8 +239,8 @@ public abstract class GraphicsModule extends BackendModule { * @param grad gradient */ public abstract void quad(Rect rect, Grad grad); - - + + /** * Render textured quad with current color * @@ -248,8 +248,8 @@ public abstract class GraphicsModule extends BackendModule { * @param txquad texture quad */ public abstract void quad(Rect rect, TxQuad txquad); - - + + /** * Render textured quad with given color * @@ -258,14 +258,14 @@ public abstract class GraphicsModule extends BackendModule { * @param color color tint */ public abstract void quad(Rect rect, TxQuad txquad, Color color); - - + + /** * Setup projection for 2D graphics, using current screen size */ public abstract void setupProjection(); - - + + /** * Get backend-flavoured deferred PNG texture. * @@ -273,8 +273,8 @@ public abstract class GraphicsModule extends BackendModule { * @return the deferred font */ public abstract DeferredTexture createTextureResource(String path); - - + + /** * Get backend-flavoured deferred TTF font. * @@ -282,8 +282,8 @@ public abstract class GraphicsModule extends BackendModule { * @return the deferred font */ public abstract DeferredFont createFontResource(String path); - - + + /** * Get backend-flavoured deferred TTF font. * @@ -298,11 +298,11 @@ public abstract class GraphicsModule extends BackendModule { final DeferredFont font = createFontResource(path); font.setChars(chars); font.setSize(size); - + return font; } - - + + /** * Set target fps (for syncing in endFrame() call).
* With vsync enabled, the target fps may not be met. @@ -310,8 +310,8 @@ public abstract class GraphicsModule extends BackendModule { * @param fps requested fps */ public abstract void setTargetFps(int fps); - - + + /** * Set fullscreen. The fullscreen state will be changed when possible (eg. * at the end of the current frame) and a {@link ViewportChangeEvent} will @@ -320,14 +320,14 @@ public abstract class GraphicsModule extends BackendModule { * @param fs true for fullscreen */ public abstract void setFullscreen(boolean fs); - - + + /** * Request fullscreen toggle. See setFullscreen() for more info) */ public abstract void switchFullscreen(); - - + + /** * Get fullscreen state (note that methods changing fullscreen may not have * immediate effect, so this method may report the old state if the @@ -336,8 +336,8 @@ public abstract class GraphicsModule extends BackendModule { * @return is fullscreen */ public abstract boolean isFullscreen(); - - + + /** * Take screenshot (expensive processing should be done in separate thread * when screenshot is saved).
@@ -346,20 +346,20 @@ public abstract class GraphicsModule extends BackendModule { * @return screenshot object */ public abstract Screenshot takeScreenshot(); - - + + /** * Start a render frame - clear buffers, prepare rendering context etc. */ public abstract void beginFrame(); - - + + /** * End a render frame: flip buffers, sync to fps... */ public abstract void endFrame(); - - + + /** * Set display dimensions * @@ -367,76 +367,76 @@ public abstract class GraphicsModule extends BackendModule { * @param height display height (pixels) */ public abstract void setSize(int width, int height); - - + + /** * Set window titlebar text * * @param title titlebar text */ public abstract void setTitle(String title); - - + + /** * Enable or disable VSync * * @param vsync true for vsync enabled */ public abstract void setVSync(boolean vsync); - - + + /** * Set window resizable / fixed * * @param resizable true for resizable */ public abstract void setResizable(boolean resizable); - - + + /** * Get screen rect. Should always return the same Rect instance. * * @return the rect */ public abstract Rect getRect(); - - + + /** * Get current FPS (eg. measured by a {@link FpsMeter}) * * @return current FPS */ public abstract long getFps(); - - + + /** * Get screen center. Should always return the same {@link Vect} instance. * * @return screen center. */ public abstract Vect getCenter(); - - + + /** * Get screen size. Should always return the same {@link Vect} instance. * * @return size */ public abstract Vect getSize(); - - + + /** * @return screen width */ public abstract int getWidth(); - - + + /** * @return screen height */ public abstract int getHeight(); - - + + /** * Create the display (window) based on current settings. */ diff --git a/src/mightypork/gamecore/graphics/Renderable.java b/src/mightypork/gamecore/graphics/Renderable.java index c3890a5..3a967d4 100644 --- a/src/mightypork/gamecore/graphics/Renderable.java +++ b/src/mightypork/gamecore/graphics/Renderable.java @@ -7,10 +7,10 @@ package mightypork.gamecore.graphics; * @author Ondřej Hruška (MightyPork) */ public interface Renderable { - + /** * Render on screen. */ void render(); - + } diff --git a/src/mightypork/gamecore/graphics/Screenshot.java b/src/mightypork/gamecore/graphics/Screenshot.java index 475d774..f00170e 100644 --- a/src/mightypork/gamecore/graphics/Screenshot.java +++ b/src/mightypork/gamecore/graphics/Screenshot.java @@ -22,7 +22,7 @@ import java.io.IOException; * @author MightyPork */ public interface Screenshot { - + /** * Process byte buffer and write image to a file.
* Image can be cached for future save. diff --git a/src/mightypork/gamecore/graphics/fonts/DeferredFont.java b/src/mightypork/gamecore/graphics/fonts/DeferredFont.java index edab06b..c5aadfc 100644 --- a/src/mightypork/gamecore/graphics/fonts/DeferredFont.java +++ b/src/mightypork/gamecore/graphics/fonts/DeferredFont.java @@ -11,42 +11,42 @@ import mightypork.gamecore.resources.BaseDeferredResource; * @author Ondřej Hruška (MightyPork) */ public abstract class DeferredFont extends BaseDeferredResource implements IFont { - + /** * 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 * cached with this size. */ protected double size = 12; - + /** Requested font style. If not applicable, fall back to PLAIN */ protected FontStyle style = FontStyle.PLAIN; - + /** * Chars that are required to be loaded in the font. A space glyph must be * also added when loading. */ protected String chars = Glyphs.basic; - + /** Requested filtering mode */ protected FilterMode filter = FilterMode.NEAREST; - + /** Whether to use anti-aliasing for the font. */ protected boolean antialias = false; - + /** * Ratio of the font to discard at the top (how much of the glyphs height is * blank from top) */ protected double discardTop = 0; - + /** * Ratio of the font to discard at the bottom (how much of the glyphs height * is blank from bottom) */ protected double discardBottom = 0; - - + + /** * Make a font from resource * @@ -56,8 +56,8 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { super(resource); } - - + + /** * Set font size. If the font is backed by a texture, this is the size at * which the font is rendered to the texture. For bitmap fonts, this should @@ -69,8 +69,8 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { this.size = size; } - - + + /** * Set desired font style * @@ -80,8 +80,8 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { this.style = style; } - - + + /** * Set what chars are to be loaded. The space glyph will be loaded always. * @@ -91,8 +91,8 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { this.chars = chars; } - - + + /** * Set texture filtering mode. For bitmap fonts, set to NEAREST. * @@ -102,8 +102,8 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { this.filter = filter; } - - + + /** * Set whether to use antialiasing. * @@ -113,27 +113,27 @@ public abstract class DeferredFont extends BaseDeferredResource implements IFont { this.antialias = antialias; } - - + + @Override public final void setDiscardRatio(double top, double bottom) { discardTop = top; discardBottom = bottom; } - - + + @Override public final double getTopDiscardRatio() { return discardTop; } - - + + @Override public final double getBottomDiscardRatio() { return discardBottom; } - + } diff --git a/src/mightypork/gamecore/graphics/fonts/FontRegistry.java b/src/mightypork/gamecore/graphics/fonts/FontRegistry.java index 2d7f31c..7b81f55 100644 --- a/src/mightypork/gamecore/graphics/fonts/FontRegistry.java +++ b/src/mightypork/gamecore/graphics/fonts/FontRegistry.java @@ -14,11 +14,11 @@ import mightypork.utils.eventbus.clients.BusNode; * @author Ondřej Hruška (MightyPork) */ public class FontRegistry extends BusNode { - + private final HashMap fonts = new HashMap<>(); private final HashMap 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,8 +43,8 @@ public class FontRegistry extends BusNode { { fonts.put(key, font); } - - + + /** * 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 @@ -58,8 +58,8 @@ public class FontRegistry extends BusNode { { aliases.put(alias_key, font_key); } - - + + /** * Get a loaded {@link IFont} * @@ -69,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; } - + } diff --git a/src/mightypork/gamecore/graphics/fonts/FontRenderer.java b/src/mightypork/gamecore/graphics/fonts/FontRenderer.java index 24b84d0..d3fa1ad 100644 --- a/src/mightypork/gamecore/graphics/fonts/FontRenderer.java +++ b/src/mightypork/gamecore/graphics/fonts/FontRenderer.java @@ -15,12 +15,12 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public class FontRenderer { - + private IFont font; - + private Color color; - - + + /** * @param font used font */ @@ -28,8 +28,8 @@ public class FontRenderer { { this(font, RGB.WHITE); } - - + + /** * @param font used font * @param color drawing color @@ -39,8 +39,8 @@ public class FontRenderer { this.font = font; this.color = color; } - - + + /** * Get region needed to draw text at size * @@ -52,8 +52,8 @@ public class FontRenderer { { return font.getNeededSpace(text).mul(getScale(height)); } - - + + /** * Get width needed to draw text at size * @@ -65,14 +65,14 @@ public class FontRenderer { { return getNeededSpace(text, height).x(); } - - + + private double getScale(double height) { return height / font.getLineHeight(); } - - + + /** * Change drawing font * @@ -82,8 +82,8 @@ public class FontRenderer { { this.font = font; } - - + + /** * Set drawing color * @@ -93,8 +93,8 @@ public class FontRenderer { { this.color = color; } - - + + /** * Draw on screen * @@ -106,18 +106,18 @@ public class FontRenderer { public void draw(String text, Vect pos, double height, Color color) { App.gfx().pushGeometry(); - + final double sc = getScale(height); - + App.gfx().translate(pos.x(), pos.y()); App.gfx().scaleXY(sc); - + font.draw(text, color); - + App.gfx().popGeometry(); } - - + + /** * Draw on screen * @@ -130,8 +130,8 @@ public class FontRenderer { { this.draw(text, bounds, align, this.color); } - - + + /** * Draw on screen * @@ -144,26 +144,26 @@ public class FontRenderer { public void draw(String text, Rect bounds, AlignX align, Color color) { Vect start; - + switch (align) { case LEFT: start = bounds.topLeft(); break; - + case CENTER: start = bounds.topCenter(); break; - + case RIGHT: default: start = bounds.topRight(); break; } - + draw(text, start, bounds.height().value(), align, color); } - - + + /** * Draw on screen * @@ -176,8 +176,8 @@ public class FontRenderer { { draw(text, pos, height, align, this.color); } - - + + /** * Draw on screen * @@ -189,27 +189,27 @@ public class FontRenderer { */ public void draw(String text, Vect pos, double height, AlignX align, Color color) { - + final double w = getWidth(text, height); - + Vect start; - + switch (align) { case LEFT: start = pos; break; - + case CENTER: start = pos.sub(w / 2D, 0); break; - + case RIGHT: default: start = pos.sub(w, 0); break; } - + draw(text, start, height, color); } - + } diff --git a/src/mightypork/gamecore/graphics/fonts/FontStyle.java b/src/mightypork/gamecore/graphics/fonts/FontStyle.java index 007bef5..2b5630d 100644 --- a/src/mightypork/gamecore/graphics/fonts/FontStyle.java +++ b/src/mightypork/gamecore/graphics/fonts/FontStyle.java @@ -14,11 +14,11 @@ public enum FontStyle ITALIC(2), /** Bond and italic together */ BOLD_ITALIC(1 + 2); - + /** Number associated with the style */ public int numval; - - + + /** * Font style * diff --git a/src/mightypork/gamecore/graphics/fonts/Glyphs.java b/src/mightypork/gamecore/graphics/fonts/Glyphs.java index 9820767..6646381 100644 --- a/src/mightypork/gamecore/graphics/fonts/Glyphs.java +++ b/src/mightypork/gamecore/graphics/fonts/Glyphs.java @@ -8,35 +8,35 @@ package mightypork.gamecore.graphics.fonts; * @author Ondřej Hruška (MightyPork) */ public class Glyphs { - + /** A-Z a-z */ public static final String latin = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - + /** Extra variants of latin glyphs */ public static final String latin_extra = "ŒÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜŸÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĚŠČŘŽŤŇĎŮěščřžťňďůŁłđ"; - + /** 0-9 */ public static final String numbers = "0123456789"; - + /** Commonly used punctuation symbols */ public static final String punctuation = ".-,.?!:;\"'"; - + /** Less common punctuation symbols */ public static final String punctuation_extra = "()¿¡»«›‹“”‘’„…"; - + /** Commonly used symbols (that are not included in punctuation) */ public static final String symbols = "[]{}#$%&§*+/<=>@\\^_|~°"; - + /** Less common symbols */ public static final String symbols_extra = "¥€£¢`ƒ†‡ˆ‰•¤¦¨ªº¹²³¬­¯±´µ¶·¸¼½¾×÷™©­®→↓←↑"; - + /** Latin, numbers, punctuation and symbols */ public static final String basic = latin + numbers + punctuation + symbols; - + /** Extra glyphs to accompany "basic" */ public static final String extra = latin_extra + punctuation_extra + symbols_extra; - + /** Basic + Extra */ public static final String all = basic + extra; - + } diff --git a/src/mightypork/gamecore/graphics/fonts/IFont.java b/src/mightypork/gamecore/graphics/fonts/IFont.java index 835e8d1..9a78765 100644 --- a/src/mightypork/gamecore/graphics/fonts/IFont.java +++ b/src/mightypork/gamecore/graphics/fonts/IFont.java @@ -11,7 +11,7 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public interface IFont { - + /** * Draw without scaling at (0, 0) in given color. * @@ -19,8 +19,8 @@ public interface IFont { * @param color draw color */ void draw(String text, Color color); - - + + /** * Get suize needed to render give string * @@ -28,27 +28,27 @@ public interface IFont { * @return coord (width, height) */ Vect getNeededSpace(String text); - - + + /** * @return font height */ int getLineHeight(); - - + + /** * @param text texted text * @return space needed */ int getWidth(String text); - - + + /** * @return specified font size */ int getFontSize(); - - + + /** * Set what vertical ratio of the font size is blank and should be cut off * when rendering @@ -57,16 +57,16 @@ public interface IFont { * @param bottom bottom ratio (0-1) */ void setDiscardRatio(double top, double bottom); - - + + /** * Get top discard ratio (blank unused space) * * @return ratio */ double getTopDiscardRatio(); - - + + /** * Get bottom discard ratio (blank unused space) * diff --git a/src/mightypork/gamecore/graphics/textures/DeferredTexture.java b/src/mightypork/gamecore/graphics/textures/DeferredTexture.java index 38a184e..f5441f6 100644 --- a/src/mightypork/gamecore/graphics/textures/DeferredTexture.java +++ b/src/mightypork/gamecore/graphics/textures/DeferredTexture.java @@ -15,13 +15,13 @@ import mightypork.utils.math.constraints.rect.Rect; @Alias(name = "Texture") @MustLoadInRenderingContext public abstract class DeferredTexture extends BaseDeferredResource implements ITexture { - + /** Used filtering mode */ protected FilterMode filter = FilterMode.NEAREST; /** Used wrapping mode */ protected WrapMode wrap = WrapMode.CLAMP; - - + + /** * @param resourcePath resource path */ @@ -29,29 +29,29 @@ public abstract class DeferredTexture extends BaseDeferredResource implements IT { super(resourcePath); } - - + + @Override public TxQuad makeQuad(Rect uvs) { return new TxQuad(this, uvs); } - - + + @Override public void setFilter(FilterMode filterMin) { this.filter = filterMin; } - - + + @Override public void setWrap(WrapMode wrapping) { this.wrap = wrapping; } - - + + @Override public QuadGrid grid(int x, int y) { diff --git a/src/mightypork/gamecore/graphics/textures/ITexture.java b/src/mightypork/gamecore/graphics/textures/ITexture.java index 63ef49f..d862319 100644 --- a/src/mightypork/gamecore/graphics/textures/ITexture.java +++ b/src/mightypork/gamecore/graphics/textures/ITexture.java @@ -11,21 +11,21 @@ import mightypork.utils.math.constraints.rect.Rect; * @author Ondřej Hruška (MightyPork) */ public interface ITexture extends Destroyable { - + /** * Set filter for scaling * * @param filter filter */ void setFilter(FilterMode filter); - - + + /** * @param wrapping wrap mode */ void setWrap(WrapMode wrapping); - - + + /** * Get a quad from this texture of given position/size * @@ -33,8 +33,8 @@ public interface ITexture extends Destroyable { * @return the quad */ TxQuad makeQuad(Rect uvs); - - + + /** * Get a grid for given number of tiles * @@ -43,20 +43,20 @@ public interface ITexture extends Destroyable { * @return grid */ QuadGrid grid(int x, int y); - - + + /** * @return source image width (corresponding to width01) */ int getImageWidth(); - - + + /** * @return source image height (corresponding to height01) */ int getImageHeight(); - - + + /** * @return true if the image is RGBA */ diff --git a/src/mightypork/gamecore/graphics/textures/QuadGrid.java b/src/mightypork/gamecore/graphics/textures/QuadGrid.java index aea47ce..bcd76a3 100644 --- a/src/mightypork/gamecore/graphics/textures/QuadGrid.java +++ b/src/mightypork/gamecore/graphics/textures/QuadGrid.java @@ -11,14 +11,14 @@ import mightypork.utils.math.constraints.rect.Rect; * @author Ondřej Hruška (MightyPork) */ public class QuadGrid { - + private final ITexture tx; private final int txHeight; private final int txWidth; private final double tileW; private final double tileH; - - + + /** * @param tx backing texture * @param tilesX number of tile columns @@ -32,8 +32,8 @@ public class QuadGrid { this.tileW = 1D / tilesX; this.tileH = 1D / tilesY; } - - + + /** * Make square quad at given coords (one grid cell) * @@ -46,11 +46,11 @@ public class QuadGrid { if (x < 0 || x >= txWidth || y < 0 || y >= txHeight) { throw new IndexOutOfBoundsException("Requested invalid txquad coordinates."); } - + return makeQuad(x, y, 1, 1); } - - + + /** * Make square quad at given coords, with arbitrary size. Coordinates are * multiples of cell size. @@ -66,15 +66,15 @@ public class QuadGrid { if (x < 0 || x >= txWidth || y < 0 || y >= txHeight) { throw new IndexOutOfBoundsException("Requested invalid txquad coordinates."); } - + if (x + width > txWidth || y + height > txHeight) { throw new IndexOutOfBoundsException("Requested invalid txquad size (would go beyond texture size)."); } - + return tx.makeQuad(Rect.make(tileW * x, tileH * y, tileW * width, tileH * height)); } - - + + /** * Make a sheet. * @@ -89,11 +89,11 @@ public class QuadGrid { if (x < 0 || x >= txWidth || y < 0 || y >= txHeight) { throw new IndexOutOfBoundsException("Requested invalid txquad coordinates."); } - + if (x + width > txWidth || y + height > txHeight) { throw new IndexOutOfBoundsException("Requested invalid txsheet size (would go beyond texture size)."); } - + return makeQuad(x, y).makeSheet(width, height); } } diff --git a/src/mightypork/gamecore/graphics/textures/TextureRegistry.java b/src/mightypork/gamecore/graphics/textures/TextureRegistry.java index 26dbcd9..46f8d95 100644 --- a/src/mightypork/gamecore/graphics/textures/TextureRegistry.java +++ b/src/mightypork/gamecore/graphics/textures/TextureRegistry.java @@ -17,11 +17,11 @@ import mightypork.utils.math.constraints.rect.Rect; * @author Ondřej Hruška (MightyPork) */ public class TextureRegistry { - + private final Map textures = new HashMap<>(); private final Map sheets = new HashMap<>(); - - + + /** * Load a texture from resource. * @@ -35,13 +35,13 @@ public class TextureRegistry { final DeferredTexture texture = App.gfx().createTextureResource(resourcePath); texture.setFilter(filter); texture.setWrap(wrap); - - App.bus().send(new ResourceLoadRequest(texture)); + App.bus().send(new ResourceLoadRequest(texture)); + return texture; } - - + + /** * Load a texture from resource; if key is not null, the texture will be * added to the bank. @@ -55,18 +55,18 @@ public class TextureRegistry { public ITexture addTexture(String key, String resourcePath, FilterMode filter, WrapMode wrap) { if (key != null) if (textures.containsKey(key)) throw new KeyAlreadyExistsException(); - + final ITexture texture = loadTexture(resourcePath, filter, wrap); - + if (key != null) { textures.put(key, texture); add(key, texture.makeQuad(Rect.ONE)); } - + return texture; } - - + + /** * Add already created quad to the quad registry * @@ -76,11 +76,11 @@ public class TextureRegistry { public void add(String quadKey, TxQuad quad) { if (sheets.containsKey(quadKey)) throw new KeyAlreadyExistsException(); - + sheets.put(quadKey, quad.makeSheet(1, 1)); } - - + + /** * Add an already created sheet * @@ -90,11 +90,11 @@ public class TextureRegistry { public void add(String sheetKey, TxSheet sheet) { if (sheets.containsKey(sheetKey)) throw new KeyAlreadyExistsException(); - + sheets.put(sheetKey, sheet); } - - + + /** * Get a {@link TxQuad} for key; if it was added as sheet, the first quad * ofthe sheet is returned. @@ -106,8 +106,8 @@ public class TextureRegistry { { return getSheet(key).getQuad(0); // get the first } - - + + /** * Get a loaded {@link ITexture} * @@ -117,13 +117,13 @@ public class TextureRegistry { public ITexture getTexture(String key) { final ITexture tx = textures.get(key); - + if (tx == null) throw new RuntimeException("There's no texture called \"" + key + "\"!"); - + return tx; } - - + + /** * Get a {@link TxSheet} for key * @@ -133,12 +133,12 @@ public class TextureRegistry { public TxSheet getSheet(String key) { final TxSheet sh = sheets.get(key); - + if (sh == null) { throw new RuntimeException("There's no sheet called \"" + key + "\"!"); } - + return sh; } - + } diff --git a/src/mightypork/gamecore/graphics/textures/TxQuad.java b/src/mightypork/gamecore/graphics/textures/TxQuad.java index 3d14af6..ef042f1 100644 --- a/src/mightypork/gamecore/graphics/textures/TxQuad.java +++ b/src/mightypork/gamecore/graphics/textures/TxQuad.java @@ -11,16 +11,16 @@ import mightypork.utils.math.constraints.rect.RectConst; * @author Ondřej Hruška (MightyPork) */ public class TxQuad { - + /** The texture */ public final ITexture tx; /** Coords in texture (0-1) */ public final RectConst uvs; - + private boolean flipX; private boolean flipY; - - + + /** * TxQuad from origin and size in pixels * @@ -35,11 +35,11 @@ public class TxQuad { { final double w = tx.getImageWidth(); final double h = tx.getImageHeight(); - + return fromSize(tx, xPx / w, yPx / h, widthPx / w, heightPx / h); } - - + + /** * TxQuad from origin and size 0-1 * @@ -54,8 +54,8 @@ public class TxQuad { { return new TxQuad(tx, x1, y1, x1 + width, y1 + height); } - - + + /** * Make of coords * @@ -69,8 +69,8 @@ public class TxQuad { { this(tx, Rect.make(x1, y1, x2, y2)); } - - + + /** * @param tx Texture * @param uvs Rect of texture UVs (0-1); will be frozen. @@ -80,8 +80,8 @@ public class TxQuad { this.tx = tx; this.uvs = uvs.freeze(); } - - + + /** * Clone another * @@ -94,8 +94,8 @@ public class TxQuad { this.flipX = txQuad.flipX; this.flipY = txQuad.flipY; } - - + + /** * Get copy * @@ -105,8 +105,8 @@ public class TxQuad { { return new TxQuad(this); } - - + + /** * Make a sheet starting with this quad, spannign to right and down. * @@ -118,8 +118,8 @@ public class TxQuad { { return new TxSheet(this, (int) Math.round(width), (int) Math.round(height)); } - - + + /** * @return copy flipped X */ @@ -129,8 +129,8 @@ public class TxQuad { copy.flipX ^= true; return copy; } - - + + /** * @return copy flipped Y */ @@ -140,8 +140,8 @@ public class TxQuad { copy.flipY ^= true; return copy; } - - + + /** * @return true if the quad is to be rendered flipped vertically */ @@ -149,8 +149,8 @@ public class TxQuad { { return flipY; } - - + + /** * @return true if the quad is to be rendered flipped horizontally */ @@ -158,8 +158,8 @@ public class TxQuad { { return flipX; } - - + + /** * Use the same flit/other attributes as the original txQuad * diff --git a/src/mightypork/gamecore/graphics/textures/TxSheet.java b/src/mightypork/gamecore/graphics/textures/TxSheet.java index 00846f5..0017739 100644 --- a/src/mightypork/gamecore/graphics/textures/TxSheet.java +++ b/src/mightypork/gamecore/graphics/textures/TxSheet.java @@ -13,16 +13,16 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public class TxSheet { - + private final TxQuad original; private final TxQuad[] sprites; private final int width; - + private final Random rand = new Random(); private final Random randForSeed = new Random(); private final int count; - - + + /** * Make a sprite sheet * @@ -35,11 +35,11 @@ public class TxSheet { this.original = tx; this.width = width; this.count = width * height; - + this.sprites = new TxQuad[count]; } - - + + /** * @return number of quads */ @@ -47,8 +47,8 @@ public class TxSheet { { return count; } - - + + /** * Get a quad based on ratio 0-1 (0: first, 1: last) * @@ -59,8 +59,8 @@ public class TxSheet { { return getQuad((int) Math.round((count - 1) * ratio)); } - - + + /** * Get quad of index * @@ -73,25 +73,25 @@ public class TxSheet { Log.w("Index out of bounds: " + index + ", allowed: 0.." + count); index = index % count; } - + // lazy - init only when needed if (sprites[index] == null) { final int x = index % width; final int y = index / width; - + final double origW = original.uvs.width().value(); final double origH = original.uvs.height().value(); - + final TxQuad txq = new TxQuad(original.tx, original.uvs.move(x * origW, y * origH)); txq.dupeAttrs(original); - + sprites[index] = txq; } - + return sprites[index]; } - - + + /** * Get entirely random TxQuad from this sheet * @@ -101,8 +101,8 @@ public class TxSheet { { return getQuad(rand.nextInt(count)); } - - + + /** * Get random TxQuad from this sheet * @@ -114,8 +114,8 @@ public class TxSheet { randForSeed.setSeed(seed); return getQuad(randForSeed.nextInt(count)); } - - + + /** * Get random TxQuad from this sheet * diff --git a/src/mightypork/gamecore/gui/Action.java b/src/mightypork/gamecore/gui/Action.java index 464c4b1..a9edad2 100644 --- a/src/mightypork/gamecore/gui/Action.java +++ b/src/mightypork/gamecore/gui/Action.java @@ -10,10 +10,10 @@ import mightypork.utils.interfaces.Enableable; * @author Ondřej Hruška (MightyPork) */ public abstract class Action implements Runnable, Enableable { - + private boolean enabled = true; - - + + /** * Enable the action * @@ -24,8 +24,8 @@ public abstract class Action implements Runnable, Enableable { { this.enabled = enable; } - - + + /** * @return true if this action is enabled. */ @@ -34,8 +34,8 @@ public abstract class Action implements Runnable, Enableable { { return enabled; } - - + + /** * Run the action, if it's enabled. */ @@ -44,11 +44,11 @@ public abstract class Action implements Runnable, Enableable { { if (enabled) execute(); } - - + + /** * Do the work. */ protected abstract void execute(); - + } diff --git a/src/mightypork/gamecore/gui/ActionGroup.java b/src/mightypork/gamecore/gui/ActionGroup.java index 78b524c..6544423 100644 --- a/src/mightypork/gamecore/gui/ActionGroup.java +++ b/src/mightypork/gamecore/gui/ActionGroup.java @@ -14,12 +14,12 @@ import mightypork.utils.interfaces.Enableable; * @author Ondřej Hruška (MightyPork) */ public class ActionGroup implements Enableable { - + private boolean enabled = true; - + private final Set groupMembers = new HashSet<>(); - - + + @Override public void setEnabled(boolean yes) { @@ -27,15 +27,15 @@ public class ActionGroup implements Enableable { for (final Enableable e : groupMembers) e.setEnabled(yes); } - - + + @Override public boolean isEnabled() { return enabled; } - - + + /** * Add an {@link Enableable} to the group * @@ -45,8 +45,8 @@ public class ActionGroup implements Enableable { { groupMembers.add(member); } - - + + /** * Remove a group member * @@ -56,5 +56,5 @@ public class ActionGroup implements Enableable { { groupMembers.remove(member); } - + } diff --git a/src/mightypork/gamecore/gui/HasAction.java b/src/mightypork/gamecore/gui/HasAction.java index fdf0af4..d8e156d 100644 --- a/src/mightypork/gamecore/gui/HasAction.java +++ b/src/mightypork/gamecore/gui/HasAction.java @@ -7,7 +7,7 @@ package mightypork.gamecore.gui; * @author Ondřej Hruška (MightyPork) */ public interface HasAction { - + /** * Assign an action * diff --git a/src/mightypork/gamecore/gui/components/BaseComponent.java b/src/mightypork/gamecore/gui/components/BaseComponent.java index fa0f76a..628a6bf 100644 --- a/src/mightypork/gamecore/gui/components/BaseComponent.java +++ b/src/mightypork/gamecore/gui/components/BaseComponent.java @@ -5,7 +5,7 @@ import mightypork.gamecore.core.App; import mightypork.gamecore.graphics.Renderable; import mightypork.gamecore.gui.events.LayoutChangeEvent; import mightypork.gamecore.gui.events.LayoutChangeListener; -import mightypork.utils.Support; +import mightypork.utils.Str; import mightypork.utils.annotations.Stub; import mightypork.utils.logging.Log; import mightypork.utils.math.color.Color; @@ -23,15 +23,15 @@ import mightypork.utils.math.constraints.rect.proxy.RectProxy; * @author Ondřej Hruška (MightyPork) */ public abstract class BaseComponent extends AbstractRectCache implements Component, LayoutChangeListener { - + private Rect source; private boolean visible = true; private boolean enabled = true; private int indirectDisableLevel = 0; - + private Num alphaMul = Num.ONE; - - + + /** * Create a base component.
* By default, disable caching to avoid problems with updating. Caching can @@ -41,113 +41,113 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone { enableCaching(false); } - - + + @Override public void setRect(RectBound rect) { this.source = new RectProxy(rect); } - - + + @Override public final boolean isVisible() { return visible; } - - + + @Override public final void setVisible(boolean visible) { this.visible = visible; } - - + + @Override public final Rect getCacheSource() { return source.round(); // round to avoid visual artifacts in fonts and such } - - + + @Override public final void render() { if (!isVisible()) return; - + Color.pushAlpha(alphaMul); renderComponent(); Color.popAlpha(); } - - + + @Override public final void onLayoutChanged() { try { poll(); } catch (final NullPointerException e) { - Log.e("Component is missing a bounding rect, at: " + Support.str(getClass())); + Log.e("Component is missing a bounding rect, at: " + Str.val(getClass())); } } - - + + @Override public final void onConstraintChanged() { updateLayout(); } - - + + @Override public final boolean isMouseOver() { return App.input().getMousePos().isInside(this); } - - + + /** * Draw the component (it's visible) */ protected abstract void renderComponent(); - - + + @Override @Stub public void updateLayout() { } - - + + @Override public void setEnabled(boolean yes) { enabled = yes; } - - + + @Override public boolean isEnabled() { return enabled && isIndirectlyEnabled(); } - - + + @Override public final void setAlpha(Num alpha) { this.alphaMul = alpha; } - - + + @Override public final void setAlpha(double alpha) { this.alphaMul = Num.make(alpha); } - - + + @Override public void setIndirectlyEnabled(boolean yes) { @@ -157,15 +157,15 @@ public abstract class BaseComponent extends AbstractRectCache implements Compone if (indirectDisableLevel > 0) indirectDisableLevel--; } } - - + + @Override public boolean isIndirectlyEnabled() { return indirectDisableLevel == 0; } - - + + @Override public boolean isDirectlyEnabled() { diff --git a/src/mightypork/gamecore/gui/components/Component.java b/src/mightypork/gamecore/gui/components/Component.java index 755e6da..8468460 100644 --- a/src/mightypork/gamecore/gui/components/Component.java +++ b/src/mightypork/gamecore/gui/components/Component.java @@ -12,43 +12,43 @@ import mightypork.utils.math.constraints.num.Num; * @author Ondřej Hruška (MightyPork) */ public interface Component extends Enableable, Hideable, PluggableRenderable { - + /** * Render the component, if it is visible. */ @Override void render(); - - + + /** * The bounding rect was changed. The component should now update any cached * constraints derived from it. */ void updateLayout(); - - + + /** * @return true if mouse is currently over the component */ boolean isMouseOver(); - - + + /** * Set alpha multiplier for this and nested components * * @param alpha alpha multiplier (dynamic value) */ void setAlpha(Num alpha); - - + + /** * Set alpha multiplier for this and nested components * * @param alpha alpha multiplier (constant value) */ void setAlpha(double alpha); - - + + /** * Indirectly enable / disable, used for nested hierarchies.
* When component is twice indirectly disabled, it needs to be twice @@ -57,8 +57,8 @@ public interface Component extends Enableable, Hideable, PluggableRenderable { * @param yes */ void setIndirectlyEnabled(boolean yes); - - + + /** * Check if the compionent is not indirectly disabled. May still be directly * disabled. @@ -66,8 +66,8 @@ public interface Component extends Enableable, Hideable, PluggableRenderable { * @return indirectly enabled */ boolean isIndirectlyEnabled(); - - + + /** * Check if the component is directly enabled (set by setEnabled()). May * still be indirectly disabled. @@ -75,16 +75,16 @@ public interface Component extends Enableable, Hideable, PluggableRenderable { * @return directly enabled */ boolean isDirectlyEnabled(); - - + + /** * Set directly enabled (must be both directly and indirectly enabled to be * enabled completely) */ @Override public void setEnabled(boolean yes); - - + + /** * Check if the component is both directly and indirectly enabled * diff --git a/src/mightypork/gamecore/gui/components/DynamicWidthComponent.java b/src/mightypork/gamecore/gui/components/DynamicWidthComponent.java index b0b0db1..6a61e67 100644 --- a/src/mightypork/gamecore/gui/components/DynamicWidthComponent.java +++ b/src/mightypork/gamecore/gui/components/DynamicWidthComponent.java @@ -8,7 +8,7 @@ package mightypork.gamecore.gui.components; * @author Ondřej Hruška (MightyPork) */ public interface DynamicWidthComponent extends Component { - + /** * Get current width, if the element has specified height * diff --git a/src/mightypork/gamecore/gui/components/InputComponent.java b/src/mightypork/gamecore/gui/components/InputComponent.java index 71e5f76..e44784d 100644 --- a/src/mightypork/gamecore/gui/components/InputComponent.java +++ b/src/mightypork/gamecore/gui/components/InputComponent.java @@ -10,7 +10,7 @@ import mightypork.utils.eventbus.clients.ToggleableClient; * @author Ondřej Hruška (MightyPork) */ public abstract class InputComponent extends BaseComponent implements ToggleableClient { - + @Override public boolean isListening() { diff --git a/src/mightypork/gamecore/gui/components/LayoutComponent.java b/src/mightypork/gamecore/gui/components/LayoutComponent.java index 0b66007..51bbb60 100644 --- a/src/mightypork/gamecore/gui/components/LayoutComponent.java +++ b/src/mightypork/gamecore/gui/components/LayoutComponent.java @@ -15,11 +15,11 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public abstract class LayoutComponent extends BaseComponent implements ClientHub { - + private final DelegatingList clientList; final LinkedList components = new LinkedList<>(); - - + + /** * Layout component with the given context (container) * @@ -31,8 +31,8 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub setRect(context); enableCaching(true); // layout is typically updated only when screen resizes. } - - + + /** * Component without context (can be assigned a context using * setRect()) @@ -41,56 +41,56 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub { this(null); } - - + + @Override public Collection getChildClients() { return clientList; } - - + + @Override public boolean doesDelegate() { return clientList.doesDelegate(); } - - + + @Override public boolean isListening() { return clientList.isListening(); } - - + + @Override public void addChildClient(Object client) { clientList.add(client); } - - + + @Override public void removeChildClient(Object client) { clientList.remove(client); } - - + + @Override public void setEnabled(boolean yes) { if (isDirectlyEnabled() != yes) { super.setEnabled(yes); - + for (final Component c : components) { c.setIndirectlyEnabled(yes); } } } - - + + /** * Connect to bus and add to element list * @@ -102,12 +102,12 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub if (component == this) { throw new IllegalArgumentException("Uruboros. (infinite recursion evaded)"); } - + components.add(component); addChildClient(component); } - - + + @Override public void renderComponent() { @@ -115,8 +115,8 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub cmp.render(); } } - - + + @Override public void updateLayout() { @@ -124,13 +124,13 @@ public abstract class LayoutComponent extends BaseComponent implements ClientHub cmp.updateLayout(); } } - - + + @Override public void setIndirectlyEnabled(boolean yes) { super.setIndirectlyEnabled(yes); - + for (final Component cmp : components) { cmp.setIndirectlyEnabled(yes); } diff --git a/src/mightypork/gamecore/gui/components/LinearComponent.java b/src/mightypork/gamecore/gui/components/LinearComponent.java index 153f963..debc634 100644 --- a/src/mightypork/gamecore/gui/components/LinearComponent.java +++ b/src/mightypork/gamecore/gui/components/LinearComponent.java @@ -15,36 +15,36 @@ import mightypork.utils.math.constraints.vect.proxy.VectAdapter; * @author Ondřej Hruška (MightyPork) */ public abstract class LinearComponent extends BaseComponent implements DynamicWidthComponent { - + private final Rect rect = new Rect() { - + @Override public Vect size() { return new Vect() { - + @Override public double x() { return computeWidth(y()); } - - + + @Override public double y() { return height.value(); } - + }; } - - + + @Override public Vect origin() { return new VectAdapter() { - + @Override protected Vect getSource() { @@ -53,11 +53,11 @@ public abstract class LinearComponent extends BaseComponent implements DynamicWi }; } }; - + private Vect origin; private Num height; - - + + /** * Create a linear component */ @@ -65,15 +65,15 @@ public abstract class LinearComponent extends BaseComponent implements DynamicWi { super.setRect(rect); } - - + + @Override public void setRect(RectBound rect) { throw new RuntimeException("Cannot assign a rect to a linear component. Set origin and height instead."); } - - + + /** * Set component's height * @@ -83,8 +83,8 @@ public abstract class LinearComponent extends BaseComponent implements DynamicWi { this.height = height; } - - + + /** * Set component's origin * diff --git a/src/mightypork/gamecore/gui/components/PluggableRenderable.java b/src/mightypork/gamecore/gui/components/PluggableRenderable.java index fb55253..97fa698 100644 --- a/src/mightypork/gamecore/gui/components/PluggableRenderable.java +++ b/src/mightypork/gamecore/gui/components/PluggableRenderable.java @@ -13,16 +13,16 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public interface PluggableRenderable extends Renderable, PluggableRectBound { - + @Override void render(); - - + + @Override Rect getRect(); - - + + @Override void setRect(RectBound rect); - + } diff --git a/src/mightypork/gamecore/gui/components/input/ClickableComponent.java b/src/mightypork/gamecore/gui/components/input/ClickableComponent.java index d969097..8714cd5 100644 --- a/src/mightypork/gamecore/gui/components/input/ClickableComponent.java +++ b/src/mightypork/gamecore/gui/components/input/ClickableComponent.java @@ -9,40 +9,40 @@ import mightypork.gamecore.input.events.MouseButtonHandler; public abstract class ClickableComponent extends InputComponent implements HasAction, MouseButtonHandler { - + protected boolean btnDownOver; private Action action; - - + + @Override public void setAction(Action action) { this.action = action; } - - + + protected void triggerAction() { if (action != null && isEnabled()) action.run(); } - - + + @Override public void receive(MouseButtonEvent event) { if (!event.isButtonEvent()) return; - + if (event.isDown()) { btnDownOver = event.isOver(this); } - + if (event.isUp()) { - + if (btnDownOver && event.isOver(this)) { triggerAction(); event.consume(); } - + btnDownOver = false; } } diff --git a/src/mightypork/gamecore/gui/components/input/ClickableWrapper.java b/src/mightypork/gamecore/gui/components/input/ClickableWrapper.java index 45dc6b7..8292e6c 100644 --- a/src/mightypork/gamecore/gui/components/input/ClickableWrapper.java +++ b/src/mightypork/gamecore/gui/components/input/ClickableWrapper.java @@ -9,41 +9,41 @@ import mightypork.utils.eventbus.clients.DelegatingClient; public class ClickableWrapper extends ClickableComponent implements DelegatingClient { - + private final Component wrapped; private final ClientList list; - - + + public ClickableWrapper(Component wrapped) { this.wrapped = wrapped; wrapped.setRect(this); - + list = new ClientList(wrapped); } - - + + @Override public Collection getChildClients() { return list; } - - + + @Override public boolean doesDelegate() { return true; } - - + + @Override protected void renderComponent() { wrapped.render(); } - - + + @Override public void setEnabled(boolean yes) { @@ -52,13 +52,13 @@ public class ClickableWrapper extends ClickableComponent implements DelegatingCl wrapped.setIndirectlyEnabled(yes); } } - - + + @Override public void setIndirectlyEnabled(boolean yes) { super.setIndirectlyEnabled(yes); wrapped.setIndirectlyEnabled(yes); } - + } diff --git a/src/mightypork/gamecore/gui/components/input/TextButton.java b/src/mightypork/gamecore/gui/components/input/TextButton.java index 20bf77a..5a7c36e 100644 --- a/src/mightypork/gamecore/gui/components/input/TextButton.java +++ b/src/mightypork/gamecore/gui/components/input/TextButton.java @@ -18,31 +18,31 @@ import mightypork.utils.math.constraints.vect.var.VectVar; * @author Ondřej Hruška (MightyPork) */ public class TextButton extends ClickableComponent implements DynamicWidthComponent { - + public final TextPainter textPainter; - + private final VectVar offset = Vect.makeVar(); - + public Vect offsetPassive = height().div(16).toVectXY(); public Vect offsetOver = height().div(20).toVectXY(); public Vect offsetUnder = height().div(32).toVectXY(); - + private final Color color; - + private boolean hoverMove = true; - - + + public TextButton(IFont font, String text, Color color) { this.color = color; - + this.textPainter = new TextPainter(font, AlignX.CENTER, this.color, text); this.textPainter.setRect(this); this.textPainter.setShadow(RGB.BLACK_30, offset); textPainter.setVPaddingPercent(5); } - - + + @Override protected void renderComponent() { @@ -55,11 +55,11 @@ public class TextButton extends ClickableComponent implements DynamicWidthCompon } else { offset.setTo(offsetPassive); } - + textPainter.render(); } - - + + /** * Disable offset change on hover */ @@ -67,12 +67,12 @@ public class TextButton extends ClickableComponent implements DynamicWidthCompon { hoverMove = false; } - - + + @Override public double computeWidth(double height) { return textPainter.computeWidth(height); } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/ColumnLayout.java b/src/mightypork/gamecore/gui/components/layout/ColumnLayout.java index 9b3f317..c1b7cd1 100644 --- a/src/mightypork/gamecore/gui/components/layout/ColumnLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/ColumnLayout.java @@ -6,37 +6,37 @@ import mightypork.utils.math.constraints.rect.RectBound; public class ColumnLayout extends GridLayout { - + private int col = 0; - - + + public ColumnLayout(int rows) { this(null, rows); } - - + + public ColumnLayout(RectBound context, int cols) { super(context, 1, cols); } - - + + public void add(final Component elem) { add(elem, 1); } - - + + public void add(final Component elem, int colSpan) { if (elem == null) return; - + put(elem, 0, col, 1, colSpan); col += colSpan; } - - + + public void skip(int cols) { col += cols; diff --git a/src/mightypork/gamecore/gui/components/layout/ConstraintLayout.java b/src/mightypork/gamecore/gui/components/layout/ConstraintLayout.java index b8ab75a..2a73a07 100644 --- a/src/mightypork/gamecore/gui/components/layout/ConstraintLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/ConstraintLayout.java @@ -12,18 +12,18 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public class ConstraintLayout extends LayoutComponent { - + public ConstraintLayout() { } - - + + public ConstraintLayout(RectBound context) { super(context); } - - + + /** * Add a component to the layout.
* The component's rect must be set up manually. @@ -34,5 +34,5 @@ public class ConstraintLayout extends LayoutComponent { { attach(component); } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/FlowColumnLayout.java b/src/mightypork/gamecore/gui/components/layout/FlowColumnLayout.java index 7cb9067..3c99299 100644 --- a/src/mightypork/gamecore/gui/components/layout/FlowColumnLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/FlowColumnLayout.java @@ -15,12 +15,12 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public class FlowColumnLayout extends LayoutComponent { - + private int col = 0; private Num elementWidth; private final AlignX align; - - + + /** * @param context context * @param elementWidth width of all elements @@ -31,13 +31,13 @@ public class FlowColumnLayout extends LayoutComponent { super(context); this.elementWidth = elementWidth; this.align = align; - + if (align != AlignX.LEFT && align != AlignX.RIGHT) { throw new IllegalArgumentException("Can align only left or right."); } } - - + + /** * make a new holder.
* Context must be assigned before rendering. @@ -49,8 +49,8 @@ public class FlowColumnLayout extends LayoutComponent { { this(null, elementWidth, align); } - - + + /** * Add an item * @@ -59,9 +59,9 @@ public class FlowColumnLayout extends LayoutComponent { public void add(final Component elem) { if (elem == null) return; - + final Rect r; - + switch (align) { case LEFT: r = leftEdge().growRight(elementWidth).moveX(elementWidth.mul(col++)); @@ -72,16 +72,16 @@ public class FlowColumnLayout extends LayoutComponent { default: throw new IllegalArgumentException("Bad align."); } - + elem.setRect(r); - + attach(elem); } - - + + public void setElementWidth(Num elementWidth) { this.elementWidth = elementWidth; } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/FlowRowLayout.java b/src/mightypork/gamecore/gui/components/layout/FlowRowLayout.java index 42669fb..2fa9be5 100644 --- a/src/mightypork/gamecore/gui/components/layout/FlowRowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/FlowRowLayout.java @@ -15,12 +15,12 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public class FlowRowLayout extends LayoutComponent { - + private int row = 0; private Num elementHeight; private final AlignY align; - - + + /** * @param context context * @param elementHeight height of all elements @@ -31,13 +31,13 @@ public class FlowRowLayout extends LayoutComponent { super(context); this.elementHeight = elementHeight; this.align = align; - + if (align != AlignY.TOP && align != AlignY.BOTTOM) { throw new IllegalArgumentException("Can align only to top or bottom."); } } - - + + /** * make a new holder.
* Context must be assigned before rendering. @@ -49,8 +49,8 @@ public class FlowRowLayout extends LayoutComponent { { this(null, elementHeight, align); } - - + + /** * Add an item * @@ -59,9 +59,9 @@ public class FlowRowLayout extends LayoutComponent { public void add(final Component elem) { if (elem == null) return; - + final Rect r; - + switch (align) { case TOP: r = topEdge().growDown(elementHeight).moveY(elementHeight.mul(row++)); @@ -72,13 +72,13 @@ public class FlowRowLayout extends LayoutComponent { default: throw new IllegalArgumentException("Bad align."); } - + elem.setRect(r); - + attach(elem); } - - + + public void setElementHeight(Num elementHeight) { this.elementHeight = elementHeight; diff --git a/src/mightypork/gamecore/gui/components/layout/GridLayout.java b/src/mightypork/gamecore/gui/components/layout/GridLayout.java index b8075cb..ab31c58 100644 --- a/src/mightypork/gamecore/gui/components/layout/GridLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/GridLayout.java @@ -13,10 +13,10 @@ import mightypork.utils.math.constraints.rect.builders.TiledRect; * @author Ondřej Hruška (MightyPork) */ public class GridLayout extends LayoutComponent { - + private final TiledRect tiler; - - + + /** * @param context context * @param rows number of rows @@ -27,8 +27,8 @@ public class GridLayout extends LayoutComponent { super(context); this.tiler = tiles(cols, rows); } - - + + /** * make a new holder.
* Context must be assigned before rendering. @@ -40,8 +40,8 @@ public class GridLayout extends LayoutComponent { { this(null, rows, cols); } - - + + /** * Add a row to the holder. * @@ -52,13 +52,13 @@ public class GridLayout extends LayoutComponent { public void put(Component elem, int row, int column) { if (elem == null) return; - + elem.setRect(tiler.tile(column, row)); - + attach(elem); } - - + + /** * Put with span * @@ -71,10 +71,10 @@ public class GridLayout extends LayoutComponent { public void put(Component elem, int row, int column, int rowspan, int colspan) { if (elem == null) return; - + elem.setRect(tiler.span(column, row, colspan, rowspan)); - + attach(elem); } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/NullComponent.java b/src/mightypork/gamecore/gui/components/layout/NullComponent.java index 4b2ebfa..ed24b2d 100644 --- a/src/mightypork/gamecore/gui/components/layout/NullComponent.java +++ b/src/mightypork/gamecore/gui/components/layout/NullComponent.java @@ -10,7 +10,7 @@ import mightypork.gamecore.gui.components.BaseComponent; * @author Ondřej Hruška (MightyPork) */ public class NullComponent extends BaseComponent { - + @Override protected void renderComponent() { diff --git a/src/mightypork/gamecore/gui/components/layout/RowLayout.java b/src/mightypork/gamecore/gui/components/layout/RowLayout.java index aed15d1..9135763 100644 --- a/src/mightypork/gamecore/gui/components/layout/RowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/RowLayout.java @@ -6,37 +6,37 @@ import mightypork.utils.math.constraints.rect.RectBound; public class RowLayout extends GridLayout { - + private int row = 0; - - + + public RowLayout(int rows) { this(null, rows); } - - + + public RowLayout(RectBound context, int rows) { super(context, rows, 1); } - - + + public void add(final Component elem) { add(elem, 1); } - - + + public void add(final Component elem, int rowSpan) { if (elem == null) return; - + put(elem, row, 0, rowSpan, 1); row += rowSpan; } - - + + public void skip(int rows) { row += rows; diff --git a/src/mightypork/gamecore/gui/components/layout/linear/AbstractLinearWrapper.java b/src/mightypork/gamecore/gui/components/layout/linear/AbstractLinearWrapper.java index 82d6681..e0f1863 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/AbstractLinearWrapper.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/AbstractLinearWrapper.java @@ -15,11 +15,11 @@ import mightypork.utils.eventbus.clients.DelegatingClient; * @author Ondřej Hruška (MightyPork) */ public abstract class AbstractLinearWrapper extends LinearComponent implements DelegatingClient { - + protected final Component wrapped; private final ClientList list; - - + + /** * @param wrapped wrapped component. Can be null. */ @@ -34,32 +34,32 @@ public abstract class AbstractLinearWrapper extends LinearComponent implements D wrapped.setRect(this); } } - + list = new ClientList(wrapped); } - - + + @Override protected void renderComponent() { if (wrapped != null) wrapped.render(); } - - + + @Override public Collection getChildClients() { return list; } - - + + @Override public boolean doesDelegate() { return true; } - - + + @Override public void setEnabled(boolean yes) { @@ -68,8 +68,8 @@ public abstract class AbstractLinearWrapper extends LinearComponent implements D wrapped.setIndirectlyEnabled(yes); } } - - + + @Override public void setIndirectlyEnabled(boolean yes) { diff --git a/src/mightypork/gamecore/gui/components/layout/linear/LinearGap.java b/src/mightypork/gamecore/gui/components/layout/linear/LinearGap.java index 7da7b8a..228d76f 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/LinearGap.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/LinearGap.java @@ -11,13 +11,13 @@ import mightypork.utils.math.constraints.num.Num; * @author Ondřej Hruška (MightyPork) */ public class LinearGap extends LinearRectangle { - + public LinearGap(Num width) { super(new NullComponent(), width); } - - + + public LinearGap(double heightPercent) { this(Num.ZERO); diff --git a/src/mightypork/gamecore/gui/components/layout/linear/LinearLayout.java b/src/mightypork/gamecore/gui/components/layout/linear/LinearLayout.java index 44059b1..da243c5 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/LinearLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/LinearLayout.java @@ -20,27 +20,27 @@ import mightypork.utils.math.constraints.vect.proxy.VectAdapter; * @author Ondřej Hruška (MightyPork) */ public class LinearLayout extends LayoutComponent { - + public LinearLayout(AlignX align) { this.align = align; } - - + + public LinearLayout(RectBound context, AlignX align) { super(context); this.align = align; } - + private final NumSum totalWidth = new NumSum(); - + private final Vect leftAlignOrigin = LinearLayout.this.origin(); private final Vect centerAlignOrigin = LinearLayout.this.topCenter().sub(totalWidth.half(), Num.ZERO); private final Vect rightAlignOrigin = LinearLayout.this.topRight().sub(totalWidth, Num.ZERO); - + private final Vect leftMostOrigin = new VectAdapter() { - + @Override protected Vect getSource() { @@ -55,18 +55,18 @@ public class LinearLayout extends LayoutComponent { } } }; - + private Vect nextOrigin = leftMostOrigin; - + private AlignX align = AlignX.LEFT; - - + + public void add(DynamicWidthComponent dwcomp) { add(new LinearWrapper(dwcomp)); } - - + + public void add(LinearComponent lincomp) { lincomp.setHeight(height()); @@ -75,14 +75,14 @@ public class LinearLayout extends LayoutComponent { totalWidth.addSummand(lincomp.width()); attach(lincomp); } - - + + public void setAlign(AlignX align) { this.align = align; } - - + + /** * Add a gap. * diff --git a/src/mightypork/gamecore/gui/components/layout/linear/LinearRectangle.java b/src/mightypork/gamecore/gui/components/layout/linear/LinearRectangle.java index 78e3f9c..6a87ea7 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/LinearRectangle.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/LinearRectangle.java @@ -6,27 +6,27 @@ import mightypork.utils.math.constraints.num.Num; public class LinearRectangle extends AbstractLinearWrapper { - + private Num width; - - + + public LinearRectangle(Component wrapped, Num width) { super(wrapped); this.width = width; } - - + + public void setWidth(Num width) { this.width = width; } - - + + @Override public double computeWidth(double height) { return this.width.value(); } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/linear/LinearSquare.java b/src/mightypork/gamecore/gui/components/layout/linear/LinearSquare.java index a3c37ee..ff88b08 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/LinearSquare.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/LinearSquare.java @@ -5,17 +5,17 @@ import mightypork.gamecore.gui.components.Component; public class LinearSquare extends AbstractLinearWrapper { - + public LinearSquare(Component wrapped) { super(wrapped); } - - + + @Override public double computeWidth(double height) { return height; } - + } diff --git a/src/mightypork/gamecore/gui/components/layout/linear/LinearWrapper.java b/src/mightypork/gamecore/gui/components/layout/linear/LinearWrapper.java index 2fe8896..6f5b0f9 100644 --- a/src/mightypork/gamecore/gui/components/layout/linear/LinearWrapper.java +++ b/src/mightypork/gamecore/gui/components/layout/linear/LinearWrapper.java @@ -5,17 +5,17 @@ import mightypork.gamecore.gui.components.DynamicWidthComponent; public class LinearWrapper extends AbstractLinearWrapper { - + public LinearWrapper(DynamicWidthComponent wrapped) { super(wrapped); } - - + + @Override public double computeWidth(double height) { return ((DynamicWidthComponent) wrapped).computeWidth(height); } - + } diff --git a/src/mightypork/gamecore/gui/components/painters/ImagePainter.java b/src/mightypork/gamecore/gui/components/painters/ImagePainter.java index 42928fc..28f5583 100644 --- a/src/mightypork/gamecore/gui/components/painters/ImagePainter.java +++ b/src/mightypork/gamecore/gui/components/painters/ImagePainter.java @@ -13,10 +13,10 @@ import mightypork.gamecore.gui.components.DynamicWidthComponent; * @author Ondřej Hruška (MightyPork) */ public class ImagePainter extends BaseComponent implements DynamicWidthComponent { - + private TxQuad txQuad; - - + + /** * @param txQuad drawn image */ @@ -24,22 +24,22 @@ public class ImagePainter extends BaseComponent implements DynamicWidthComponent { this.txQuad = txQuad; } - - + + @Override public void renderComponent() { App.gfx().quad(this, txQuad); } - - + + @Override public double computeWidth(double height) { return (height / txQuad.uvs.height().value()) * txQuad.uvs.width().value(); } - - + + /** * Set drawn {@link TxQuad} * diff --git a/src/mightypork/gamecore/gui/components/painters/QuadPainter.java b/src/mightypork/gamecore/gui/components/painters/QuadPainter.java index 6043c40..da13cca 100644 --- a/src/mightypork/gamecore/gui/components/painters/QuadPainter.java +++ b/src/mightypork/gamecore/gui/components/painters/QuadPainter.java @@ -14,23 +14,23 @@ import mightypork.utils.math.color.Grad; * @author Ondřej Hruška (MightyPork) */ public class QuadPainter extends BaseComponent { - + @FactoryMethod public static QuadPainter gradH(Color colorLeft, Color colorRight) { return new QuadPainter(colorLeft, colorRight, colorRight, colorLeft); } - - + + @FactoryMethod public static QuadPainter gradV(Color colorTop, Color colorBottom) { return new QuadPainter(colorTop, colorTop, colorBottom, colorBottom); } - + private final Grad grad; - - + + /** * Painter with solid color * @@ -40,8 +40,8 @@ public class QuadPainter extends BaseComponent { { this.grad = new Grad(color, color, color, color); } - - + + /** * Painter with coloured vertices. * @@ -54,8 +54,8 @@ public class QuadPainter extends BaseComponent { { this.grad = new Grad(leftTop, rightTop, rightBottom, leftBottom); } - - + + @Override public void renderComponent() { diff --git a/src/mightypork/gamecore/gui/components/painters/TextPainter.java b/src/mightypork/gamecore/gui/components/painters/TextPainter.java index ae33de1..a87dabe 100644 --- a/src/mightypork/gamecore/gui/components/painters/TextPainter.java +++ b/src/mightypork/gamecore/gui/components/painters/TextPainter.java @@ -22,20 +22,20 @@ import mightypork.utils.string.StringWrapper; * @author Ondřej Hruška (MightyPork) */ public class TextPainter extends BaseComponent implements DynamicWidthComponent { - + private static final boolean DEBUG_FONT_RENDER = false; private final FontRenderer font; private Color color; private AlignX align; private StringProvider text; private boolean shadow; - + private double yPaddingPerc = 0; - + private Color shadowColor = RGB.BLACK; private Vect shadowOffset = Vect.make(2, 2); - - + + /** * @param font font to use */ @@ -43,32 +43,32 @@ public class TextPainter extends BaseComponent implements DynamicWidthComponent { this(font, AlignX.LEFT, RGB.WHITE); } - - + + public TextPainter(IFont font, Color color, String text) { this(font, AlignX.LEFT, color, new StringWrapper(text)); } - - + + public TextPainter(IFont font, Color color, StringProvider text) { this(font, AlignX.LEFT, color, text); } - - + + public TextPainter(IFont font, Color color) { this(font, AlignX.LEFT, color, (StringProvider) null); } - - + + public TextPainter(IFont font, AlignX align, Color color, String text) { this(font, align, color, new StringWrapper(text)); } - - + + public TextPainter(IFont font, AlignX align, Color color, StringProvider text) { this.font = new FontRenderer(font); @@ -76,92 +76,92 @@ public class TextPainter extends BaseComponent implements DynamicWidthComponent this.align = align; this.text = text; } - - + + public TextPainter(IFont font, AlignX align, Color color) { this(font, align, color, (StringProvider) null); } - - + + @Override public void renderComponent() { if (text == null) return; - + final String str = text.getString(); - + final Num shrY = height().perc(yPaddingPerc); - + final Rect rect = getRect().shrink(Num.ZERO, shrY); - + if (shadow) { font.draw(str, rect.round(), align, shadowColor); } - + final Rect r = (shadow ? rect.move(shadowOffset.neg()) : rect).round(); font.draw(str, r, align, color); - + if (DEBUG_FONT_RENDER) App.gfx().quad(r, RGB.PINK.withAlpha(0.4)); } - - + + public void setShadow(Color color, Vect offset) { setShadow(true); setShadowColor(color); setShadowOffset(offset); } - - + + public void setShadow(boolean shadow) { this.shadow = shadow; } - - + + public void setShadowColor(Color shadowColor) { this.shadowColor = shadowColor; } - - + + public void setShadowOffset(Vect shadowOffset) { this.shadowOffset = shadowOffset; } - - + + public void setColor(Color color) { this.color = color; } - - + + public void setAlign(AlignX align) { this.align = align; } - - + + public void setText(String text) { this.text = new StringWrapper(text); } - - + + public void setText(StringProvider text) { this.text = text; } - - + + public void setVPaddingPercent(double percY) { yPaddingPerc = percY; } - - + + @Override public double computeWidth(double height) { diff --git a/src/mightypork/gamecore/gui/events/LayoutChangeEvent.java b/src/mightypork/gamecore/gui/events/LayoutChangeEvent.java index 4158600..2c6d6af 100644 --- a/src/mightypork/gamecore/gui/events/LayoutChangeEvent.java +++ b/src/mightypork/gamecore/gui/events/LayoutChangeEvent.java @@ -19,7 +19,7 @@ import mightypork.utils.eventbus.events.flags.NonRejectableEvent; @NonConsumableEvent @NonRejectableEvent public class LayoutChangeEvent extends BusEvent { - + @Override public void handleBy(LayoutChangeListener handler) { diff --git a/src/mightypork/gamecore/gui/events/LayoutChangeListener.java b/src/mightypork/gamecore/gui/events/LayoutChangeListener.java index df4e53e..d2ef4a6 100644 --- a/src/mightypork/gamecore/gui/events/LayoutChangeListener.java +++ b/src/mightypork/gamecore/gui/events/LayoutChangeListener.java @@ -7,7 +7,7 @@ package mightypork.gamecore.gui.events; * @author Ondřej Hruška (MightyPork) */ public interface LayoutChangeListener { - + /** * Triggered when display size changed and GUI should be recalculated. */ diff --git a/src/mightypork/gamecore/gui/events/ScreenRequest.java b/src/mightypork/gamecore/gui/events/ScreenRequest.java index 9af5c0a..8d1a073 100644 --- a/src/mightypork/gamecore/gui/events/ScreenRequest.java +++ b/src/mightypork/gamecore/gui/events/ScreenRequest.java @@ -13,10 +13,10 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class ScreenRequest extends BusEvent { - + private final String scrName; - - + + /** * Create a request to change screen * @@ -26,12 +26,12 @@ public class ScreenRequest extends BusEvent { { scrName = screenKey; } - - + + @Override public void handleBy(ScreenRequestListener handler) { handler.showScreen(scrName); } - + } diff --git a/src/mightypork/gamecore/gui/events/ScreenRequestListener.java b/src/mightypork/gamecore/gui/events/ScreenRequestListener.java index 98914e4..94612ca 100644 --- a/src/mightypork/gamecore/gui/events/ScreenRequestListener.java +++ b/src/mightypork/gamecore/gui/events/ScreenRequestListener.java @@ -7,7 +7,7 @@ package mightypork.gamecore.gui.events; * @author Ondřej Hruška (MightyPork) */ public interface ScreenRequestListener { - + /** * @param key screen to show */ diff --git a/src/mightypork/gamecore/gui/events/ViewportChangeEvent.java b/src/mightypork/gamecore/gui/events/ViewportChangeEvent.java index 0022833..dc4c551 100644 --- a/src/mightypork/gamecore/gui/events/ViewportChangeEvent.java +++ b/src/mightypork/gamecore/gui/events/ViewportChangeEvent.java @@ -15,10 +15,10 @@ import mightypork.utils.math.constraints.vect.Vect; @NonConsumableEvent @NotLoggedEvent public class ViewportChangeEvent extends BusEvent { - + private final Vect screenSize; - - + + /** * @param size new screen size */ @@ -26,8 +26,8 @@ public class ViewportChangeEvent extends BusEvent { { this.screenSize = size; } - - + + /** * @return new screen size */ @@ -35,8 +35,8 @@ public class ViewportChangeEvent extends BusEvent { { return screenSize; } - - + + @Override public void handleBy(ViewportChangeListener handler) { diff --git a/src/mightypork/gamecore/gui/events/ViewportChangeListener.java b/src/mightypork/gamecore/gui/events/ViewportChangeListener.java index d0b7d5c..68af308 100644 --- a/src/mightypork/gamecore/gui/events/ViewportChangeListener.java +++ b/src/mightypork/gamecore/gui/events/ViewportChangeListener.java @@ -7,7 +7,7 @@ package mightypork.gamecore.gui.events; * @author Ondřej Hruška (MightyPork) */ public interface ViewportChangeListener { - + /** * Handle event * diff --git a/src/mightypork/gamecore/gui/screens/LayeredScreen.java b/src/mightypork/gamecore/gui/screens/LayeredScreen.java index 67964ed..4fa7f0c 100644 --- a/src/mightypork/gamecore/gui/screens/LayeredScreen.java +++ b/src/mightypork/gamecore/gui/screens/LayeredScreen.java @@ -17,36 +17,36 @@ import mightypork.utils.eventbus.clients.DelegatingClient; * @author Ondřej Hruška (MightyPork) */ public abstract class LayeredScreen extends Screen { - + /** * Wrapper for delegating client, to use custom client ordering. * * @author Ondřej Hruška (MightyPork) */ private class LayersClient implements DelegatingClient { - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Collection getChildClients() { return layersByEventPriority; } - - + + @Override public boolean doesDelegate() { return true; } - + } - + private final List layersByZIndex = new ArrayList<>(); private final List layersByEventPriority = new ArrayList<>(); - + private final LayersClient layersClient = new LayersClient(); - - + + /** * Create a layered screen */ @@ -54,8 +54,8 @@ public abstract class LayeredScreen extends Screen { { addChildClient(layersClient); } - - + + @Override protected void renderScreen() { @@ -63,8 +63,8 @@ public abstract class LayeredScreen extends Screen { if (layer.isVisible()) layer.render(); } } - - + + /** * Add a layer to the screen. * @@ -74,29 +74,29 @@ public abstract class LayeredScreen extends Screen { { this.layersByZIndex.add(layer); this.layersByEventPriority.add(layer); - + Collections.sort(layersByEventPriority, new Comparator() { - + @Override public int compare(Overlay o1, Overlay o2) { return o2.getEventPriority() - o1.getEventPriority(); } - + }); - + Collections.sort(layersByZIndex, new Comparator() { - + @Override public int compare(Overlay o1, Overlay o2) { return o1.getZIndex() - o2.getZIndex(); } - + }); } - - + + @Override protected void onScreenEnter() { @@ -104,8 +104,8 @@ public abstract class LayeredScreen extends Screen { layer.onScreenEnter(); } } - - + + @Override protected void onScreenLeave() { @@ -113,5 +113,5 @@ public abstract class LayeredScreen extends Screen { layer.onScreenLeave(); } } - + } diff --git a/src/mightypork/gamecore/gui/screens/Overlay.java b/src/mightypork/gamecore/gui/screens/Overlay.java index eebf224..a81bd4d 100644 --- a/src/mightypork/gamecore/gui/screens/Overlay.java +++ b/src/mightypork/gamecore/gui/screens/Overlay.java @@ -29,62 +29,62 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public abstract class Overlay extends BusNode implements Comparable, Updateable, Renderable, KeyBinder, Hideable, Enableable, LayoutChangeListener { - + private boolean visible = true; private boolean enabled = true; - + private final KeyBindingPool keybindings = new KeyBindingPool(); - + /** Root layout, rendered and attached to the event bus. */ protected final ConstraintLayout root; - + /** Constraint: Mouse position. */ protected final Vect mouse; - + /** Extra rendered items (outside root) */ protected final Collection rendered = new ArrayList<>(); - + /** Extra updated items (not members of the component tree) */ protected final Collection updated = new ArrayList<>(); private Num alphaMul = Num.ONE; - - + + /** * Create an overlay over the screen */ public Overlay() { this.mouse = App.input().getMousePos(); - + this.root = new ConstraintLayout(App.gfx().getRect()); addChildClient(root); addChildClient(keybindings); - + rendered.add(root); } - - + + @Override public final void bindKey(KeyStroke stroke, Trigger edge, Runnable task) { keybindings.bindKey(stroke, edge, task); } - - + + @Override public final void unbindKey(KeyStroke stroke) { keybindings.unbindKey(stroke); } - - + + @Override public final boolean isVisible() { return visible; } - - + + @Override public void setVisible(boolean visible) { @@ -93,8 +93,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up root.setVisible(visible); } } - - + + @Override public void setEnabled(boolean yes) { @@ -103,15 +103,15 @@ public abstract class Overlay extends BusNode implements Comparable, Up root.setEnabled(yes); } } - - + + @Override public boolean isEnabled() { return enabled; } - - + + /** * Get rendering layer * @@ -119,8 +119,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up */ @Stub public abstract int getZIndex(); - - + + /** * Get event bus listening priority - useful to block incoming events. * @@ -130,8 +130,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up { return getZIndex(); } - - + + /** * Render the overlay. The caller MUST check for visibility himself. */ @@ -139,34 +139,34 @@ public abstract class Overlay extends BusNode implements Comparable, Up public void render() { if (!isVisible()) return; - + Color.pushAlpha(alphaMul); for (final Renderable r : rendered) { r.render(); } - + Color.popAlpha(); } - - + + @Override public void update(double delta) { if (!isEnabled()) return; - + for (final Updateable u : updated) { u.update(delta); } } - - + + @Override public int compareTo(Overlay o) { return o.getEventPriority() - getEventPriority(); } - - + + /** *

* Screen size changed. @@ -182,8 +182,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up public void onLayoutChanged() { } - - + + /** * Set overlay's alpha multiplier * @@ -193,8 +193,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up { this.alphaMul = alpha; } - - + + /** * Set overlay's alpha multiplier * @@ -204,8 +204,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up { this.alphaMul = Num.make(alpha); } - - + + /** * Show and set enabled */ @@ -214,8 +214,8 @@ public abstract class Overlay extends BusNode implements Comparable, Up setVisible(true); setEnabled(true); } - - + + /** * Hide and set disabled */ @@ -224,15 +224,15 @@ public abstract class Overlay extends BusNode implements Comparable, Up setVisible(false); setEnabled(false); } - - + + @Override public boolean isListening() { return (isVisible() || isEnabled()); } - - + + @Override public boolean doesDelegate() { diff --git a/src/mightypork/gamecore/gui/screens/Screen.java b/src/mightypork/gamecore/gui/screens/Screen.java index ade3ae9..d3f5fb3 100644 --- a/src/mightypork/gamecore/gui/screens/Screen.java +++ b/src/mightypork/gamecore/gui/screens/Screen.java @@ -21,13 +21,13 @@ import mightypork.utils.math.constraints.rect.RectBound; * @author Ondřej Hruška (MightyPork) */ public abstract class Screen extends BusNode implements Renderable, RectBound, KeyBinder, LayoutChangeListener { - + private final KeyBindingPool keybindings = new KeyBindingPool(); - + private volatile boolean active; private volatile boolean needSetupViewport = false; - - + + /** * Make a screen. The screen will initially not listen to the bus, which is * changed once the setActive method is set to true. @@ -36,31 +36,31 @@ public abstract class Screen extends BusNode implements Renderable, RectBound, K { // disable events initially setListening(false); - + addChildClient(keybindings); } - - + + private void fireLayoutChangeEvent() { App.bus().sendDirectToChildren(this, new LayoutChangeEvent()); } - - + + @Override public final void bindKey(KeyStroke stroke, Trigger edge, Runnable task) { keybindings.bindKey(stroke, edge, task); } - - + + @Override public final void unbindKey(KeyStroke stroke) { keybindings.unbindKey(stroke); } - - + + /** * Prepare for being shown * @@ -71,24 +71,24 @@ public abstract class Screen extends BusNode implements Renderable, RectBound, K if (shown) { active = true; needSetupViewport = true; - + fireLayoutChangeEvent(); onScreenEnter(); - + // enable events setListening(true); - + } else { onScreenLeave(); - + active = false; - + // disable events setListening(false); } } - - + + /** * @return true if screen is the current screen */ @@ -96,41 +96,41 @@ public abstract class Screen extends BusNode implements Renderable, RectBound, K { return active; } - - + + @Override public void onLayoutChanged() { if (!isActive()) return; - + needSetupViewport = true; } - - + + @Override public final Rect getRect() { return App.gfx().getRect(); } - - + + @Override public void render() { if (!isActive()) return; - + if (needSetupViewport) { App.gfx().setupProjection(); } - + App.gfx().pushState(); - + renderScreen(); - + App.gfx().popState(); } - - + + /** * Called when the screen becomes active */ @@ -139,8 +139,8 @@ public abstract class Screen extends BusNode implements Renderable, RectBound, K { // } - - + + /** * Called when the screen is no longer active */ @@ -149,11 +149,11 @@ public abstract class Screen extends BusNode implements Renderable, RectBound, K { // } - - + + /** * Render screen contents (context is ready for 2D rendering) */ protected abstract void renderScreen(); - + } diff --git a/src/mightypork/gamecore/gui/screens/ScreenLayer.java b/src/mightypork/gamecore/gui/screens/ScreenLayer.java index f675969..cf4b3d8 100644 --- a/src/mightypork/gamecore/gui/screens/ScreenLayer.java +++ b/src/mightypork/gamecore/gui/screens/ScreenLayer.java @@ -10,10 +10,10 @@ import mightypork.utils.annotations.Stub; * @author Ondřej Hruška (MightyPork) */ public abstract class ScreenLayer extends Overlay { - + private final Screen screen; - - + + /** * @param screen parent screen */ @@ -21,8 +21,8 @@ public abstract class ScreenLayer extends Overlay { { this.screen = screen; } - - + + /** * @return parent screen instance */ @@ -30,8 +30,8 @@ public abstract class ScreenLayer extends Overlay { { return screen; } - - + + /** * Called when the screen becomes active */ @@ -39,8 +39,8 @@ public abstract class ScreenLayer extends Overlay { protected void onScreenEnter() { } - - + + /** * Called when the screen is no longer active */ diff --git a/src/mightypork/gamecore/gui/screens/ScreenRegistry.java b/src/mightypork/gamecore/gui/screens/ScreenRegistry.java index 06c2db5..311959b 100644 --- a/src/mightypork/gamecore/gui/screens/ScreenRegistry.java +++ b/src/mightypork/gamecore/gui/screens/ScreenRegistry.java @@ -22,12 +22,12 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public class ScreenRegistry extends BusNode implements ScreenRequestListener, ViewportChangeListener, Renderable { - + private final Map screens = new HashMap<>(); private final Collection overlays = new TreeSet<>(); private volatile Screen active = null; - - + + /** * Add a screen * @@ -39,8 +39,8 @@ public class ScreenRegistry extends BusNode implements ScreenRequestListener, Vi screens.put(name, screen); addChildClient(screen); } - - + + /** * Add an overlay * @@ -51,56 +51,56 @@ public class ScreenRegistry extends BusNode implements ScreenRequestListener, Vi overlays.add(overlay); addChildClient(overlay); } - - + + @Override public void showScreen(String key) { Log.f3("Request to show screen \"" + key + "\""); - + // find screen to show final Screen toShow = screens.get(key); if (toShow == null) { throw new RuntimeException("Screen " + key + " not defined."); } - + // deactivate last screen if (active != null) { active.setActive(false); } - + // activate new screen toShow.setActive(true); - + active = toShow; - + fireLayoutUpdateEvent(); } - - + + @Override public void render() { if (active != null) { active.render(); - + for (final Overlay overlay : overlays) { if (overlay.isVisible()) overlay.render(); } } } - - + + @Override public void onViewportChanged(ViewportChangeEvent event) { if (active != null) fireLayoutUpdateEvent(); } - - + + private void fireLayoutUpdateEvent() { App.bus().sendDirectToChildren(this, new LayoutChangeEvent()); } - + } diff --git a/src/mightypork/gamecore/gui/screens/impl/CrossfadeOverlay.java b/src/mightypork/gamecore/gui/screens/impl/CrossfadeOverlay.java index 53c01c6..e981ae6 100644 --- a/src/mightypork/gamecore/gui/screens/impl/CrossfadeOverlay.java +++ b/src/mightypork/gamecore/gui/screens/impl/CrossfadeOverlay.java @@ -18,15 +18,15 @@ import mightypork.utils.math.timing.TimedTask; * @author Ondřej Hruška (MightyPork) */ public class CrossfadeOverlay extends Overlay { - + private static final double T_IN = 0.4; private static final double T_OUT = 0.6; - + NumAnimated alpha = new NumAnimated(0); String requestedScreenName; - + TimedTask revealTask = new TimedTask() { - + @Override public void run() { @@ -39,8 +39,8 @@ public class CrossfadeOverlay extends Overlay { alpha.fadeOut(T_OUT); } }; - - + + /** * Create new crossfade overlay */ @@ -49,21 +49,21 @@ public class CrossfadeOverlay extends Overlay { final QuadPainter qp = new QuadPainter(RGB.BLACK); // TODO allow custom colors qp.setRect(root); root.add(qp); - + updated.add(alpha); updated.add(revealTask); - + setAlpha(alpha); } - - + + @Override public int getZIndex() { return 10000; // not too high, so app can put something on top } - - + + /** * Go to specified screen * @@ -73,21 +73,21 @@ public class CrossfadeOverlay extends Overlay { public void goToScreen(String screen, boolean fromDark) { requestedScreenName = screen; - + if (screen == null) { // going for halt App.sound().fadeOutAllLoops(); } - + if (fromDark) { alpha.setTo(1); revealTask.run(); } else { revealTask.start(T_IN); - + alpha.setEasing(Easing.SINE_IN); alpha.fadeIn(T_IN); } } - + } diff --git a/src/mightypork/gamecore/gui/screens/impl/CrossfadeRequest.java b/src/mightypork/gamecore/gui/screens/impl/CrossfadeRequest.java index ec14232..5a985d4 100644 --- a/src/mightypork/gamecore/gui/screens/impl/CrossfadeRequest.java +++ b/src/mightypork/gamecore/gui/screens/impl/CrossfadeRequest.java @@ -10,11 +10,11 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class CrossfadeRequest extends BusEvent { - + private final String screen; private final boolean fromDark; - - + + /** * @param screen screen key to show. Null = exit the app. * @param fromDark true to fade from full black (ie. start of the game) @@ -25,8 +25,8 @@ public class CrossfadeRequest extends BusEvent { this.screen = screen; this.fromDark = fromDark; } - - + + /** * @param screen screen key to show. Null = exit the app. */ @@ -36,12 +36,12 @@ public class CrossfadeRequest extends BusEvent { this.screen = screen; this.fromDark = false; } - - + + @Override public void handleBy(CrossfadeOverlay handler) { handler.goToScreen(screen, fromDark); } - + } diff --git a/src/mightypork/gamecore/gui/screens/impl/FadingLayer.java b/src/mightypork/gamecore/gui/screens/impl/FadingLayer.java index 01da8fb..aa98f49 100644 --- a/src/mightypork/gamecore/gui/screens/impl/FadingLayer.java +++ b/src/mightypork/gamecore/gui/screens/impl/FadingLayer.java @@ -15,10 +15,10 @@ import mightypork.utils.math.timing.TimedTask; * @author Ondřej Hruška (MightyPork) */ public abstract class FadingLayer extends ScreenLayer { - + private final NumAnimated numa; private final TimedTask hideTimer = new TimedTask() { - + @Override public void run() { @@ -27,9 +27,9 @@ public abstract class FadingLayer extends ScreenLayer { onHideFinished(); } }; - + private final TimedTask showTimer = new TimedTask() { - + @Override public void run() { @@ -37,11 +37,11 @@ public abstract class FadingLayer extends ScreenLayer { onShowFinished(); } }; - + private boolean fadingIn = false; private boolean fadingOut = false; - - + + /** * Create with default fading time and effect * @@ -51,8 +51,8 @@ public abstract class FadingLayer extends ScreenLayer { { this(screen, new NumAnimated(1, Easing.QUADRATIC_OUT, 0.3)); } - - + + /** * Create with custom animator * @@ -62,17 +62,17 @@ public abstract class FadingLayer extends ScreenLayer { public FadingLayer(Screen screen, NumAnimated easingAnim) { super(screen); - + numa = easingAnim; - + updated.add(numa); updated.add(hideTimer); updated.add(showTimer); - + setAlpha(numa); } - - + + /** * Called after the fade-out was completed */ @@ -80,8 +80,8 @@ public abstract class FadingLayer extends ScreenLayer { protected void onHideFinished() { } - - + + /** * Called after the fade-in was completed */ @@ -89,8 +89,8 @@ public abstract class FadingLayer extends ScreenLayer { protected void onShowFinished() { } - - + + /** * Show with fading */ @@ -98,19 +98,19 @@ public abstract class FadingLayer extends ScreenLayer { public void show() { if (fadingIn) return; - + if (!isVisible() || fadingOut) { super.show(); numa.fadeIn(); hideTimer.stop(); showTimer.start(numa.getDefaultDuration()); - + fadingOut = false; fadingIn = true; } } - - + + /** * Hide without fading */ @@ -121,8 +121,8 @@ public abstract class FadingLayer extends ScreenLayer { super.hide(); onHideFinished(); } - - + + /** * Show without fading */ @@ -133,8 +133,8 @@ public abstract class FadingLayer extends ScreenLayer { super.show(); onShowFinished(); } - - + + /** * Hide with fading */ @@ -142,14 +142,14 @@ public abstract class FadingLayer extends ScreenLayer { public void hide() { if (fadingOut) return; - + if (isVisible()) { numa.fadeOut(); hideTimer.start(numa.getDefaultDuration()); - + fadingOut = true; fadingIn = false; } } - + } diff --git a/src/mightypork/gamecore/gui/screens/impl/LayerColor.java b/src/mightypork/gamecore/gui/screens/impl/LayerColor.java index 465ee9a..acf85e5 100644 --- a/src/mightypork/gamecore/gui/screens/impl/LayerColor.java +++ b/src/mightypork/gamecore/gui/screens/impl/LayerColor.java @@ -13,10 +13,10 @@ import mightypork.utils.math.color.Color; * @author Ondřej Hruška (MightyPork) */ public class LayerColor extends ScreenLayer { - + private final int zIndex; - - + + /** * Overlay with color * @@ -27,18 +27,18 @@ public class LayerColor extends ScreenLayer { public LayerColor(Screen screen, Color color, int zIndex) { super(screen); - + final QuadPainter qp = new QuadPainter(color); qp.setRect(root); root.add(qp); this.zIndex = zIndex; } - - + + @Override public int getZIndex() { return this.zIndex; } - + } diff --git a/src/mightypork/gamecore/input/InputModule.java b/src/mightypork/gamecore/input/InputModule.java index c958087..adfc01f 100644 --- a/src/mightypork/gamecore/input/InputModule.java +++ b/src/mightypork/gamecore/input/InputModule.java @@ -15,47 +15,47 @@ import mightypork.utils.math.constraints.vect.Vect; * @author Ondřej Hruška (MightyPork) */ public abstract class InputModule extends BackendModule implements KeyBinder { - + protected KeyBindingPool keybindings; - - + + @Override public final void init() { initKeyCodes(); initDevices(); - + keybindings = new KeyBindingPool(); addChildClient(keybindings); } - - + + /** * Initialize key codes for keys in {@link Keys} */ protected abstract void initKeyCodes(); - - + + /** * Initialize input devices (set up infrastructure for getting the input) */ protected abstract void initDevices(); - - + + @Override public void bindKey(KeyStroke stroke, Trigger edge, Runnable task) { keybindings.bindKey(stroke, edge, task); } - - + + @Override public void unbindKey(KeyStroke stroke) { keybindings.unbindKey(stroke); } - - + + /** * Get absolute mouse position. Should always return the same Vect instance * (use a VectVar or similar). @@ -63,24 +63,24 @@ public abstract class InputModule extends BackendModule implements KeyBinder { * @return mouse position */ public abstract Vect getMousePos(); - - + + /** * Check if mouse is inside window * * @return true if mouse is inside window. */ public abstract boolean isMouseInside(); - - + + /** * Trap mouse cursor in the window / release it * * @param grab true to grab, false to release */ public abstract void grabMouse(boolean grab); - - + + /** * Check if key is down. The key comes from the Keys class, so the code is * the one assigned in initKeyCodes() @@ -89,8 +89,8 @@ public abstract class InputModule extends BackendModule implements KeyBinder { * @return is down */ public abstract boolean isKeyDown(Key key); - - + + /** * Check mouse button state * diff --git a/src/mightypork/gamecore/input/Key.java b/src/mightypork/gamecore/input/Key.java index 414643b..65f3c41 100644 --- a/src/mightypork/gamecore/input/Key.java +++ b/src/mightypork/gamecore/input/Key.java @@ -15,12 +15,12 @@ import mightypork.gamecore.core.App; * @author Ondřej Hruška (MightyPork) */ public class Key { - + private int code = -1; private final String name; private final Set aliases = new HashSet<>(1); - - + + /** * Create a key. Note that both name and aliases are converted to uppercase, * and all underscores are ignored when the aliases are matched. @@ -30,24 +30,24 @@ public class Key { */ public Key(String name, String... aliases) { - + // assign name and aliases, converting both to uppercase - + this.name = name; this.aliases.add(prepareForMatch(name)); - + for (final String al : aliases) { this.aliases.add(prepareForMatch(al)); } } - - + + public boolean isDown() { return App.input().isKeyDown(this); } - - + + /** * Set a key code. This can be used by the {@link InputModule} to store a * numeric code in the key. @@ -58,8 +58,8 @@ public class Key { { this.code = code; } - - + + /** * Check if the provided alias matches this key.
* Both the primary alias and the extra aliases are considered. @@ -72,14 +72,14 @@ public class Key { if (alias == null) return false; return aliases.contains(prepareForMatch(alias)); } - - + + private String prepareForMatch(String matched) { return matched.toUpperCase().replace("_", ""); } - - + + /** * Get key name (primary alias). * @@ -89,8 +89,8 @@ public class Key { { return name; } - - + + /** * Get the numeric code assigned to this key. If none is assigned, the value * is -1. @@ -101,8 +101,8 @@ public class Key { { return code; } - - + + /** * Get if this key is not a NONE or undefined key. * diff --git a/src/mightypork/gamecore/input/KeyBinder.java b/src/mightypork/gamecore/input/KeyBinder.java index 3a65723..c8e8ae0 100644 --- a/src/mightypork/gamecore/input/KeyBinder.java +++ b/src/mightypork/gamecore/input/KeyBinder.java @@ -10,7 +10,7 @@ import mightypork.gamecore.gui.Action; * @author Ondřej Hruška (MightyPork) */ public interface KeyBinder { - + /** * Bind handler to a keystroke, replace current handler if any * @@ -19,13 +19,13 @@ public interface KeyBinder { * @param task handler; can be {@link Runnable} or {@link Action} */ void bindKey(KeyStroke stroke, Trigger edge, Runnable task); - - + + /** * Remove handler from a keystroke (id any) * * @param stroke stroke */ void unbindKey(KeyStroke stroke); - + } diff --git a/src/mightypork/gamecore/input/KeyBinding.java b/src/mightypork/gamecore/input/KeyBinding.java index 6a3b881..7a94a09 100644 --- a/src/mightypork/gamecore/input/KeyBinding.java +++ b/src/mightypork/gamecore/input/KeyBinding.java @@ -11,13 +11,13 @@ import mightypork.gamecore.input.events.KeyEventHandler; * @author Ondřej Hruška (MightyPork) */ public class KeyBinding implements KeyEventHandler { - + private final KeyStroke keystroke; private Runnable handler; private final Trigger edge; private boolean wasDown = false; - - + + /** * @param edge trigger edge * @param stroke trigger keystroke @@ -30,8 +30,8 @@ public class KeyBinding implements KeyEventHandler { this.edge = edge; wasDown = stroke.isDown(); } - - + + /** * Check for equality of keystroke * @@ -42,8 +42,8 @@ public class KeyBinding implements KeyEventHandler { { return this.keystroke.equals(stroke); } - - + + /** * @param handler event handler */ @@ -51,18 +51,18 @@ public class KeyBinding implements KeyEventHandler { { this.handler = handler; } - - + + @Override public void receive(KeyEvent event) { final boolean nowDown = keystroke.isDown(); - + boolean trigger = false; trigger |= (edge == Trigger.FALLING && (!wasDown && nowDown)); trigger |= (edge == Trigger.RISING && (wasDown && !nowDown)); wasDown = nowDown; - + // run handler when event was met if (trigger) { handler.run(); diff --git a/src/mightypork/gamecore/input/KeyBindingPool.java b/src/mightypork/gamecore/input/KeyBindingPool.java index 3d60813..53701bb 100644 --- a/src/mightypork/gamecore/input/KeyBindingPool.java +++ b/src/mightypork/gamecore/input/KeyBindingPool.java @@ -16,10 +16,10 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public class KeyBindingPool implements KeyBinder, KeyEventHandler { - + private final Set bindings = new HashSet<>(); - - + + /** * Bind handler to a keystroke, replace current handler if any * @@ -36,11 +36,11 @@ public class KeyBindingPool implements KeyBinder, KeyEventHandler { return; } } - + bindings.add(new KeyBinding(stroke, edge, task)); } - - + + /** * Remove handler from keystroke (id any) * @@ -50,7 +50,7 @@ public class KeyBindingPool implements KeyBinder, KeyEventHandler { public void unbindKey(KeyStroke stroke) { final Iterator iter = bindings.iterator(); - + while (iter.hasNext()) { final KeyBinding kb = iter.next(); if (kb.matches(stroke)) { @@ -59,8 +59,8 @@ public class KeyBindingPool implements KeyBinder, KeyEventHandler { } } } - - + + @Override public void receive(KeyEvent event) { diff --git a/src/mightypork/gamecore/input/KeyStroke.java b/src/mightypork/gamecore/input/KeyStroke.java index fd94428..e08bff5 100644 --- a/src/mightypork/gamecore/input/KeyStroke.java +++ b/src/mightypork/gamecore/input/KeyStroke.java @@ -1,7 +1,7 @@ package mightypork.gamecore.input; -import mightypork.utils.string.StringUtil; +import mightypork.utils.Str; /** @@ -10,11 +10,11 @@ import mightypork.utils.string.StringUtil; * @author Ondřej Hruška (MightyPork) */ public class KeyStroke { - + private byte mod; private Key key; - - + + /** * Create a Key Stroke * @@ -25,8 +25,8 @@ public class KeyStroke { { setTo(key, modmask); } - - + + /** * Change to...
* (KeyStroke is mutable, so that upon changing it in Config, all existing @@ -40,8 +40,8 @@ public class KeyStroke { this.key = key; this.mod = (byte) (modmask | Keys.keyToMod(key)); // for mods alone } - - + + /** * Create a new keystroke without modifiers * @@ -51,8 +51,8 @@ public class KeyStroke { { this(key, Keys.MOD_NONE); } - - + + /** * Get if the key is down and modifiers match * @@ -62,58 +62,58 @@ public class KeyStroke { { return key.isDown() && (Keys.getActiveMods() == mod); } - - + + public String saveToString() { return Keys.modToString(mod) + "+" + key.getName(); } - - + + public static KeyStroke createFromString(String dataString) { final KeyStroke ks = new KeyStroke(Keys.NONE, Keys.MOD_NONE); ks.loadFromString(dataString); return ks; } - - + + public void loadFromString(String dataString) { final String dataString1 = dataString.toUpperCase().replace('-', '+').replaceAll("[^A-Z0-9_+]", ""); - + if (dataString1.contains("+")) { - - final String keyStr = StringUtil.fromLastChar(dataString1, '+'); - final String modStr = StringUtil.toLastChar(dataString1, '+'); - + + final String keyStr = Str.fromLast(dataString1, '+'); + final String modStr = Str.toLast(dataString1, '+'); + setTo(Keys.stringToKey(keyStr), Keys.stringToMod(modStr)); - + } else { setTo(Keys.stringToKey(dataString1), Keys.MOD_NONE); } } - - + + public Key getKey() { return key; } - - + + public byte getMod() { return mod; } - - + + @Override public String toString() { return saveToString(); } - - + + @Override public int hashCode() { @@ -123,8 +123,8 @@ public class KeyStroke { result = prime * result + mod; return result; } - - + + @Override public boolean equals(Object obj) { diff --git a/src/mightypork/gamecore/input/Keys.java b/src/mightypork/gamecore/input/Keys.java index 7949dca..57b3674 100644 --- a/src/mightypork/gamecore/input/Keys.java +++ b/src/mightypork/gamecore/input/Keys.java @@ -18,10 +18,10 @@ import mightypork.utils.logging.Log; * @author Ondřej Hruška (MightyPork) */ public class Keys { - + //@formatter:off public static final Key NONE = new Key("NONE", "NULL"); - + public static final Key NUM_0 = new Key("0", "ZERO"); public static final Key NUM_1 = new Key("1", "ONE"); public static final Key NUM_2 = new Key("2", "TWO"); @@ -32,7 +32,7 @@ public class Keys { public static final Key NUM_7 = new Key("7", "SEVEN"); public static final Key NUM_8 = new Key("8", "EIGHT"); public static final Key NUM_9 = new Key("9", "NINE"); - + public static final Key Q = new Key("Q"); public static final Key W = new Key("W"); public static final Key E = new Key("E"); @@ -59,7 +59,7 @@ public class Keys { public static final Key B = new Key("B"); public static final Key N = new Key("N"); public static final Key M = new Key("M"); - + public static final Key MINUS = new Key("MINUS", "DASH"); public static final Key EQUALS = new Key("EQUALS"); public static final Key SLASH = new Key("SLASH"); @@ -71,18 +71,18 @@ public class Keys { public static final Key GRAVE = new Key("GRAVE", "ACCENT"); public static final Key COMMA = new Key("COMMA"); public static final Key PERIOD = new Key("PERIOD", "DOT", "POINT"); - + public static final Key SPACE = new Key("SPACE", "SPACEBAR"); public static final Key BACKSPACE = new Key("BACKSPACE", "BACK"); public static final Key TAB = new Key("TAB", "TABULATOR", "INDENT"); public static final Key ESCAPE = new Key("ESC", "ESCAPE"); - + // those probably can't be used public static final Key APPS = new Key("APPS"); public static final Key POWER = new Key("POWER"); public static final Key SLEEP = new Key("SLEEP"); public static final Key MENU = new Key("MENU"); - + public static final Key F1 = new Key("F1"); public static final Key F2 = new Key("F2"); public static final Key F3 = new Key("F3"); @@ -98,12 +98,12 @@ public class Keys { public static final Key F13 = new Key("F13"); public static final Key F14 = new Key("F14"); public static final Key F15 = new Key("F15"); - + // probably not possible to bind to those. public static final Key CAPS_LOCK = new Key("CAPSLOCK", "CAPS", "CAPITAL"); public static final Key SCROLL_LOCK = new Key("SCROLL", "SCROLL_LOCK"); public static final Key NUM_LOCK = new Key("NUMLOCK"); - + public static final Key NUMPAD_MINUS = new Key("SUBTRACT", "NUMPAD_MINUS", "NUMPAD_SUBTRACT"); public static final Key NUMPAD_PLUSS = new Key("ADD", "NUMPAD_PLUS", "NUMPAD_ADD"); public static final Key NUMPAD_0 = new Key("NUMPAD_0"); @@ -120,7 +120,7 @@ public class Keys { public static final Key NUMPAD_ENTER = new Key("NUMPAD_ENTER", "NUMPADRETURN", "NUMPAD_RETURN"); public static final Key NUMPAD_DIVIDE = new Key("DIVIDE", "NUMPAD_DIVIDE", "NUMPAD_SLASH"); public static final Key NUMPAD_MULTIPLY = new Key("MULTIPLY", "NUMPAD_MULTIPLY", "NUMPAD_ASTERISK"); - + public static final Key CONTROL_LEFT = new Key("LCONTROL", "LEFT_CONTROL", "LCTRL", "LEFT_CTRL"); public static final Key CONTROL_RIGHT = new Key("RCONTROL", "RIGHT_CONTROL", "RCTRL", "RIGHT_CTRL"); public static final Key ALT_LEFT = new Key("LALT", "LMENU", "LEFT_MENU"); @@ -129,24 +129,24 @@ public class Keys { public static final Key SHIFT_RIGHT = new Key("RSHIFT", "RIGHT_SHIFT"); public static final Key META_LEFT = new Key("LMETA", "LEFT_META", "LWIN", "LEFT_WIN"); public static final Key META_RIGHT = new Key("RMETA", "RIGHT_META", "RWIN", "RIGHT_WIN"); - + public static final Key UP = new Key("UP", "ARROW_UP"); public static final Key DOWN = new Key("DOWN", "ARROW_DOWN"); public static final Key LEFT = new Key("LEFT", "ARROW_LEFT"); public static final Key RIGHT = new Key("RIGHT", "ARROW_RIGHT"); - + public static final Key HOME = new Key("HOME"); public static final Key END = new Key("END"); - + public static final Key PAGE_UP = new Key("PAGE_UP", "PGUP", "PRIOR"); public static final Key PAGE_DOWN = new Key("PAGE_DOWN", "PGDN", "NEXT"); - + public static final Key RETURN = new Key("ENTER", "RETURN", "CR"); public static final Key PAUSE = new Key("PAUSE", "BREAK"); public static final Key INSERT = new Key("INSERT"); public static final Key DELETE = new Key("DELETE"); public static final Key SYSRQ = new Key("SYSRQ"); // wtf is this anyway? - + // here go modifier bits public static final byte MOD_NONE = 0; public static final byte MOD_ALT = 1; @@ -154,51 +154,51 @@ public class Keys { public static final byte MOD_SHIFT = 4; public static final byte MOD_META = 8; //@formatter:on - + private static Map lookupByCode = new HashMap<>(100); private static List keyList = new ArrayList<>(100); - + static { // define none key NONE.setCode(0); - + // Use reflection to find keys final Field[] fields = Keys.class.getFields(); try { for (final Field field : fields) { final int modifiers = field.getModifiers(); if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && Modifier.isFinal(modifiers) && field.getType().equals(Key.class)) { - + keyList.add((Key) field.get(null)); } } } catch (final Exception e) {} } - - + + /** * Build lookup table by key codes */ private static void buildCodeLookupTable() { lookupByCode.clear(); - + lookupByCode.put(NONE.getCode(), NONE); - + for (final Key k : keyList) { if (!k.isDefined()) continue; if (!lookupByCode.containsKey(k.getCode())) { lookupByCode.put(k.getCode(), k); } } - + if (lookupByCode.size() == 1) { // NONE alone Log.w("Key codes are not ininitialized."); } } - - + + /** * Convert a key name to a key code. * @@ -210,13 +210,13 @@ public class Keys { for (final Key k : keyList) { if (k.matches(keyStr)) return k; } - + Log.w("No such key: " + keyStr); - + return NONE; } - - + + /** * Convert a mod description to a mod mask. A mod description is a string * containing CTRL,ALT,SHIFT,META, as in CTRL+ALT.
@@ -230,29 +230,29 @@ public class Keys { public static int stringToMod(String modStr) { int mod_mask = MOD_NONE; - + modStr = modStr.toUpperCase(); - + if (modStr.contains("CTRL")) { mod_mask |= MOD_CONTROL; } - + if (modStr.contains("ALT")) { mod_mask |= MOD_ALT; } - + if (modStr.contains("SHIFT")) { mod_mask |= MOD_SHIFT; } - + if (modStr.contains("META") || modStr.contains("WIN")) { mod_mask |= MOD_META; } - + return mod_mask; } - - + + /** * Convert a mod mask to a mod description, in a format recognized by * stringToMod() - joining mods by +. @@ -263,30 +263,30 @@ public class Keys { public static String modToString(int modMask) { String s = ""; - + if ((modMask & MOD_CONTROL) != 0) { s += "CTRL"; } - + if ((modMask & MOD_ALT) != 0) { if (!s.isEmpty()) s += "+"; s += "ALT"; } - + if ((modMask & MOD_SHIFT) != 0) { if (!s.isEmpty()) s += "+"; s += "SHIFT"; } - + if ((modMask & MOD_META) != 0) { if (!s.isEmpty()) s += "+"; s += "META"; } - + return s; } - - + + /** * Get a {@link Key} for key code. * @@ -296,18 +296,18 @@ public class Keys { public static Key codeToKey(int keyCode) { if (lookupByCode.isEmpty()) buildCodeLookupTable(); - + Key k = lookupByCode.get(keyCode); - + if (k == null) { Log.w("No key for code: " + keyCode); k = NONE; } - + return k; } - - + + /** * Convert a key to mod mask, in case the key is one of the mod keys. * @@ -316,17 +316,17 @@ public class Keys { */ public static int keyToMod(Key key) { - + if (key == SHIFT_LEFT || key == SHIFT_RIGHT) return MOD_SHIFT; - + if (key == CONTROL_LEFT || key == CONTROL_RIGHT) return MOD_CONTROL; if (key == ALT_LEFT || key == ALT_RIGHT) return MOD_ALT; if (key == META_LEFT || key == META_RIGHT) return MOD_META; - + return MOD_NONE; } - - + + /** * Get if the given key is down (call it's "isDown()" method).
* This method is here just for completeness, since the getActiveMod() is @@ -339,8 +339,8 @@ public class Keys { { return key.isDown(); } - - + + /** * Get currently active key modifiers * @@ -349,26 +349,26 @@ public class Keys { public static int getActiveMods() { int mods = 0; - + final InputModule inp = App.input(); - + if (inp.isKeyDown(Keys.ALT_LEFT) || inp.isKeyDown(Keys.ALT_RIGHT)) { mods |= Keys.MOD_ALT; } - + if (inp.isKeyDown(Keys.SHIFT_LEFT) || inp.isKeyDown(Keys.SHIFT_RIGHT)) { mods |= Keys.MOD_SHIFT; } - + if (inp.isKeyDown(Keys.CONTROL_LEFT) || inp.isKeyDown(Keys.CONTROL_RIGHT)) { mods |= Keys.MOD_CONTROL; } - + if (inp.isKeyDown(Keys.META_LEFT) || inp.isKeyDown(Keys.META_RIGHT)) { mods |= Keys.MOD_META; } - + return mods; } - + } diff --git a/src/mightypork/gamecore/input/events/KeyEvent.java b/src/mightypork/gamecore/input/events/KeyEvent.java index eedc5a5..8a35e57 100644 --- a/src/mightypork/gamecore/input/events/KeyEvent.java +++ b/src/mightypork/gamecore/input/events/KeyEvent.java @@ -13,12 +13,12 @@ import mightypork.utils.eventbus.events.flags.NotLoggedEvent; */ @NotLoggedEvent public class KeyEvent extends BusEvent { - + private final int key; private final boolean down; private final char c; - - + + /** * @param key key that triggered the event. Can be KEY_NONE. * @param c typed char (can be zero char) @@ -30,8 +30,8 @@ public class KeyEvent extends BusEvent { this.c = c; this.down = down; } - - + + /** * @return key code */ @@ -39,8 +39,8 @@ public class KeyEvent extends BusEvent { { return key; } - - + + /** * @return true if key was just pressed */ @@ -48,8 +48,8 @@ public class KeyEvent extends BusEvent { { return down; } - - + + /** * @return true if key was just released */ @@ -57,8 +57,8 @@ public class KeyEvent extends BusEvent { { return !down; } - - + + /** * @return event character (if any) */ @@ -66,20 +66,20 @@ public class KeyEvent extends BusEvent { { return c; } - - + + @Override public void handleBy(KeyEventHandler keh) { keh.receive(this); } - - + + @Override public String toString() { // FIXME return Keys.codeToKey(key).getName() + ":" + (down ? "DOWN" : "UP"); } - + } diff --git a/src/mightypork/gamecore/input/events/KeyEventHandler.java b/src/mightypork/gamecore/input/events/KeyEventHandler.java index c058ee7..67f4c61 100644 --- a/src/mightypork/gamecore/input/events/KeyEventHandler.java +++ b/src/mightypork/gamecore/input/events/KeyEventHandler.java @@ -7,7 +7,7 @@ package mightypork.gamecore.input.events; * @author Ondřej Hruška (MightyPork) */ public interface KeyEventHandler { - + /** * Handle an event * diff --git a/src/mightypork/gamecore/input/events/MouseButtonEvent.java b/src/mightypork/gamecore/input/events/MouseButtonEvent.java index d2e671f..cda4fa2 100644 --- a/src/mightypork/gamecore/input/events/MouseButtonEvent.java +++ b/src/mightypork/gamecore/input/events/MouseButtonEvent.java @@ -15,17 +15,17 @@ import mightypork.utils.math.constraints.vect.VectConst; */ @NotLoggedEvent public class MouseButtonEvent extends BusEvent { - + public static final int BUTTON_LEFT = 0; public static final int BUTTON_MIDDLE = 1; public static final int BUTTON_RIGHT = 2; - + private final int button; private final int wheeld; private final VectConst pos; private final boolean down; - - + + /** * Mouse button event * @@ -41,8 +41,8 @@ public class MouseButtonEvent extends BusEvent { this.pos = pos.freeze(); this.wheeld = wheeld; } - - + + /** * @return true if the event was caused by a button state change */ @@ -50,8 +50,8 @@ public class MouseButtonEvent extends BusEvent { { return button != -1; } - - + + /** * @return true if the event was caused by a wheel change */ @@ -59,8 +59,8 @@ public class MouseButtonEvent extends BusEvent { { return wheeld != 0; } - - + + /** * @return button id or -1 if none was pressed */ @@ -68,8 +68,8 @@ public class MouseButtonEvent extends BusEvent { { return button; } - - + + /** * @return number of steps the wheel changed since last event */ @@ -77,8 +77,8 @@ public class MouseButtonEvent extends BusEvent { { return wheeld; } - - + + /** * @return mouse position when the event occurred */ @@ -86,8 +86,8 @@ public class MouseButtonEvent extends BusEvent { { return pos; } - - + + /** * @return true if button was just pressed */ @@ -95,8 +95,8 @@ public class MouseButtonEvent extends BusEvent { { return button != -1 && down; } - - + + /** * @return true if button was just released */ @@ -104,8 +104,8 @@ public class MouseButtonEvent extends BusEvent { { return button != -1 && !down; } - - + + /** * Get if event happened over a rect * @@ -116,8 +116,8 @@ public class MouseButtonEvent extends BusEvent { { return rect.getRect().contains(pos); } - - + + @Override public void handleBy(MouseButtonHandler handler) { diff --git a/src/mightypork/gamecore/input/events/MouseButtonHandler.java b/src/mightypork/gamecore/input/events/MouseButtonHandler.java index 317b6c0..4dc0297 100644 --- a/src/mightypork/gamecore/input/events/MouseButtonHandler.java +++ b/src/mightypork/gamecore/input/events/MouseButtonHandler.java @@ -7,7 +7,7 @@ package mightypork.gamecore.input.events; * @author Ondřej Hruška (MightyPork) */ public interface MouseButtonHandler { - + /** * Handle an event * diff --git a/src/mightypork/gamecore/input/events/MouseMotionEvent.java b/src/mightypork/gamecore/input/events/MouseMotionEvent.java index d36cc9f..648b061 100644 --- a/src/mightypork/gamecore/input/events/MouseMotionEvent.java +++ b/src/mightypork/gamecore/input/events/MouseMotionEvent.java @@ -14,11 +14,11 @@ import mightypork.utils.math.constraints.vect.VectConst; */ @NotLoggedEvent public class MouseMotionEvent extends BusEvent { - + private final VectConst move; private final VectConst pos; - - + + /** * @param pos end pos * @param move move vector @@ -28,8 +28,8 @@ public class MouseMotionEvent extends BusEvent { this.move = move.freeze(); this.pos = pos.freeze(); } - - + + /** * @return movement since last {@link MouseMotionEvent} */ @@ -37,8 +37,8 @@ public class MouseMotionEvent extends BusEvent { { return move; } - - + + /** * @return current mouse position */ @@ -46,12 +46,12 @@ public class MouseMotionEvent extends BusEvent { { return pos; } - - + + @Override public void handleBy(MouseMotionHandler keh) { keh.receive(this); } - + } diff --git a/src/mightypork/gamecore/input/events/MouseMotionHandler.java b/src/mightypork/gamecore/input/events/MouseMotionHandler.java index 38fd663..38ee5c0 100644 --- a/src/mightypork/gamecore/input/events/MouseMotionHandler.java +++ b/src/mightypork/gamecore/input/events/MouseMotionHandler.java @@ -7,7 +7,7 @@ package mightypork.gamecore.input.events; * @author Ondřej Hruška (MightyPork) */ public interface MouseMotionHandler { - + /** * Handle an event * diff --git a/src/mightypork/gamecore/resources/BaseDeferredResource.java b/src/mightypork/gamecore/resources/BaseDeferredResource.java index 8cf91a6..1956334 100644 --- a/src/mightypork/gamecore/resources/BaseDeferredResource.java +++ b/src/mightypork/gamecore/resources/BaseDeferredResource.java @@ -3,11 +3,11 @@ package mightypork.gamecore.resources; import java.io.IOException; +import mightypork.utils.Str; import mightypork.utils.annotations.Alias; import mightypork.utils.interfaces.Destroyable; import mightypork.utils.logging.Log; import mightypork.utils.math.timing.Profiler; -import mightypork.utils.string.StringUtil; /** @@ -17,12 +17,12 @@ import mightypork.utils.string.StringUtil; */ @Alias(name = "Resource") public abstract class BaseDeferredResource implements DeferredResource, Destroyable { - + private final String resource; private volatile boolean loadFailed = false; private volatile boolean loadAttempted = false; - - + + /** * @param resource resource path / name; this string is later used in * loadResource() @@ -31,45 +31,45 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya { this.resource = resource; } - - + + @Override public synchronized final void load() { if (!loadFailed && loadAttempted) return; - + // // if (loadFailed) return; // if (loadAttempted) return; // - + loadAttempted = true; loadFailed = false; - + try { if (resource == null) { throw new NullPointerException("Resource string cannot be null for non-null resource."); } - + final long time = Profiler.begin(); Log.f3("(res) + Load: " + this); loadResource(resource); Log.f3("(res) - Done: " + this + " in " + Profiler.endStr(time)); - + } catch (final Throwable t) { loadFailed = true; Log.e("(res) Failed to load: " + this, t); } } - - + + @Override public synchronized final boolean isLoaded() { return loadAttempted && !loadFailed; } - - + + /** * Check if the resource is loaded; if not, try to do so. * @@ -81,15 +81,15 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya return true; } else { if (loadFailed) return false; - + Log.f3("(res) !! Loading on access: " + this); load(); } - + return isLoaded(); } - - + + /** * Load the resource. Called from load() - once only. * @@ -98,19 +98,19 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya * loaded. */ protected abstract void loadResource(String resource) throws IOException; - - + + @Override public abstract void destroy(); - - + + @Override public String toString() { - return StringUtil.fromLastChar(resource, '/'); + return Str.fromLast(resource, '/'); } - - + + @Override public int hashCode() { @@ -119,8 +119,8 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya result = prime * result + ((resource == null) ? 0 : resource.hashCode()); return result; } - - + + @Override public boolean equals(Object obj) { diff --git a/src/mightypork/gamecore/resources/DeferredResource.java b/src/mightypork/gamecore/resources/DeferredResource.java index 888cb9e..67af186 100644 --- a/src/mightypork/gamecore/resources/DeferredResource.java +++ b/src/mightypork/gamecore/resources/DeferredResource.java @@ -7,13 +7,13 @@ package mightypork.gamecore.resources; * @author Ondřej Hruška (MightyPork) */ public interface DeferredResource { - + /** * Load the actual resource, if not loaded yet. */ void load(); - - + + /** * Check if resource was successfully loaded. * diff --git a/src/mightypork/gamecore/resources/Res.java b/src/mightypork/gamecore/resources/Res.java index 1528cb0..a131f92 100644 --- a/src/mightypork/gamecore/resources/Res.java +++ b/src/mightypork/gamecore/resources/Res.java @@ -18,12 +18,12 @@ import mightypork.gamecore.graphics.textures.TxSheet; * @author Ondřej Hruška (MightyPork) */ public final class Res { - + private static TextureRegistry textures = new TextureRegistry(); private static SoundRegistry sounds = new SoundRegistry(); private static FontRegistry fonts = new FontRegistry(); - - + + /** * Get a texture by key * @@ -34,8 +34,8 @@ public final class Res { { return textures.getTexture(key); } - - + + /** * Get a texture sheet by key * @@ -46,8 +46,8 @@ public final class Res { { return textures.getSheet(key); } - - + + /** * Get a texture quad by key * @@ -58,8 +58,8 @@ public final class Res { { return textures.getQuad(key); } - - + + /** * Get a sound loop player by key * @@ -70,8 +70,8 @@ public final class Res { { return sounds.getLoop(key); } - - + + /** * Get a sound effect player by key * @@ -82,8 +82,8 @@ public final class Res { { return sounds.getEffect(key); } - - + + /** * Get a font by key * @@ -94,8 +94,8 @@ public final class Res { { return fonts.getFont(key); } - - + + /** * Get internal texture registry * @@ -105,8 +105,8 @@ public final class Res { { return textures; } - - + + /** * Get internal font registry * @@ -116,8 +116,8 @@ public final class Res { { return fonts; } - - + + /** * Get internal sound registry * @@ -127,8 +127,8 @@ public final class Res { { return sounds; } - - + + /** * Load resources by a resource initializer. * @@ -140,5 +140,5 @@ public final class Res { initializer.addTextures(textures); initializer.addSounds(sounds); } - + } diff --git a/src/mightypork/gamecore/resources/ResourceInitializer.java b/src/mightypork/gamecore/resources/ResourceInitializer.java index 346eae2..b1cee0a 100644 --- a/src/mightypork/gamecore/resources/ResourceInitializer.java +++ b/src/mightypork/gamecore/resources/ResourceInitializer.java @@ -12,23 +12,23 @@ import mightypork.gamecore.graphics.textures.TextureRegistry; * @author Ondřej Hruška (MightyPork) */ public interface ResourceInitializer { - + /** * Add fonts to load. * * @param fonts font registry */ void addFonts(FontRegistry fonts); - - + + /** * Add sounds to load. * * @param sounds sound registry */ void addSounds(SoundRegistry sounds); - - + + /** * Add textures to load * diff --git a/src/mightypork/gamecore/resources/loading/AsyncResourceLoader.java b/src/mightypork/gamecore/resources/loading/AsyncResourceLoader.java index 2976c51..29452cd 100644 --- a/src/mightypork/gamecore/resources/loading/AsyncResourceLoader.java +++ b/src/mightypork/gamecore/resources/loading/AsyncResourceLoader.java @@ -9,7 +9,7 @@ import mightypork.gamecore.core.App; import mightypork.gamecore.core.events.MainLoopRequest; import mightypork.gamecore.resources.DeferredResource; import mightypork.utils.Reflect; -import mightypork.utils.Support; +import mightypork.utils.Str; import mightypork.utils.interfaces.Destroyable; import mightypork.utils.logging.Log; @@ -20,14 +20,14 @@ 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 toLoad = new LinkedBlockingQueue<>(); private volatile boolean stopped; private volatile boolean mainLoopQueuing = true; - - + + /** * Create a resource loader. */ @@ -35,17 +35,16 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr { 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 @@ -57,23 +56,23 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr { 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)); - + Log.f3("(loader) Delegating to main thread: " + Str.val(resource)); + App.bus().send(new MainLoopRequest(new Runnable() { - + @Override public void run() { @@ -81,31 +80,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)); - + + Log.f3("(loader) Scheduling... " + Str.val(def)); + exs.submit(new Runnable() { - + @Override public void run() { @@ -115,15 +114,15 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr } }); } - + } catch (final InterruptedException ignored) { // } - + } } - - + + // apparently, destroy method exists on thread :/ @SuppressWarnings("deprecation") @Override @@ -133,5 +132,5 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr stopped = true; exs.shutdownNow(); } - + } diff --git a/src/mightypork/gamecore/resources/loading/ResourceLoadRequest.java b/src/mightypork/gamecore/resources/loading/ResourceLoadRequest.java index e95d05e..2e6ccee 100644 --- a/src/mightypork/gamecore/resources/loading/ResourceLoadRequest.java +++ b/src/mightypork/gamecore/resources/loading/ResourceLoadRequest.java @@ -13,10 +13,10 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent; */ @SingleReceiverEvent public class ResourceLoadRequest extends BusEvent { - + private final DeferredResource resource; - - + + /** * @param resource resource to load */ @@ -24,8 +24,8 @@ public class ResourceLoadRequest extends BusEvent { { this.resource = resource; } - - + + @Override public void handleBy(ResourceLoader handler) { diff --git a/src/mightypork/gamecore/resources/loading/ResourceLoader.java b/src/mightypork/gamecore/resources/loading/ResourceLoader.java index c96590b..5586d71 100644 --- a/src/mightypork/gamecore/resources/loading/ResourceLoader.java +++ b/src/mightypork/gamecore/resources/loading/ResourceLoader.java @@ -10,15 +10,15 @@ 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 thread etc) *