diff --git a/src/mightypork/gamecore/control/BaseApp.java b/src/mightypork/gamecore/control/BaseApp.java index cbccdba..a23b829 100644 --- a/src/mightypork/gamecore/control/BaseApp.java +++ b/src/mightypork/gamecore/control/BaseApp.java @@ -8,14 +8,12 @@ import java.util.logging.Level; import javax.swing.JOptionPane; import mightypork.gamecore.audio.SoundSystem; -import mightypork.gamecore.control.events.*; +import mightypork.gamecore.control.events.DestroyEvent; import mightypork.gamecore.gui.screens.ScreenRegistry; import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.render.DisplaySystem; import mightypork.util.annotations.DefaultImpl; -import mightypork.util.control.Destroyable; import mightypork.util.control.eventbus.EventBus; -import mightypork.util.control.timing.Updateable; import mightypork.util.files.InstanceLock; import mightypork.util.logging.Log; import mightypork.util.logging.writers.LogWriter; @@ -86,7 +84,6 @@ public abstract class BaseApp implements AppAccess, UncaughtExceptionHandler { eventBus = new EventBus(); Log.f3("Registering channels..."); - initDefaultBusChannels(eventBus); initBus(eventBus); /* @@ -236,8 +233,8 @@ public abstract class BaseApp implements AppAccess, UncaughtExceptionHandler { /** - * Initialize event bus (ie. add custom channels)
- * When overriding, must call super! + * Initialize event bus. Usually, no action is needed, since the bus + * automatically recognizes new event types. * * @param bus */ @@ -247,26 +244,6 @@ public abstract class BaseApp implements AppAccess, UncaughtExceptionHandler { } - private void initDefaultBusChannels(EventBus bus) - { - // framework events - bus.addChannel(DestroyEvent.class, Destroyable.class); - bus.addChannel(UpdateEvent.class, Updateable.class); - bus.addChannel(LayoutChangeEvent.class, LayoutChangeEvent.Listener.class); - - // input events - bus.addChannel(ViewportChangeEvent.class, ViewportChangeEvent.Listener.class); - bus.addChannel(KeyEvent.class, KeyEvent.Listener.class); - bus.addChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class); - bus.addChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class); - - // control events - bus.addChannel(ScreenRequestEvent.class, ScreenRequestEvent.Listener.class); - bus.addChannel(ResourceLoadRequest.class, ResourceLoadRequest.Listener.class); - bus.addChannel(MainLoopTaskRequest.class, MainLoopTaskRequest.Listener.class); - } - - /* * Try to obtain lock. */ diff --git a/src/mightypork/gamecore/gui/components/VisualComponent.java b/src/mightypork/gamecore/gui/components/VisualComponent.java index 0ec9641..ea10462 100644 --- a/src/mightypork/gamecore/gui/components/VisualComponent.java +++ b/src/mightypork/gamecore/gui/components/VisualComponent.java @@ -2,6 +2,7 @@ package mightypork.gamecore.gui.components; import mightypork.gamecore.control.events.LayoutChangeEvent; +import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.render.Renderable; import mightypork.util.annotations.DefaultImpl; import mightypork.util.constraints.rect.Rect; @@ -86,6 +87,12 @@ public abstract class VisualComponent extends AbstractRectCache implements Compo } + protected boolean isMouseOver() + { + return InputSystem.getMousePos().isInside(this); + } + + /** * Draw the component (it's visible) */ diff --git a/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java b/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java index 6082ada..b36cef5 100644 --- a/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java +++ b/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java @@ -26,7 +26,7 @@ public class ColumnHolder extends LayoutComponent { */ public ColumnHolder(AppAccess app, RectBound context, int cols) { super(app, context); - this.tiler = columns(cols).zeroBased(); + this.tiler = columns(cols); } diff --git a/src/mightypork/gamecore/gui/components/layout/GridLayout.java b/src/mightypork/gamecore/gui/components/layout/GridLayout.java new file mode 100644 index 0000000..e954df4 --- /dev/null +++ b/src/mightypork/gamecore/gui/components/layout/GridLayout.java @@ -0,0 +1,81 @@ +package mightypork.gamecore.gui.components.layout; + + +import mightypork.gamecore.control.AppAccess; +import mightypork.gamecore.gui.components.Component; +import mightypork.gamecore.gui.components.LayoutComponent; +import mightypork.util.constraints.rect.builders.TiledRect; +import mightypork.util.constraints.rect.proxy.RectBound; + + +/** + * Holder with table cells + * + * @author MightyPork + */ +public class GridLayout extends LayoutComponent { + + private final TiledRect tiler; + + + /** + * @param app app access + * @param context context + * @param rows number of rows + * @param cols number of columns + */ + public GridLayout(AppAccess app, RectBound context, int rows, int cols) { + super(app, context); + this.tiler = tiles(cols, rows); + } + + + /** + * make a new holder.
+ * Context must be assigned before rendering. + * + * @param app app access + * @param rows number of rows + * @param cols number of columns + */ + public GridLayout(AppAccess app, int rows, int cols) { + this(app, null, rows, cols); + } + + + /** + * Add a row to the holder. + * + * @param row row (one-based) + * @param column column (one-based) + * @param elem added component + */ + public void put(Component elem, int row, int column) + { + if (elem == null) return; + + elem.setRect(tiler.tile(column, row)); + + attach(elem); + } + + + /** + * Put with span + * + * @param row + * @param column + * @param rowspan + * @param colspan + * @param elem + */ + 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/HorizontalFixedFlowLayout.java b/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java index 7346c79..d6ff371 100644 --- a/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/HorizontalFixedFlowLayout.java @@ -18,8 +18,8 @@ import mightypork.util.constraints.rect.proxy.RectBound; public class HorizontalFixedFlowLayout extends LayoutComponent { private int col = 0; - private Num colWidth; - private AlignX align; + private final Num colWidth; + private final AlignX align; /** diff --git a/src/mightypork/gamecore/gui/components/layout/RowHolder.java b/src/mightypork/gamecore/gui/components/layout/RowHolder.java index 24261ff..73e3c53 100644 --- a/src/mightypork/gamecore/gui/components/layout/RowHolder.java +++ b/src/mightypork/gamecore/gui/components/layout/RowHolder.java @@ -38,7 +38,7 @@ public class RowHolder extends LayoutComponent { */ public RowHolder(AppAccess app, RectBound context, int rows) { super(app, context); - this.tiler = rows(rows).zeroBased(); + this.tiler = rows(rows); } diff --git a/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java b/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java index 6d9704c..5a3931c 100644 --- a/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java +++ b/src/mightypork/gamecore/gui/components/layout/VerticalFixedFlowLayout.java @@ -18,8 +18,8 @@ import mightypork.util.constraints.rect.proxy.RectBound; public class VerticalFixedFlowLayout extends LayoutComponent { private int row = 0; - private Num rowHeight; - private AlignY align; + private final Num rowHeight; + private final AlignY align; /** diff --git a/src/mightypork/gamecore/gui/screens/BaseScreen.java b/src/mightypork/gamecore/gui/screens/BaseScreen.java index 9af6388..92d8dfc 100644 --- a/src/mightypork/gamecore/gui/screens/BaseScreen.java +++ b/src/mightypork/gamecore/gui/screens/BaseScreen.java @@ -4,7 +4,6 @@ package mightypork.gamecore.gui.screens; import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.control.AppSubModule; import mightypork.gamecore.control.events.LayoutChangeEvent; -import mightypork.gamecore.control.events.ViewportChangeEvent; import mightypork.gamecore.input.KeyBinder; import mightypork.gamecore.input.KeyBindingPool; import mightypork.gamecore.input.KeyStroke; @@ -18,7 +17,7 @@ import mightypork.util.constraints.rect.Rect; * * @author MightyPork */ -public abstract class BaseScreen extends AppSubModule implements Screen, KeyBinder, ViewportChangeEvent.Listener { +public abstract class BaseScreen extends AppSubModule implements Screen, KeyBinder, LayoutChangeEvent.Listener { private final KeyBindingPool keybindings = new KeyBindingPool(); @@ -46,16 +45,16 @@ public abstract class BaseScreen extends AppSubModule implements Screen, KeyBind @Override - public final void bindKeyStroke(KeyStroke stroke, Runnable task) + public final void bindKey(KeyStroke stroke, Runnable task) { - keybindings.bindKeyStroke(stroke, task); + keybindings.bindKey(stroke, task); } @Override - public final void unbindKeyStroke(KeyStroke stroke) + public final void unbindKey(KeyStroke stroke) { - keybindings.unbindKeyStroke(stroke); + keybindings.unbindKey(stroke); } @@ -99,13 +98,10 @@ public abstract class BaseScreen extends AppSubModule implements Screen, KeyBind @Override - public final void onViewportChanged(ViewportChangeEvent event) + public void onLayoutChanged() { if (!isActive()) return; - // fire event - fireLayoutChangeEvent(); - needSetupViewport = true; } diff --git a/src/mightypork/gamecore/gui/screens/Overlay.java b/src/mightypork/gamecore/gui/screens/Overlay.java index 15d4f00..7654bbb 100644 --- a/src/mightypork/gamecore/gui/screens/Overlay.java +++ b/src/mightypork/gamecore/gui/screens/Overlay.java @@ -8,7 +8,6 @@ import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.control.AppSubModule; import mightypork.gamecore.control.events.LayoutChangeEvent; import mightypork.gamecore.gui.Hideable; -import mightypork.gamecore.gui.components.VisualComponent; import mightypork.gamecore.gui.components.layout.ConstraintLayout; import mightypork.gamecore.input.KeyBinder; import mightypork.gamecore.input.KeyBindingPool; @@ -57,16 +56,16 @@ public abstract class Overlay extends AppSubModule implements Updateable, Compar @Override - public final void bindKeyStroke(KeyStroke stroke, Runnable task) + public final void bindKey(KeyStroke stroke, Runnable task) { - keybindings.bindKeyStroke(stroke, task); + keybindings.bindKey(stroke, task); } @Override - public final void unbindKeyStroke(KeyStroke stroke) + public final void unbindKey(KeyStroke stroke) { - keybindings.unbindKeyStroke(stroke); + keybindings.unbindKey(stroke); } @@ -106,7 +105,7 @@ public abstract class Overlay extends AppSubModule implements Updateable, Compar @Override public void render() { - for (Renderable r : rendered) { + for (final Renderable r : rendered) { r.render(); } } @@ -115,7 +114,7 @@ public abstract class Overlay extends AppSubModule implements Updateable, Compar @Override public void update(double delta) { - for (Updateable u : updated) { + for (final Updateable u : updated) { u.update(delta); } } diff --git a/src/mightypork/gamecore/gui/screens/ScreenRegistry.java b/src/mightypork/gamecore/gui/screens/ScreenRegistry.java index 041ee03..9652a31 100644 --- a/src/mightypork/gamecore/gui/screens/ScreenRegistry.java +++ b/src/mightypork/gamecore/gui/screens/ScreenRegistry.java @@ -8,7 +8,9 @@ import java.util.TreeSet; import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.control.AppModule; +import mightypork.gamecore.control.events.LayoutChangeEvent; import mightypork.gamecore.control.events.ScreenRequestEvent; +import mightypork.gamecore.control.events.ViewportChangeEvent; import mightypork.gamecore.render.Renderable; import mightypork.util.annotations.DefaultImpl; import mightypork.util.logging.Log; @@ -19,7 +21,7 @@ import mightypork.util.logging.Log; * * @author MightyPork */ -public class ScreenRegistry extends AppModule implements ScreenRequestEvent.Listener, Renderable { +public class ScreenRegistry extends AppModule implements ScreenRequestEvent.Listener, ViewportChangeEvent.Listener, Renderable { private final Map screens = new HashMap<>(); private final Collection overlays = new TreeSet<>(); @@ -44,7 +46,6 @@ public class ScreenRegistry extends AppModule implements ScreenRequestEvent.List screens.put(screen.getName(), screen); addChildClient(screen); } - /** @@ -58,6 +59,7 @@ public class ScreenRegistry extends AppModule implements ScreenRequestEvent.List addChildClient(overlay); } + @Override public void showScreen(String key) { @@ -86,7 +88,7 @@ public class ScreenRegistry extends AppModule implements ScreenRequestEvent.List { if (active != null) { active.render(); - + for (final Overlay overlay : overlays) { if (overlay.isVisible()) overlay.render(); } @@ -101,4 +103,11 @@ public class ScreenRegistry extends AppModule implements ScreenRequestEvent.List // } + + @Override + public void onViewportChanged(ViewportChangeEvent event) + { + getEventBus().sendDirectToChildren(this, new LayoutChangeEvent()); + } + } diff --git a/src/mightypork/gamecore/input/InputSystem.java b/src/mightypork/gamecore/input/InputSystem.java index 859d2a3..c6260e7 100644 --- a/src/mightypork/gamecore/input/InputSystem.java +++ b/src/mightypork/gamecore/input/InputSystem.java @@ -29,7 +29,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { private final KeyBindingPool keybindings; /** Current mouse position */ - private final Vect mousePos = new Vect() { + private static final Vect mousePos = new Vect() { @Override public double x() @@ -90,16 +90,16 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { @Override - public final void bindKeyStroke(KeyStroke stroke, Runnable task) + public final void bindKey(KeyStroke stroke, Runnable task) { - keybindings.bindKeyStroke(stroke, task); + keybindings.bindKey(stroke, task); } @Override - public void unbindKeyStroke(KeyStroke stroke) + public void unbindKey(KeyStroke stroke) { - keybindings.unbindKeyStroke(stroke); + keybindings.unbindKey(stroke); } // counters as fields to save memory. @@ -179,7 +179,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { * * @return mouse position */ - public Vect getMousePos() + public static Vect getMousePos() { return mousePos; } @@ -188,7 +188,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { /** * @return true if mouse is inside window. */ - public boolean isMouseInside() + public static boolean isMouseInside() { return Mouse.isInsideWindow(); } @@ -199,7 +199,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { * * @param grab true to grab */ - public void grabMouse(boolean grab) + public static void grabMouse(boolean grab) { Mouse.setGrabbed(grab); } diff --git a/src/mightypork/gamecore/input/KeyBinder.java b/src/mightypork/gamecore/input/KeyBinder.java index b04fe84..ba3971c 100644 --- a/src/mightypork/gamecore/input/KeyBinder.java +++ b/src/mightypork/gamecore/input/KeyBinder.java @@ -17,7 +17,7 @@ public interface KeyBinder { * @param stroke trigger keystroke * @param task handler; can be {@link Runnable} or {@link Action} */ - void bindKeyStroke(KeyStroke stroke, Runnable task); + void bindKey(KeyStroke stroke, Runnable task); /** @@ -25,6 +25,6 @@ public interface KeyBinder { * * @param stroke stroke */ - void unbindKeyStroke(KeyStroke stroke); + void unbindKey(KeyStroke stroke); } diff --git a/src/mightypork/gamecore/input/KeyBindingPool.java b/src/mightypork/gamecore/input/KeyBindingPool.java index 8738ed9..0ee346d 100644 --- a/src/mightypork/gamecore/input/KeyBindingPool.java +++ b/src/mightypork/gamecore/input/KeyBindingPool.java @@ -26,11 +26,11 @@ public class KeyBindingPool implements KeyBinder, KeyEvent.Listener { * @param task handler */ @Override - public void bindKeyStroke(KeyStroke stroke, Runnable task) + public void bindKey(KeyStroke stroke, Runnable task) { for (final KeyBinding kb : bindings) { if (kb.matches(stroke)) { - Log.w("Duplicate KeyBinding (" + stroke + "), using newest handler."); + Log.w("Duplicate KeyBinding (" + stroke + "), replacing handler."); kb.setHandler(task); return; } @@ -46,7 +46,7 @@ public class KeyBindingPool implements KeyBinder, KeyEvent.Listener { * @param stroke stroke */ @Override - public void unbindKeyStroke(KeyStroke stroke) + public void unbindKey(KeyStroke stroke) { final Iterator iter = bindings.iterator(); diff --git a/src/mightypork/gamecore/input/Keys.java b/src/mightypork/gamecore/input/Keys.java index 29a86bd..435f2d6 100644 --- a/src/mightypork/gamecore/input/Keys.java +++ b/src/mightypork/gamecore/input/Keys.java @@ -13,128 +13,125 @@ public interface Keys { //@formatter:off - public static final int CHAR_NONE = '\0'; + public static final int NONE = 0x00; - public static final int KEY_NONE = 0x00; - - public static final int KEY_ESCAPE = 0x01; + public static final int ESCAPE = 0x01; - public static final int KEY_1 = 0x02; - public static final int KEY_2 = 0x03; - public static final int KEY_3 = 0x04; - public static final int KEY_4 = 0x05; - public static final int KEY_5 = 0x06; - public static final int KEY_6 = 0x07; - public static final int KEY_7 = 0x08; - public static final int KEY_8 = 0x09; - public static final int KEY_9 = 0x0A; - public static final int KEY_0 = 0x0B; + public static final int NUM_1 = 0x02; + public static final int NUM_2 = 0x03; + public static final int NUM_3 = 0x04; + public static final int NUM_4 = 0x05; + public static final int NUM_5 = 0x06; + public static final int NUM_6 = 0x07; + public static final int NUM_7 = 0x08; + public static final int NUM_8 = 0x09; + public static final int NUM_9 = 0x0A; + public static final int NUM_0 = 0x0B; - public static final int KEY_Q = 0x10; - public static final int KEY_W = 0x11; - public static final int KEY_E = 0x12; - public static final int KEY_R = 0x13; - public static final int KEY_T = 0x14; - public static final int KEY_Y = 0x15; - public static final int KEY_U = 0x16; - public static final int KEY_I = 0x17; - public static final int KEY_O = 0x18; - public static final int KEY_P = 0x19; - public static final int KEY_A = 0x1E; - public static final int KEY_S = 0x1F; - public static final int KEY_D = 0x20; - public static final int KEY_F = 0x21; - public static final int KEY_G = 0x22; - public static final int KEY_H = 0x23; - public static final int KEY_J = 0x24; - public static final int KEY_K = 0x25; - public static final int KEY_L = 0x26; - public static final int KEY_Z = 0x2C; - public static final int KEY_X = 0x2D; - public static final int KEY_C = 0x2E; - public static final int KEY_V = 0x2F; - public static final int KEY_B = 0x30; - public static final int KEY_N = 0x31; - public static final int KEY_M = 0x32; + public static final int Q = 0x10; + public static final int W = 0x11; + public static final int E = 0x12; + public static final int R = 0x13; + public static final int T = 0x14; + public static final int Y = 0x15; + public static final int U = 0x16; + public static final int I = 0x17; + public static final int O = 0x18; + public static final int P = 0x19; + public static final int A = 0x1E; + public static final int S = 0x1F; + public static final int D = 0x20; + public static final int F = 0x21; + public static final int G = 0x22; + public static final int H = 0x23; + public static final int J = 0x24; + public static final int K = 0x25; + public static final int L = 0x26; + public static final int Z = 0x2C; + public static final int X = 0x2D; + public static final int C = 0x2E; + public static final int V = 0x2F; + public static final int B = 0x30; + public static final int N = 0x31; + public static final int M = 0x32; - public static final int KEY_MINUS = 0x0C; - public static final int KEY_EQUALS = 0x0D; - public static final int KEY_SLASH = 0x35; - public static final int KEY_BACKSLASH = 0x2B; - public static final int KEY_LBRACKET = 0x1A; - public static final int KEY_RBRACKET = 0x1B; - public static final int KEY_SEMICOLON = 0x27; - public static final int KEY_APOSTROPHE = 0x28; - public static final int KEY_GRAVE = 0x29; - public static final int KEY_COMMA = 0x33; - public static final int KEY_PERIOD = 0x34; + public static final int MINUS = 0x0C; + public static final int EQUALS = 0x0D; + public static final int SLASH = 0x35; + public static final int BACKSLASH = 0x2B; + public static final int L_BRACKET = 0x1A; + public static final int R_BRACKET = 0x1B; + public static final int SEMICOLON = 0x27; + public static final int APOSTROPHE = 0x28; + public static final int GRAVE = 0x29; + public static final int COMMA = 0x33; + public static final int PERIOD = 0x34; - public static final int KEY_SPACE = 0x39; - public static final int KEY_BACKSPACE = 0x0E; - public static final int KEY_TAB = 0x0F; + public static final int SPACE = 0x39; + public static final int BACKSPACE = 0x0E; + public static final int TAB = 0x0F; - public static final int KEY_F1 = 0x3B; - public static final int KEY_F2 = 0x3C; - public static final int KEY_F3 = 0x3D; - public static final int KEY_F4 = 0x3E; - public static final int KEY_F5 = 0x3F; - public static final int KEY_F6 = 0x40; - public static final int KEY_F7 = 0x41; - public static final int KEY_F8 = 0x42; - public static final int KEY_F9 = 0x43; - public static final int KEY_F10 = 0x44; - public static final int KEY_F11 = 0x57; - public static final int KEY_F12 = 0x58; - public static final int KEY_F13 = 0x64; - public static final int KEY_F14 = 0x65; - public static final int KEY_F15 = 0x66; + public static final int F1 = 0x3B; + public static final int F2 = 0x3C; + public static final int F3 = 0x3D; + public static final int F4 = 0x3E; + public static final int F5 = 0x3F; + public static final int F6 = 0x40; + public static final int F7 = 0x41; + public static final int F8 = 0x42; + public static final int F9 = 0x43; + public static final int F10 = 0x44; + public static final int F11 = 0x57; + public static final int F12 = 0x58; + public static final int F13 = 0x64; + public static final int F14 = 0x65; + public static final int F15 = 0x66; - public static final int KEY_CAPSLOCK = 0x3A; - public static final int KEY_SCROLLLOCK = 0x46; - public static final int KEY_NUMLOCK = 0x45; + public static final int CAPS_LOCK = 0x3A; + public static final int SCROLL_LOCK = 0x46; + public static final int NUM_LOCK = 0x45; - public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */ - public static final int KEY_ADD = 0x4E; /* + on numeric keypad */ - public static final int KEY_NUMPAD0 = 0x52; - public static final int KEY_NUMPAD1 = 0x4F; - public static final int KEY_NUMPAD2 = 0x50; - public static final int KEY_NUMPAD3 = 0x51; - public static final int KEY_NUMPAD4 = 0x4B; - public static final int KEY_NUMPAD5 = 0x4C; - public static final int KEY_NUMPAD6 = 0x4D; - public static final int KEY_NUMPAD7 = 0x47; - public static final int KEY_NUMPAD8 = 0x48; - public static final int KEY_NUMPAD9 = 0x49; - public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */ - public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */ - public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */ - public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */ + public static final int SUBTRACT = 0x4A; /* - on numeric keypad */ + public static final int ADD = 0x4E; /* + on numeric keypad */ + public static final int NUMPAD_0 = 0x52; + public static final int NUMPAD_1 = 0x4F; + public static final int NUMPAD_2 = 0x50; + public static final int NUMPAD_3 = 0x51; + public static final int NUMPAD_4 = 0x4B; + public static final int NUMPAD_5 = 0x4C; + public static final int NUMPAD_6 = 0x4D; + public static final int NUMPAD_7 = 0x47; + public static final int NUMPAD_8 = 0x48; + public static final int NUMPAD_9 = 0x49; + public static final int DECIMAL = 0x53; /* . on numeric keypad */ + public static final int NUMPAD_ENTER = 0x9C; /* Enter on numeric keypad */ + public static final int DIVIDE = 0xB5; /* / on numeric keypad */ + public static final int MULTIPLY = 0x37; /* * on numeric keypad */ - public static final int KEY_LCONTROL = 0x1D; - public static final int KEY_RCONTROL = 0x9D; - public static final int KEY_LALT = 0x38; - public static final int KEY_RALT = 0xB8; - public static final int KEY_LSHIFT = 0x2A; - public static final int KEY_RSHIFT = 0x36; - public static final int KEY_LMETA = 0xDB; - public static final int KEY_RMETA = 0xDC; - + public static final int L_CONTROL = 0x1D; + public static final int R_CONTROL = 0x9D; + public static final int L_ALT = 0x38; + public static final int R_ALT = 0xB8; + public static final int L_SHIFT = 0x2A; + public static final int R_SHIFT = 0x36; + public static final int L_META = 0xDB; + public static final int R_META = 0xDC; - public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */ - public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */ - public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */ - public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */ + public static final int UP = 0xC8; /* UpArrow on arrow keypad */ + public static final int DOWN = 0xD0; /* DownArrow on arrow keypad */ + public static final int LEFT = 0xCB; /* LeftArrow on arrow keypad */ + public static final int RIGHT = 0xCD; /* RightArrow on arrow keypad */ - public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */ - public static final int KEY_END = 0xCF; /* End on arrow keypad */ + public static final int HOME = 0xC7; /* Home on arrow keypad */ + public static final int END = 0xCF; /* End on arrow keypad */ - public static final int KEY_PAGEUP = 0xC9; /* PgUp on arrow keypad */ - public static final int KEY_PAGEDOWN = 0xD1; /* PgDn on arrow keypad */ + public static final int PAGE_UP = 0xC9; /* PgUp on arrow keypad */ + public static final int PAGE_DOWN = 0xD1; /* PgDn on arrow keypad */ - public static final int KEY_RETURN = 0x1C; - public static final int KEY_PAUSE = 0xC5; /* Pause */ - public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */ - public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */ + public static final int RETURN = 0x1C; + public static final int PAUSE = 0xC5; /* Pause */ + public static final int INSERT = 0xD2; /* Insert on arrow keypad */ + public static final int DELETE = 0xD3; /* Delete on arrow keypad */ //@formatter:on } diff --git a/src/mightypork/gamecore/render/fonts/impl/CachedFont.java b/src/mightypork/gamecore/render/fonts/impl/CachedFont.java index 7c3abde..682c13c 100644 --- a/src/mightypork/gamecore/render/fonts/impl/CachedFont.java +++ b/src/mightypork/gamecore/render/fonts/impl/CachedFont.java @@ -294,7 +294,8 @@ public class CachedFont implements GLFont { byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI); } else { - byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData()); + byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()) + .put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData()); } byteBuffer.flip(); @@ -412,7 +413,8 @@ public class CachedFont implements GLFont { chtx = chars.get(charCurrent); if (chtx != null) { - drawQuad((totalwidth), 0, (totalwidth + chtx.width), (chtx.height), chtx.texPosX, chtx.texPosY, chtx.texPosX + chtx.width, chtx.texPosY + chtx.height); + drawQuad((totalwidth), 0, (totalwidth + chtx.width), (chtx.height), chtx.texPosX, chtx.texPosY, chtx.texPosX + chtx.width, chtx.texPosY + + chtx.height); totalwidth += chtx.width; } } diff --git a/src/mightypork/gamecore/render/fonts/impl/DeferredFont.java b/src/mightypork/gamecore/render/fonts/impl/DeferredFont.java index d74ed41..9abb5ec 100644 --- a/src/mightypork/gamecore/render/fonts/impl/DeferredFont.java +++ b/src/mightypork/gamecore/render/fonts/impl/DeferredFont.java @@ -129,7 +129,7 @@ public class DeferredFont extends DeferredResource implements GLFont { */ protected Font getAwtFont(String resource, float size, int style) throws FontFormatException, IOException { - try (InputStream in = FileUtils.getResource(resource)) { + try(InputStream in = FileUtils.getResource(resource)) { Font awtFont = Font.createFont(Font.TRUETYPE_FONT, in); diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java index 71016b1..9e9747c 100644 --- a/src/mightypork/rogue/App.java +++ b/src/mightypork/rogue/App.java @@ -14,6 +14,7 @@ import mightypork.gamecore.loading.AsyncResourceLoader; import mightypork.gamecore.render.DisplaySystem; import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest.RequestType; +import mightypork.rogue.screens.FpsOverlay; import mightypork.rogue.screens.main_menu.ScreenMainMenu; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_cat_sound.ScreenTestCat; @@ -47,11 +48,9 @@ public class App extends BaseApp { @Override protected LogWriter createLog() { - Locale.setDefault(Locale.ENGLISH); + Locale.setDefault(Locale.ENGLISH); // for decimal point in numbers - final LogWriter log = Log.create("runtime", Paths.LOG_FILE, 5); - - return log; + return Log.create("runtime", Paths.LOG_FILE, 5); } @@ -69,9 +68,10 @@ public class App extends BaseApp { screens.addScreen(new ScreenTestBouncy(this)); screens.addScreen(new ScreenTestCat(this)); screens.addScreen(new ScreenTestRender(this)); - screens.addScreen(new ScreenMainMenu(this)); + screens.addOverlay(new FpsOverlay(this)); + screens.showScreen("rogue.menu"); } @@ -86,7 +86,7 @@ public class App extends BaseApp { @Override protected void initResources() { - AsyncResourceLoader thread = AsyncResourceLoader.launch(this); + final AsyncResourceLoader thread = AsyncResourceLoader.launch(this); thread.enableMainLoopQueuing(true); Res.load(this); @@ -103,8 +103,6 @@ public class App extends BaseApp { @Override protected void initBus(EventBus bus) { - bus.addChannel(ActionRequest.class, ActionRequest.Listener.class); - bus.detailedLogging = true; } @@ -113,7 +111,7 @@ public class App extends BaseApp { protected void initInputSystem(InputSystem input) { // Go fullscreen - getInput().bindKeyStroke(new KeyStroke(Keys.KEY_F11), new Runnable() { + input.bindKey(new KeyStroke(Keys.F11), new Runnable() { @Override public void run() @@ -123,7 +121,7 @@ public class App extends BaseApp { }); // Take screenshot - getInput().bindKeyStroke(new KeyStroke(Keys.KEY_F2), new Runnable() { + input.bindKey(new KeyStroke(Keys.F2), new Runnable() { @Override public void run() @@ -133,7 +131,7 @@ public class App extends BaseApp { }); // Exit - getInput().bindKeyStroke(new KeyStroke(Keys.KEY_LCONTROL, Keys.KEY_Q), new Runnable() { + input.bindKey(new KeyStroke(Keys.L_CONTROL, Keys.Q), new Runnable() { @Override public void run() diff --git a/src/mightypork/rogue/Res.java b/src/mightypork/rogue/Res.java index e1f61c1..8108783 100644 --- a/src/mightypork/rogue/Res.java +++ b/src/mightypork/rogue/Res.java @@ -65,6 +65,7 @@ public class Res { fonts.addAlias("default", "polygon_pixel"); fonts.addAlias("main_menu_button", "press_start"); + fonts.addAlias("main_menu_title", "press_start"); } diff --git a/src/mightypork/rogue/screens/LayerFps.java b/src/mightypork/rogue/screens/FpsOverlay.java similarity index 73% rename from src/mightypork/rogue/screens/LayerFps.java rename to src/mightypork/rogue/screens/FpsOverlay.java index 895abcd..b07f4d5 100644 --- a/src/mightypork/rogue/screens/LayerFps.java +++ b/src/mightypork/rogue/screens/FpsOverlay.java @@ -1,14 +1,15 @@ package mightypork.rogue.screens; +import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.gui.components.painters.TextPainter; -import mightypork.gamecore.gui.screens.BaseScreen; -import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.gamecore.gui.screens.Overlay; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.Keys; import mightypork.gamecore.render.fonts.GLFont; import mightypork.rogue.Res; +import mightypork.util.constraints.num.Num; import mightypork.util.constraints.rect.proxy.RectBound; import mightypork.util.constraints.vect.Vect; import mightypork.util.control.Action; @@ -16,18 +17,18 @@ import mightypork.util.math.color.Color; import mightypork.util.string.StringProvider; -public class LayerFps extends ScreenLayer { +public class FpsOverlay extends Overlay { TextPainter tp; - public LayerFps(BaseScreen screen) { + public FpsOverlay(AppAccess screen) { super(screen); /* * Toggle key: F3 */ - bindKeyStroke(new KeyStroke(Keys.KEY_F3), new Action() { + bindKey(new KeyStroke(Keys.F3), new Action() { @Override public void execute() @@ -38,7 +39,8 @@ public class LayerFps extends ScreenLayer { final GLFont font = Res.getFont("default"); - final RectBound constraint = root.topRight().add(-8, 8).expand(0, 0, 0, 32); + final Num h = root.height(); + final RectBound constraint = root.shrink(h.perc(3)).topRight().startRect().growDown(h.perc(8).max(32)); tp = new TextPainter(font, AlignX.RIGHT, Color.WHITE, new StringProvider() { diff --git a/src/mightypork/rogue/screens/main_menu/MenuButton.java b/src/mightypork/rogue/screens/main_menu/MenuButton.java index 608592c..419dd7b 100644 --- a/src/mightypork/rogue/screens/main_menu/MenuButton.java +++ b/src/mightypork/rogue/screens/main_menu/MenuButton.java @@ -6,24 +6,53 @@ import mightypork.gamecore.gui.components.ClickableComponent; import mightypork.gamecore.gui.components.painters.TextPainter; import mightypork.gamecore.render.fonts.GLFont; import mightypork.rogue.Res; +import mightypork.util.constraints.num.Num; +import mightypork.util.constraints.num.mutable.NumVar; +import mightypork.util.constraints.vect.Vect; +import mightypork.util.constraints.vect.mutable.VectVar; import mightypork.util.math.color.Color; class MenuButton extends ClickableComponent { private static GLFont font = Res.getFont("main_menu_button"); - private TextPainter painter; + private final TextPainter painter; + private final VectVar offset = Vect.makeVar(); + private final Vect offsetActive = Vect.make(this.height().perc(-5), Num.ZERO); + private final Color color; + + private final double ALPHA_OFF = 0.6; + private final double ALPHA_ON = 1; + + private final double SH_ALPHA_OFF = 0.1; + private final double SH_ALPHA_ON = 0.5; + + private final NumVar alphaMul = Num.makeVar(ALPHA_OFF); + private final NumVar alphaMulSh = Num.makeVar(SH_ALPHA_OFF); public MenuButton(String text, Color color) { - this.painter = new TextPainter(font, AlignX.CENTER, color, text); - painter.setRect(this.shrink(this.height().perc(5))); + this.color = color.withAlpha(alphaMul); + + this.painter = new TextPainter(font, AlignX.CENTER, this.color, text); + this.painter.setRect(this.shrink(this.height().perc(8)).move(offset)); + this.painter.setShadow(Color.BLACK.withAlpha(alphaMulSh), height().div(24).toVectXY()); } @Override protected void renderComponent() { + if (isMouseOver()) { + offset.setTo(offsetActive); + alphaMul.setTo(ALPHA_ON); + alphaMulSh.setTo(SH_ALPHA_ON); + } else { + offset.setTo(Vect.ZERO); + alphaMul.setTo(ALPHA_OFF); + alphaMulSh.setTo(SH_ALPHA_OFF); + } + painter.render(); } diff --git a/src/mightypork/rogue/screens/main_menu/MenuLayer.java b/src/mightypork/rogue/screens/main_menu/MenuLayer.java index e2d0150..7772a5f 100644 --- a/src/mightypork/rogue/screens/main_menu/MenuLayer.java +++ b/src/mightypork/rogue/screens/main_menu/MenuLayer.java @@ -2,16 +2,19 @@ package mightypork.rogue.screens.main_menu; import mightypork.gamecore.control.events.ScreenRequestEvent; -import mightypork.gamecore.gui.AlignY; -import mightypork.gamecore.gui.components.layout.VerticalFixedFlowLayout; +import mightypork.gamecore.gui.AlignX; +import mightypork.gamecore.gui.components.layout.GridLayout; +import mightypork.gamecore.gui.components.painters.QuadPainter; +import mightypork.gamecore.gui.components.painters.TextPainter; import mightypork.gamecore.gui.screens.BaseScreen; import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.rogue.Res; import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest.RequestType; import mightypork.util.constraints.num.Num; import mightypork.util.constraints.rect.Rect; import mightypork.util.control.Action; -import mightypork.util.math.color.Color; +import mightypork.util.math.color.PAL16; class MenuLayer extends ScreenLayer { @@ -25,19 +28,31 @@ class MenuLayer extends ScreenLayer { private void init() { - Rect menuBox = root.shrink(root.height().min(root.width()).mul(0.1)); + final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.18)).moveY(root.height().mul(-0.03)); - Num lineHeight = menuBox.height().min(menuBox.width()).mul(0.1); + final GridLayout layout = new GridLayout(root, menuBox, 17, 1); + layout.enableCaching(true); + + final QuadPainter bg = QuadPainter.gradV(PAL16.NIGHTBLUE, PAL16.SEABLUE); + bg.setRect(root); + root.add(bg); - VerticalFixedFlowLayout layout = new VerticalFixedFlowLayout(root, menuBox, lineHeight, AlignY.TOP); root.add(layout); + TextPainter tp; MenuButton b1, b2, b3, b4; - layout.add(b1 = new MenuButton("Render test", Color.WHITE)); - layout.add(b2 = new MenuButton("Bouncy Cubes", Color.CYAN)); - layout.add(b3 = new MenuButton("Flying Cat", Color.MAGENTA)); - layout.add(b4 = new MenuButton("Bye!", Color.GREEN)); + tp = new TextPainter(Res.getFont("main_menu_title"), AlignX.CENTER, PAL16.SLIMEGREEN, "Rogue!"); + b1 = new MenuButton("Gradientz", PAL16.BLAZE); + b2 = new MenuButton("Bouncy Cubes", PAL16.NEWPOOP); + b3 = new MenuButton("Flying Cat", PAL16.PIGMEAT); + b4 = new MenuButton("Bye!", PAL16.BLOODRED); + layout.put(tp, 1, 0, 4, 1); + layout.put(b1, 6, 0, 2, 1); + layout.put(b2, 8, 0, 2, 1); + layout.put(b3, 10, 0, 2, 1); + layout.put(b4, 13, 0, 2, 1); + root.add(layout); b1.setAction(new Action() { @Override diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java index fbb6946..28034a6 100644 --- a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java +++ b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java @@ -26,7 +26,7 @@ public class LayerBouncyBoxes extends ScreenLayer { public LayerBouncyBoxes(BaseScreen screen) { super(screen); - bindKeyStroke(new KeyStroke(true, Keys.KEY_RIGHT), new Runnable() { + bindKey(new KeyStroke(true, Keys.RIGHT), new Runnable() { @Override public void run() @@ -35,7 +35,7 @@ public class LayerBouncyBoxes extends ScreenLayer { } }); - bindKeyStroke(new KeyStroke(true, Keys.KEY_LEFT), new Runnable() { + bindKey(new KeyStroke(true, Keys.LEFT), new Runnable() { @Override public void run() diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java b/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java index d99ab17..70f01ac 100644 --- a/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java +++ b/src/mightypork/rogue/screens/test_bouncyboxes/ScreenTestBouncy.java @@ -2,11 +2,7 @@ package mightypork.rogue.screens.test_bouncyboxes; import mightypork.gamecore.control.AppAccess; -import mightypork.gamecore.control.events.ScreenRequestEvent; import mightypork.gamecore.gui.screens.LayeredScreen; -import mightypork.gamecore.input.KeyStroke; -import mightypork.gamecore.input.Keys; -import mightypork.rogue.screens.LayerFps; public class ScreenTestBouncy extends LayeredScreen { @@ -19,18 +15,7 @@ public class ScreenTestBouncy extends LayeredScreen { layer = new LayerBouncyBoxes(this); - addLayer(new LayerFps(this)); - addLayer(layer); - - bindKeyStroke(new KeyStroke(Keys.KEY_C), new Runnable() { - - @Override - public void run() - { - getEventBus().send(new ScreenRequestEvent("test.cat")); - } - }); } diff --git a/src/mightypork/rogue/screens/test_cat_sound/LayerFlyingCat.java b/src/mightypork/rogue/screens/test_cat_sound/LayerFlyingCat.java index 20ee105..dd1bd7b 100644 --- a/src/mightypork/rogue/screens/test_cat_sound/LayerFlyingCat.java +++ b/src/mightypork/rogue/screens/test_cat_sound/LayerFlyingCat.java @@ -41,17 +41,17 @@ public class LayerFlyingCat extends ScreenLayer implements MouseButtonEvent.List cat_position.setTo(getDisplay().getCenter()); cat_position.setDefaultDuration(3); - ImagePainter cat = new ImagePainter(Res.getTxQuad("test.kitten")); + final ImagePainter cat = new ImagePainter(Res.getTxQuad("test.kitten")); cat.setRect(Rect.make(size).centerTo(cat_position)); cat.enableCaching(false); // frame around cat - QuadPainter cat_frame = QuadPainter.gradV(Color.YELLOW, Color.RED); + final QuadPainter cat_frame = QuadPainter.gradV(Color.YELLOW, Color.RED); cat_frame.setRect(cat.grow(cat.height().mul(0.05))); cat_frame.enableCaching(false); // frame shadow - QuadPainter cat_shadow = new QuadPainter(Color.dark(0.4)); + final QuadPainter cat_shadow = new QuadPainter(Color.dark(0.4)); cat_shadow.setRect(cat_frame.move(Vect.make(cat.height().mul(0.05)))); cat_shadow.enableCaching(false); @@ -61,7 +61,7 @@ public class LayerFlyingCat extends ScreenLayer implements MouseButtonEvent.List root.add(cat); // Meow - TextPainter tp = new TextPainter(Res.getFont("press_start")); + final TextPainter tp = new TextPainter(Res.getFont("press_start")); tp.setAlign(AlignX.CENTER); tp.setColor(Color.YELLOW); tp.setText("Meow!"); @@ -73,7 +73,7 @@ public class LayerFlyingCat extends ScreenLayer implements MouseButtonEvent.List /* * Register keys */ - bindKeyStroke(new KeyStroke(Keys.KEY_RETURN), new Runnable() { + bindKey(new KeyStroke(Keys.RETURN), new Runnable() { @Override public void run() @@ -91,7 +91,7 @@ public class LayerFlyingCat extends ScreenLayer implements MouseButtonEvent.List cat_position.setTo(event.getPos()); - double newSize = root.height().perc(10 + rand.nextInt(40)).value(); + final double newSize = root.height().perc(10 + rand.nextInt(40)).value(); size.animate(newSize, 1); } diff --git a/src/mightypork/rogue/screens/test_cat_sound/ScreenTestCat.java b/src/mightypork/rogue/screens/test_cat_sound/ScreenTestCat.java index 47b7738..aacaa87 100644 --- a/src/mightypork/rogue/screens/test_cat_sound/ScreenTestCat.java +++ b/src/mightypork/rogue/screens/test_cat_sound/ScreenTestCat.java @@ -2,14 +2,12 @@ package mightypork.rogue.screens.test_cat_sound; import mightypork.gamecore.control.AppAccess; -import mightypork.gamecore.control.events.ScreenRequestEvent; import mightypork.gamecore.gui.screens.LayeredScreen; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.input.Keys; import mightypork.rogue.Res; import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest.RequestType; -import mightypork.rogue.screens.LayerFps; public class ScreenTestCat extends LayeredScreen { @@ -17,10 +15,9 @@ public class ScreenTestCat extends LayeredScreen { public ScreenTestCat(AppAccess app) { super(app); - addLayer(new LayerFps(this)); addLayer(new LayerFlyingCat(this)); - bindKeyStroke(new KeyStroke(Keys.KEY_ESCAPE), new Runnable() { + bindKey(new KeyStroke(Keys.ESCAPE), new Runnable() { @Override public void run() @@ -29,15 +26,6 @@ public class ScreenTestCat extends LayeredScreen { getEventBus().sendDelayed(new ActionRequest(RequestType.SHUTDOWN), 3); } }); - - bindKeyStroke(new KeyStroke(Keys.KEY_B), new Runnable() { - - @Override - public void run() - { - getEventBus().send(new ScreenRequestEvent("test.bouncy")); - } - }); } diff --git a/src/mightypork/rogue/screens/test_render/ScreenTestRender.java b/src/mightypork/rogue/screens/test_render/ScreenTestRender.java index 4ecdd03..4a6fd9d 100644 --- a/src/mightypork/rogue/screens/test_render/ScreenTestRender.java +++ b/src/mightypork/rogue/screens/test_render/ScreenTestRender.java @@ -3,7 +3,6 @@ package mightypork.rogue.screens.test_render; import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.gui.screens.LayeredScreen; -import mightypork.rogue.screens.LayerFps; public class ScreenTestRender extends LayeredScreen { @@ -11,7 +10,6 @@ public class ScreenTestRender extends LayeredScreen { public ScreenTestRender(AppAccess app) { super(app); - addLayer(new LayerFps(this)); addLayer(new LayerTestGradient(this)); } diff --git a/src/mightypork/util/config/PropertyManager.java b/src/mightypork/util/config/PropertyManager.java index ee74e8f..fbf2f40 100644 --- a/src/mightypork/util/config/PropertyManager.java +++ b/src/mightypork/util/config/PropertyManager.java @@ -179,7 +179,7 @@ public class PropertyManager { } } - try (FileInputStream fis = new FileInputStream(file)) { + try(FileInputStream fis = new FileInputStream(file)) { props.load(fis); } catch (final IOException e) { needsSave = true; diff --git a/src/mightypork/util/constraints/num/Num.java b/src/mightypork/util/constraints/num/Num.java index 131d940..325fe6f 100644 --- a/src/mightypork/util/constraints/num/Num.java +++ b/src/mightypork/util/constraints/num/Num.java @@ -9,6 +9,7 @@ import mightypork.util.constraints.num.caching.NumDigest; import mightypork.util.constraints.num.mutable.NumVar; import mightypork.util.constraints.num.proxy.NumBound; import mightypork.util.constraints.num.proxy.NumBoundAdapter; +import mightypork.util.constraints.vect.Vect; import mightypork.util.math.Calc; @@ -69,7 +70,7 @@ public abstract class Num implements NumBound, Digestable { private Num p_neg; private Num p_abs; - private DigestCache dc = new DigestCache() { + private final DigestCache dc = new DigestCache() { @Override protected NumDigest createDigest() @@ -747,4 +748,13 @@ public abstract class Num implements NumBound, Digestable { { return Calc.toString(value()); } + + + /** + * @return vect with both coords of this size + */ + public Vect toVectXY() + { + return Vect.make(this); + } } diff --git a/src/mightypork/util/constraints/rect/Rect.java b/src/mightypork/util/constraints/rect/Rect.java index 510dc53..2790c40 100644 --- a/src/mightypork/util/constraints/rect/Rect.java +++ b/src/mightypork/util/constraints/rect/Rect.java @@ -192,7 +192,7 @@ public abstract class Rect implements RectBound, Digestable { private Rect p_edge_t; private Rect p_edge_b; - private DigestCache dc = new DigestCache() { + private final DigestCache dc = new DigestCache() { @Override protected RectDigest createDigest() @@ -443,6 +443,12 @@ public abstract class Rect implements RectBound, Digestable { } + public Rect shrink(Num x, Num y) + { + return shrink(x, x, y, y); + } + + /** * Shrink the rect * @@ -603,6 +609,12 @@ public abstract class Rect implements RectBound, Digestable { } + public Rect grow(Num x, Num y) + { + return grow(x, x, y, y); + } + + /** * Grow the rect * diff --git a/src/mightypork/util/constraints/rect/RectConst.java b/src/mightypork/util/constraints/rect/RectConst.java index d532c57..b456cff 100644 --- a/src/mightypork/util/constraints/rect/RectConst.java +++ b/src/mightypork/util/constraints/rect/RectConst.java @@ -437,4 +437,15 @@ public class RectConst extends Rect { return super.centerTo(parent).freeze(); } + + public RectConst shrink(NumConst x, NumConst y) + { + return super.shrink(x, y).freeze(); + } + + + public RectConst grow(NumConst x, NumConst y) + { + return super.grow(x, y).freeze(); + } } diff --git a/src/mightypork/util/constraints/rect/builders/TiledRect.java b/src/mightypork/util/constraints/rect/builders/TiledRect.java index 008848c..0bebaab 100644 --- a/src/mightypork/util/constraints/rect/builders/TiledRect.java +++ b/src/mightypork/util/constraints/rect/builders/TiledRect.java @@ -4,12 +4,11 @@ package mightypork.util.constraints.rect.builders; import mightypork.util.constraints.num.Num; import mightypork.util.constraints.rect.Rect; import mightypork.util.constraints.rect.proxy.RectProxy; +import mightypork.util.logging.Log; /** - * Utility for cutting rect into evenly sized cells.
- * It's by default one-based, but this can be switched by calling the oneBased() - * and zeroBased() methods. + * Utility for cutting rect into evenly sized cells. * * @author MightyPork */ @@ -20,8 +19,6 @@ public class TiledRect extends RectProxy { final private Num perRow; final private Num perCol; - private int based = 1; - public TiledRect(Rect source, int horizontal, int vertical) { super(source); @@ -33,30 +30,6 @@ public class TiledRect extends RectProxy { } - /** - * Set to one-based mode, and return itself (for chaining). - * - * @return this - */ - public TiledRect oneBased() - { - based = 1; - return this; - } - - - /** - * Set to zero-based mode, and return itself (for chaining). - * - * @return this - */ - public TiledRect zeroBased() - { - based = 0; - return this; - } - - /** * Get a tile. * @@ -67,9 +40,6 @@ public class TiledRect extends RectProxy { */ public Rect tile(int x, int y) { - x -= based; - y -= based; - if (x >= tilesX || x < 0) { throw new IndexOutOfBoundsException("X coordinate out fo range."); } @@ -97,22 +67,19 @@ public class TiledRect extends RectProxy { */ public Rect span(int x_from, int y_from, int size_x, int size_y) { - x_from -= based; - y_from -= based; - - final int x_to = x_from + size_x; - final int y_to = y_from + size_y; + final int x_to = x_from + size_x - 1; + final int y_to = y_from + size_y - 1; if (size_x <= 0 || size_y <= 0) { - throw new IndexOutOfBoundsException("Size must be > 0."); + Log.w("Size must be > 0.", new IllegalAccessException()); } if (x_from >= tilesX || x_from < 0 || x_to >= tilesX || x_to < 0) { - throw new IndexOutOfBoundsException("X coordinate(s) out of range."); + Log.w("X coordinate(s) out of range.", new IllegalAccessException()); } if (y_from >= tilesY || y_from < 0 || y_to >= tilesY || y_to < 0) { - throw new IndexOutOfBoundsException("Y coordinate(s) out of range."); + Log.w("Y coordinate(s) out of range.", new IllegalAccessException()); } final Num leftMove = left().add(perCol.mul(x_from)); @@ -131,7 +98,7 @@ public class TiledRect extends RectProxy { */ public Rect column(int n) { - return tile(n, based); + return tile(n, 0); } @@ -144,6 +111,6 @@ public class TiledRect extends RectProxy { */ public Rect row(int n) { - return tile(based, n); + return tile(0, n); } } diff --git a/src/mightypork/util/constraints/rect/caching/RectDigest.java b/src/mightypork/util/constraints/rect/caching/RectDigest.java index 19fc0ff..4ab1a79 100644 --- a/src/mightypork/util/constraints/rect/caching/RectDigest.java +++ b/src/mightypork/util/constraints/rect/caching/RectDigest.java @@ -38,6 +38,7 @@ public class RectDigest { @Override public String toString() { - return String.format("Rect{ at: (%.1f, %.1f), size: (%.1f, %.1f), bounds: L %.1f R %.1f T %.1f B %.1f }", x, y, width, height, left, right, top, bottom); + return String + .format("Rect{ at: (%.1f, %.1f), size: (%.1f, %.1f), bounds: L %.1f R %.1f T %.1f B %.1f }", x, y, width, height, left, right, top, bottom); } } diff --git a/src/mightypork/util/constraints/vect/Vect.java b/src/mightypork/util/constraints/vect/Vect.java index 55f3395..eeff104 100644 --- a/src/mightypork/util/constraints/vect/Vect.java +++ b/src/mightypork/util/constraints/vect/Vect.java @@ -133,7 +133,7 @@ public abstract class Vect implements VectBound, Digestable { private Num p_yc; private Num p_zc; - private DigestCache dc = new DigestCache() { + private final DigestCache dc = new DigestCache() { @Override protected VectDigest createDigest() @@ -1216,4 +1216,16 @@ public abstract class Vect implements VectBound, Digestable { { return String.format("(%.1f, %.1f, %.1f)", x(), y(), z()); } + + + public final boolean isInside(Rect bounds) + { + return bounds.contains(this); + } + + + public Rect startRect() + { + return expand(0, 0, 0, 0); + } } diff --git a/src/mightypork/util/control/eventbus/BufferedHashSet.java b/src/mightypork/util/control/eventbus/BufferedHashSet.java index 70ccfa3..cfc4f88 100644 --- a/src/mightypork/util/control/eventbus/BufferedHashSet.java +++ b/src/mightypork/util/control/eventbus/BufferedHashSet.java @@ -8,8 +8,8 @@ import java.util.List; /** - * HashSet that buffers add and remove calls and performs them all at once when - * a flush() method is called. + * HashSet that buffers "add" and "remove" calls and performs them all at once + * when a flush() method is called. * * @author MightyPork * @param element type @@ -89,7 +89,7 @@ public class BufferedHashSet extends HashSet { /** * Flush all */ - private void flush() + public void flush() { for (final E e : toAdd) { super.add(e); diff --git a/src/mightypork/util/control/eventbus/EventBus.java b/src/mightypork/util/control/eventbus/EventBus.java index 719b5ca..fbb97af 100644 --- a/src/mightypork/util/control/eventbus/EventBus.java +++ b/src/mightypork/util/control/eventbus/EventBus.java @@ -1,12 +1,13 @@ package mightypork.util.control.eventbus; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Collection; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; -import mightypork.util.annotations.FactoryMethod; import mightypork.util.control.Destroyable; import mightypork.util.control.eventbus.clients.DelegatingClient; import mightypork.util.control.eventbus.events.Event; @@ -18,29 +19,123 @@ import mightypork.util.logging.Log; /** - * An event bus, accommodating multiple {@link EventChannel}s. + * An event bus, accommodating multiple EventChannels.
+ * Channel will be created when an event of type is first encountered. * * @author MightyPork */ final public class EventBus implements Destroyable { - /** Message channels */ - private final BufferedHashSet> channels = new BufferedHashSet<>(); + /** + * Queued event holder + */ + private class DelayQueueEntry implements Delayed { + + private final long due; + private final Event evt; + + + public DelayQueueEntry(double seconds, Event event) { + super(); + this.due = System.currentTimeMillis() + (long) (seconds * 1000); + this.evt = event; + } + + + @Override + public int compareTo(Delayed o) + { + return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS)); + } + + + @Override + public long getDelay(TimeUnit unit) + { + return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + } + + + public Event getEvent() + { + return evt; + } + + } - /** Registered clients */ - private final BufferedHashSet clients = new BufferedHashSet<>(); + /** + * Thread handling queued events + */ + private class QueuePollingThread extends Thread { + + public volatile boolean stopped = false; + + + public QueuePollingThread() { + super("Queue Polling Thread"); + } + + + @Override + public void run() + { + DelayQueueEntry evt; + + while (!stopped) { + evt = null; + + try { + evt = sendQueue.take(); + } catch (final InterruptedException ignored) { + // + } + + if (evt != null) { + dispatch(evt.getEvent()); + } + } + } + + } + + static final String logMark = " "; - /** Messages queued for delivery */ - private final DelayQueue sendQueue = new DelayQueue<>(); + + private static Class getEventListenerClass(Event event) + { + // BEHOLD, MAGIC! + final Type[] interfaces = event.getClass().getGenericInterfaces(); + for (final Type interf : interfaces) { + if (interf instanceof ParameterizedType) { + if (((ParameterizedType) interf).getRawType() == Event.class) { + final Type[] types = ((ParameterizedType) interf).getActualTypeArguments(); + for (final Type genericType : types) { + return (Class) genericType; + } + } + } + } + + throw new RuntimeException("Could not detect event listener type."); + } + + /** Log detailed messages (debug) */ + public boolean detailedLogging = false; /** Queue polling thread */ private final QueuePollingThread busThread; + /** Registered clients */ + private final BufferedHashSet clients = new BufferedHashSet<>(); + /** Whether the bus was destroyed */ private boolean dead = false; - /** Log detailed messages (debug) */ - public boolean detailedLogging = false; + /** Message channels */ + private final BufferedHashSet> channels = new BufferedHashSet<>(); + + /** Messages queued for delivery */ + private final DelayQueue sendQueue = new DelayQueue<>(); /** @@ -53,72 +148,21 @@ final public class EventBus implements Destroyable { } - private boolean shallLog(Event event) - { - if (!detailedLogging) return false; - if (event.getClass().isAnnotationPresent(UnloggedEvent.class)) return false; - - return true; - } - - /** - * Add a {@link EventChannel} to this bus.
- * If a channel of matching types is already added, it is returned instead. - * - * @param channel channel to be added - * @return the channel that's now in the bus - */ - public EventChannel addChannel(EventChannel channel) - { - assertLive(); - - // if the channel already exists, return this instance instead. - for (final EventChannel ch : channels) { - if (ch.equals(channel)) { - Log.w(" Channel of type " + Log.str(channel) + " already registered."); - return ch; - } - } - - channels.add(channel); - - return channel; - } - - - /** - * Make & connect a channel for given event and client type. - * - * @param eventClass event type - * @param clientClass client type - * @return the created channel instance - */ - @FactoryMethod - public , F_CLIENT> EventChannel addChannel(Class eventClass, Class clientClass) - { - assertLive(); - - final EventChannel channel = EventChannel.create(eventClass, clientClass); - return addChannel(channel); - } - - - /** - * Remove a {@link EventChannel} from this bus - * - * @param channel true if channel was removed + * Halt bus thread and reject any future events. */ - public void removeChannel(EventChannel channel) + @Override + public void destroy() { assertLive(); - channels.remove(channel); + busThread.stopped = true; + dead = true; } /** - * Send based on annotation.clients + * Send based on annotation * * @param event event */ @@ -166,7 +210,9 @@ final public class EventBus implements Destroyable { final DelayQueueEntry dm = new DelayQueueEntry(delay, event); - if (shallLog(event)) Log.f3(" Qu " + Log.str(event) + ", t = +" + delay + "s"); + if (shallLog(event)) { + Log.f3(logMark + "Qu [" + Log.str(event) + "]" + (delay == 0 ? "" : (", delay: " + delay + "s"))); + } sendQueue.add(dm); } @@ -183,7 +229,7 @@ final public class EventBus implements Destroyable { { assertLive(); - if (shallLog(event)) Log.f3(" Di " + Log.str(event)); + if (shallLog(event)) Log.f3(logMark + "Di [" + Log.str(event) + "]"); dispatch(event); } @@ -193,204 +239,149 @@ final public class EventBus implements Destroyable { { assertLive(); - if (shallLog(event)) Log.f3(" Di sub " + Log.str(event)); + if (shallLog(event)) Log.f3(logMark + "Di->sub [" + Log.str(event) + "]"); doDispatch(delegatingClient.getChildClients(), event); } /** - * Send immediately.
- * Should be used for real-time events that require immediate response, such - * as timing events. + * Connect a client to the bus. The client will be connected to all current + * and future channels, until removed from the bus. * - * @param event event + * @param client the client */ - private void dispatch(Event event) + public void subscribe(Object client) { assertLive(); - channels.setBuffering(true); - clients.setBuffering(true); + if (client == null) return; - doDispatch(clients, event); + clients.add(client); - channels.setBuffering(false); - clients.setBuffering(false); + if (detailedLogging) Log.f3(logMark + "Client joined: " + Log.str(client)); } /** - * Send to a set of clients + * Disconnect a client from the bus. * - * @param clients clients - * @param event event + * @param client the client */ - private void doDispatch(Collection clients, Event event) + public void unsubscribe(Object client) { - boolean sent = false; - boolean accepted = false; + assertLive(); - final boolean singular = event.getClass().isAnnotationPresent(SingleReceiverEvent.class); + clients.remove(client); - for (final EventChannel b : channels) { - if (b.canBroadcast(event)) { - accepted = true; - sent |= b.broadcast(event, clients); + if (detailedLogging) Log.f3(logMark + "Client left: " + Log.str(client)); + } + + + @SuppressWarnings("unchecked") + private boolean addChannelForEvent(Event event) + { + try { + if (detailedLogging) { + Log.f2(logMark + "Setting up channel for new event type: " + Log.str(event.getClass())); } - if (sent && singular) break; + final Class listener = getEventListenerClass(event); + final EventChannel ch = EventChannel.create(event.getClass(), listener); + + if (ch.canBroadcast(event)) { + + channels.add(ch); + //channels.flush(); + + if (detailedLogging) { + Log.f2(" Created new channel: " + Log.str(event.getClass()) + " -> " + Log.str(listener)); + } + + return true; + + } else { + Log.w(logMark + "Could not create channel for event " + Log.str(event.getClass())); + } + + } catch (final Throwable t) { + Log.w(logMark + "Error while trying to add channel for event.", t); } - if (!accepted) Log.e(" Not accepted by any channel: " + Log.str(event)); - if (!sent && shallLog(event)) Log.w(" Not delivered: " + Log.str(event)); - + return false; } /** - * Connect a client to the bus. The client will be connected to all current - * and future channels, until removed from the bus. + * Make sure the bus is not destroyed. * - * @param client the client + * @throws IllegalStateException if the bus is dead. */ - public void subscribe(Object client) + private void assertLive() throws IllegalStateException { - assertLive(); - - if (client == null) return; - - clients.add(client); - - if (detailedLogging) Log.f3(" Client joined: " + Log.str(client)); + if (dead) throw new IllegalStateException("EventBus is dead."); } /** - * Disconnect a client from the bus. + * Send immediately.
+ * Should be used for real-time events that require immediate response, such + * as timing events. * - * @param client the client + * @param event event */ - public void unsubscribe(Object client) + private synchronized void dispatch(Event event) { assertLive(); - clients.remove(client); - - if (detailedLogging) Log.f3(" Client left: " + Log.str(client)); + clients.setBuffering(true); + doDispatch(clients, event); + clients.setBuffering(false); } /** - * Check if client can be accepted by any channel + * Send to a set of clients * - * @param client tested client - * @return would be accepted + * @param clients clients + * @param event event */ - public boolean isClientValid(Object client) + private synchronized void doDispatch(Collection clients, Event event) { - assertLive(); - - if (client == null) return false; - - for (final EventChannel ch : channels) { - if (ch.isClientValid(client)) { - return true; - } - } - - return false; - } - - private class DelayQueueEntry implements Delayed { - - private final long due; - private Event evt = null; - - - public DelayQueueEntry(double seconds, Event event) { - super(); - this.due = System.currentTimeMillis() + (long) (seconds * 1000); - this.evt = event; - } - - - @Override - public int compareTo(Delayed o) - { - return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS)); - } - - - @Override - public long getDelay(TimeUnit unit) - { - return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS); - } - - - public Event getEvent() - { - return evt; - } - - } - - private class QueuePollingThread extends Thread { - - public boolean stopped = false; - + boolean sent = false; + boolean accepted = false; - public QueuePollingThread() { - super("Queue Polling Thread"); - } + final boolean singular = event.getClass().isAnnotationPresent(SingleReceiverEvent.class); + for (int i = 0; i < 2; i++) { // two tries. - @Override - public void run() - { - DelayQueueEntry evt; - - while (!stopped) { - evt = null; - - try { - evt = sendQueue.take(); - } catch (final InterruptedException ignored) { - // + channels.setBuffering(true); + for (final EventChannel b : channels) { + if (b.canBroadcast(event)) { + accepted = true; + sent |= b.broadcast(event, clients); } - if (evt != null) { - dispatch(evt.getEvent()); - } + if (sent && singular) break; } + channels.setBuffering(false); + + if (!accepted) if (addChannelForEvent(event)) continue; + + break; } + if (!accepted) Log.e(logMark + "Not accepted by any channel: " + Log.str(event)); + if (!sent && shallLog(event)) Log.w(logMark + "Not delivered: " + Log.str(event)); } - /** - * Halt bus thread and reject any future events. - */ - @Override - public void destroy() + private boolean shallLog(Event event) { - assertLive(); - - busThread.stopped = true; + if (!detailedLogging) return false; + if (event.getClass().isAnnotationPresent(UnloggedEvent.class)) return false; - dead = true; - } - - - /** - * Make sure the bus is not destroyed. - * - * @throws IllegalStateException if the bus is dead. - */ - private void assertLive() throws IllegalStateException - { - if (dead) throw new IllegalStateException("EventBus is dead."); + return true; } } diff --git a/src/mightypork/util/control/eventbus/EventChannel.java b/src/mightypork/util/control/eventbus/EventChannel.java index e996349..a7c29aa 100644 --- a/src/mightypork/util/control/eventbus/EventChannel.java +++ b/src/mightypork/util/control/eventbus/EventChannel.java @@ -18,7 +18,7 @@ import mightypork.util.logging.Log; * @param event type * @param client (subscriber) type */ -final public class EventChannel, CLIENT> { +class EventChannel, CLIENT> { private final Class clientClass; private final Class eventClass; @@ -79,7 +79,7 @@ final public class EventChannel, CLIENT> { // avoid executing more times if (processed.contains(client)) { - Log.w(" Client already served: " + Log.str(client)); + Log.w(EventBus.logMark + "Client already served: " + Log.str(client)); continue; } processed.add(client); @@ -131,7 +131,7 @@ final public class EventChannel, CLIENT> { /** - * Check if the given event can be broadcasted by this {@link EventChannel} + * Check if the given event can be broadcasted by this channel * * @param event event object * @return can be broadcasted diff --git a/src/mightypork/util/control/eventbus/clients/BusNode.java b/src/mightypork/util/control/eventbus/clients/BusNode.java index c2e36ca..52d79f5 100644 --- a/src/mightypork/util/control/eventbus/clients/BusNode.java +++ b/src/mightypork/util/control/eventbus/clients/BusNode.java @@ -65,9 +65,7 @@ public abstract class BusNode implements BusAccess, ClientHub { throw new IllegalArgumentException("Cannot nest RootBusNode."); } - if (getEventBus().isClientValid(client)) { - clients.add(client); - } + clients.add(client); } diff --git a/src/mightypork/util/control/eventbus/events/Event.java b/src/mightypork/util/control/eventbus/events/Event.java index 19fbbd5..7a4780a 100644 --- a/src/mightypork/util/control/eventbus/events/Event.java +++ b/src/mightypork/util/control/eventbus/events/Event.java @@ -9,7 +9,7 @@ import mightypork.util.control.eventbus.events.flags.UnloggedEvent; /** *

- * Something that can be handled by HANDLER. + * Something that can be handled by HANDLER, subscribing to the event bus. *

*

* Can be annotated as {@link SingleReceiverEvent} to be delivered once only, diff --git a/src/mightypork/util/files/FileTreeDiff.java b/src/mightypork/util/files/FileTreeDiff.java index 41d4cfc..44cec84 100644 --- a/src/mightypork/util/files/FileTreeDiff.java +++ b/src/mightypork/util/files/FileTreeDiff.java @@ -72,9 +72,11 @@ public class FileTreeDiff { ck1.reset(); ck2.reset(); - try (FileInputStream in1 = new FileInputStream(pair.a); FileInputStream in2 = new FileInputStream(pair.b)) { + try(FileInputStream in1 = new FileInputStream(pair.a); + FileInputStream in2 = new FileInputStream(pair.b)) { - try (CheckedInputStream cin1 = new CheckedInputStream(in1, ck1); CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) { + try(CheckedInputStream cin1 = new CheckedInputStream(in1, ck1); + CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) { while (true) { final int read1 = cin1.read(BUFFER); diff --git a/src/mightypork/util/files/FileUtils.java b/src/mightypork/util/files/FileUtils.java index 88835f7..acb4419 100644 --- a/src/mightypork/util/files/FileUtils.java +++ b/src/mightypork/util/files/FileUtils.java @@ -95,7 +95,8 @@ public class FileUtils { public static void copyFile(File source, File target) throws IOException { - try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) { + try(InputStream in = new FileInputStream(source); + OutputStream out = new FileOutputStream(target)) { copyStream(in, out); } @@ -160,7 +161,7 @@ public class FileUtils { */ public static String fileToString(File file) throws IOException { - try (FileInputStream fin = new FileInputStream(file)) { + try(FileInputStream fin = new FileInputStream(file)) { return streamToString(fin); } @@ -360,7 +361,7 @@ public class FileUtils { */ public static void stringToFile(File file, String text) throws IOException { - try (PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) { + try(PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) { out.print(text); @@ -481,7 +482,8 @@ public class FileUtils { */ public static void resourceToFile(String resname, File file) throws IOException { - try (InputStream in = FileUtils.getResource(resname); OutputStream out = new FileOutputStream(file)) { + try(InputStream in = FileUtils.getResource(resname); + OutputStream out = new FileOutputStream(file)) { FileUtils.copyStream(in, out); } @@ -498,7 +500,7 @@ public class FileUtils { */ public static String resourceToString(String resname) throws IOException { - try (InputStream in = FileUtils.getResource(resname)) { + try(InputStream in = FileUtils.getResource(resname)) { return streamToString(in); } } diff --git a/src/mightypork/util/files/ion/Ion.java b/src/mightypork/util/files/ion/Ion.java index 1ce8735..475e005 100644 --- a/src/mightypork/util/files/ion/Ion.java +++ b/src/mightypork/util/files/ion/Ion.java @@ -67,7 +67,7 @@ public class Ion { */ public static Object fromFile(File file) throws IonException { - try (InputStream in = new FileInputStream(file)) { + try(InputStream in = new FileInputStream(file)) { final Object obj = fromStream(in); return obj; @@ -113,7 +113,7 @@ public class Ion { */ public static void toFile(File path, Object obj) throws IonException { - try (OutputStream out = new FileOutputStream(path)) { + try(OutputStream out = new FileOutputStream(path)) { final String f = path.toString(); final File dir = new File(f.substring(0, f.lastIndexOf(File.separator))); diff --git a/src/mightypork/util/files/zip/ZipBuilder.java b/src/mightypork/util/files/zip/ZipBuilder.java index 98fbd9a..85dcd27 100644 --- a/src/mightypork/util/files/zip/ZipBuilder.java +++ b/src/mightypork/util/files/zip/ZipBuilder.java @@ -75,7 +75,7 @@ public class ZipBuilder { out.putNextEntry(new ZipEntry(path)); - try (InputStream in = FileUtils.stringToStream(text)) { + try(InputStream in = FileUtils.stringToStream(text)) { FileUtils.copyStream(in, out); } } @@ -96,7 +96,7 @@ public class ZipBuilder { out.putNextEntry(new ZipEntry(path)); - try (InputStream in = FileUtils.getResource(resPath)) { + try(InputStream in = FileUtils.getResource(resPath)) { FileUtils.copyStream(in, out); } } diff --git a/src/mightypork/util/files/zip/ZipUtils.java b/src/mightypork/util/files/zip/ZipUtils.java index a647efb..a136bcd 100644 --- a/src/mightypork/util/files/zip/ZipUtils.java +++ b/src/mightypork/util/files/zip/ZipUtils.java @@ -34,7 +34,7 @@ public class ZipUtils { */ public static List extractZip(File file, File outputDir, StringFilter filter) throws IOException { - try (ZipFile zip = new ZipFile(file)) { + try(ZipFile zip = new ZipFile(file)) { return extractZip(zip, outputDir, filter); } } @@ -90,7 +90,7 @@ public class ZipUtils { */ public static List listZip(File zipFile) throws IOException { - try (ZipFile zip = new ZipFile(zipFile)) { + try(ZipFile zip = new ZipFile(zipFile)) { return listZip(zip); } } @@ -134,7 +134,10 @@ public class ZipUtils { { if (!destFile.getParentFile().mkdirs()) throw new IOException("Could not create output directory."); - try (InputStream in = zip.getInputStream(entry); BufferedInputStream is = new BufferedInputStream(in); FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) { + try(InputStream in = zip.getInputStream(entry); + BufferedInputStream is = new BufferedInputStream(in); + FileOutputStream fos = new FileOutputStream(destFile); + BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) { FileUtils.copyStream(is, dest); } @@ -168,7 +171,7 @@ public class ZipUtils { public static boolean entryExists(File selectedFile, String string) { - try (ZipFile zf = new ZipFile(selectedFile)) { + try(ZipFile zf = new ZipFile(selectedFile)) { return zf.getEntry(string) != null; } catch (final IOException | RuntimeException e) { Log.w("Error reading zip.", e); diff --git a/src/mightypork/util/math/color/CGA.java b/src/mightypork/util/math/color/CGA.java new file mode 100644 index 0000000..e3e142d --- /dev/null +++ b/src/mightypork/util/math/color/CGA.java @@ -0,0 +1,29 @@ +package mightypork.util.math.color; + + +/** + * CGA palette + * + * @author MightyPork + */ +public interface CGA { + + Color BLACK = Color.fromHex(0x000000); + Color GRAY_DARK = Color.fromHex(0x686868); + Color GRAY_LIGHT = Color.fromHex(0xB8B8B8); + Color WHITE = Color.fromHex(0xFFFFFF); + + Color RED_DARK = Color.fromHex(0xC41F0C); + Color RED_LIGHT = Color.fromHex(0xFF706A); + Color MAGENTA_DARK = Color.fromHex(0xC12BB6); + Color MAGENTA_LIGHT = Color.fromHex(0xFF76FD); + Color BLUE_DARK = Color.fromHex(0x0019B6); + Color BLUE_LIGHT = Color.fromHex(0x5F6EFC); + Color CYAN_DARK = Color.fromHex(0x00B6B8); + Color CYAN_LIGHT = Color.fromHex(0x23FCFE); + Color GREEN_DARK = Color.fromHex(0x00B41D); + Color GREEN_LIGHT = Color.fromHex(0x39FA6F); + + Color YELLOW = Color.fromHex(0xFFFD72); + Color BROWN = Color.fromHex(0xC16A14); +} diff --git a/src/mightypork/util/math/color/COMMODORE.java b/src/mightypork/util/math/color/COMMODORE.java new file mode 100644 index 0000000..ab8ad61 --- /dev/null +++ b/src/mightypork/util/math/color/COMMODORE.java @@ -0,0 +1,27 @@ +package mightypork.util.math.color; + + +/** + * COMMODORE palette + * + * @author MightyPork + */ +public interface COMMODORE { + + Color BLACK = Color.fromHex(0x040013); + Color WHITE = Color.fromHex(0xFFFFFF); + Color RED = Color.fromHex(0x883932); + Color CYAN = Color.fromHex(0x67B6BD); + Color PURPLE = Color.fromHex(0x8B3F96); + Color GREEN = Color.fromHex(0x55A049); + Color BLUE = Color.fromHex(0x40318D); + Color YELLOW = Color.fromHex(0xBFCE72); + Color ORANGE = Color.fromHex(0x8B5429); + Color BROWN = Color.fromHex(0x574200); + Color RED_LIGHT = Color.fromHex(0xB86962); + Color GRAY_DARK = Color.fromHex(0x505050); + Color GRAY = Color.fromHex(0x787878); + Color GREEN_LIGHT = Color.fromHex(0x94E089); + Color BLUE_LIGHT = Color.fromHex(0x7869C4); + Color GRAY_LIGHT = Color.fromHex(0x9F9F9F); +} diff --git a/src/mightypork/util/math/color/Color.java b/src/mightypork/util/math/color/Color.java index 732ae31..864304c 100644 --- a/src/mightypork/util/math/color/Color.java +++ b/src/mightypork/util/math/color/Color.java @@ -19,9 +19,9 @@ public abstract class Color { public static final Color NONE = rgba(0, 0, 0, 0); public static final Color SHADOW = rgba(0, 0, 0, 0.5); - public static final Color WHITE = rgb(1, 1, 1); - public static final Color BLACK = rgb(0, 0, 0); - public static final Color DARK_GRAY = rgb(0.25, 0.25, 0.25); + public static final Color WHITE = fromHex(0xFFFFFF); + public static final Color BLACK = fromHex(0x000000); + public static final Color DARK_GRAY = fromHex(0x808080); public static final Color GRAY = rgb(0.5, 0.5, 0.5); public static final Color LIGHT_GRAY = rgb(0.75, 0.75, 0.75); @@ -40,6 +40,16 @@ public abstract class Color { private static volatile boolean alphaStackEnabled = true; + @FactoryMethod + public static final Color fromHex(int rgb_hex) + { + final int bi = rgb_hex & 0xff; + final int gi = (rgb_hex >> 8) & 0xff; + final int ri = (rgb_hex >> 16) & 0xff; + return rgb(ri / 255D, gi / 255D, bi / 255D); + } + + @FactoryMethod public static final Color rgb(double r, double g, double b) { @@ -163,7 +173,7 @@ public abstract class Color { if (alphaStackEnabled) { - for (Num n : alphaStack) { + for (final Num n : alphaStack) { alpha *= clamp(n.value()); } } @@ -241,4 +251,16 @@ public abstract class Color { { return alphaStackEnabled; } + + + public Color withAlpha(double multiplier) + { + return new ColorAlphaAdjuster(this, Num.make(multiplier)); + } + + + public Color withAlpha(Num multiplier) + { + return new ColorAlphaAdjuster(this, Num.make(multiplier)); + } } diff --git a/src/mightypork/util/math/color/ColorAlphaAdjuster.java b/src/mightypork/util/math/color/ColorAlphaAdjuster.java new file mode 100644 index 0000000..3868789 --- /dev/null +++ b/src/mightypork/util/math/color/ColorAlphaAdjuster.java @@ -0,0 +1,46 @@ +package mightypork.util.math.color; + + +import mightypork.util.constraints.num.Num; + + +public class ColorAlphaAdjuster extends Color { + + private final Color source; + private final Num alphaAdjust; + + + public ColorAlphaAdjuster(Color source, Num alphaMul) { + this.source = source; + this.alphaAdjust = alphaMul; + } + + + @Override + public double red() + { + return source.red(); + } + + + @Override + public double green() + { + return source.green(); + } + + + @Override + public double blue() + { + return source.blue(); + } + + + @Override + protected double rawAlpha() + { + return source.rawAlpha() * alphaAdjust.value(); + } + +} diff --git a/src/mightypork/util/math/color/PAL16.java b/src/mightypork/util/math/color/PAL16.java new file mode 100644 index 0000000..42922f8 --- /dev/null +++ b/src/mightypork/util/math/color/PAL16.java @@ -0,0 +1,31 @@ +package mightypork.util.math.color; + + +/** + * PAL16 palette via http://androidarts.com/palette/16pal.htm + * + * @author MightyPork + */ +public interface PAL16 { + + Color VOID = Color.fromHex(0x000000); + Color ASH = Color.fromHex(0x9D9D9D); + Color BLIND = Color.fromHex(0xFFFFFF); + + Color BLOODRED = Color.fromHex(0xBE2633); + Color PIGMEAT = Color.fromHex(0xE06F8B); + + Color OLDPOOP = Color.fromHex(0x493C2B); + Color NEWPOOP = Color.fromHex(0xA46422); + Color BLAZE = Color.fromHex(0xEB8931); + Color ZORNSKIN = Color.fromHex(0xF7E26B); + + Color SHADEGREEN = Color.fromHex(0x2F484E); + Color LEAFGREEN = Color.fromHex(0x44891A); + Color SLIMEGREEN = Color.fromHex(0xA3CE27); + + Color NIGHTBLUE = Color.fromHex(0x1B2632); + Color SEABLUE = Color.fromHex(0x005784); + Color SKYBLUE = Color.fromHex(0x31A2F2); + Color CLOUDBLUE = Color.fromHex(0xB2DCEF); +} diff --git a/src/mightypork/util/math/color/RGB.java b/src/mightypork/util/math/color/RGB.java new file mode 100644 index 0000000..ec48861 --- /dev/null +++ b/src/mightypork/util/math/color/RGB.java @@ -0,0 +1,26 @@ +package mightypork.util.math.color; + + +/** + * Basic RGB palette + * + * @author MightyPork + */ +public interface RGB { + + Color WHITE = Color.fromHex(0xFFFFFF); + Color BLACK = Color.fromHex(0x000000); + Color GRAY_DARK = Color.fromHex(0x808080); + Color GRAY_LIGHT = Color.fromHex(0xC0C0C0); + + Color RED = Color.fromHex(0xFF0000); + Color GREEN = Color.fromHex(0x00FF00); + Color BLUE = Color.fromHex(0x0000FF); + + Color YELLOW = Color.fromHex(0xFFFF00); + Color CYAN = Color.fromHex(0x00FFFF); + Color MAGENTA = Color.fromHex(0xFF00FF); + + Color PINK = Color.fromHex(0xFF3FFC); + Color ORANGE = Color.fromHex(0xFC4800); +} diff --git a/src/mightypork/util/math/color/ZX.java b/src/mightypork/util/math/color/ZX.java new file mode 100644 index 0000000..418082a --- /dev/null +++ b/src/mightypork/util/math/color/ZX.java @@ -0,0 +1,28 @@ +package mightypork.util.math.color; + + +/** + * ZX Spectrum palette + * + * @author MightyPork + */ +public interface ZX { + + Color BLACK = Color.fromHex(0x000000); + Color GRAY = Color.fromHex(0xCBCBCB); + Color WHITE = Color.fromHex(0xFFFFFF); + + Color RED_DARK = Color.fromHex(0xD8240F); + Color RED_LIGHT = Color.fromHex(0xFF3016); + Color MAGENTA_DARK = Color.fromHex(0xD530C9); + Color MAGENTA_LIGHT = Color.fromHex(0xFF3FFC); + Color BLUE_DARK = Color.fromHex(0x001DC8); + Color BLUE_LIGHT = Color.fromHex(0x0027FB); + Color CYAN_DARK = Color.fromHex(0x00C9CB); + Color CYAN_LIGHT = Color.fromHex(0xFFFD33); + Color GREEN_DARK = Color.fromHex(0x00C721); + Color GREEN_LIGHT = Color.fromHex(0x00F92C); + + Color YELLOW_DARK = Color.fromHex(0xCECA26); + Color YELLOW_LIGHT = Color.fromHex(0xFFFD33); +}