Preparation for textures, improved EventBus & events

v5stable
Ondřej Hruška 10 years ago
parent cf4e6e0a6d
commit 7f35d1d316
  1. 217
      src/mightypork/rogue/App.java
  2. 7
      src/mightypork/rogue/AppAccess.java
  3. 8
      src/mightypork/rogue/AppAdapter.java
  4. 33
      src/mightypork/rogue/Resources.java
  5. 4
      src/mightypork/rogue/bus/Subsystem.java
  6. 1
      src/mightypork/rogue/display/DisplaySystem.java
  7. 2
      src/mightypork/rogue/display/LayeredScreen.java
  8. 2
      src/mightypork/rogue/display/Screen.java
  9. 2
      src/mightypork/rogue/display/ScreenLayer.java
  10. 12
      src/mightypork/rogue/display/constraints/ElementHolder.java
  11. 22
      src/mightypork/rogue/display/screens/ScreenRegistry.java
  12. 186
      src/mightypork/rogue/display/screens/ScreenTestAnimations.java
  13. 20
      src/mightypork/rogue/display/screens/screenBouncy/BouncyBox.java
  14. 5
      src/mightypork/rogue/display/screens/screenBouncy/LayerBouncyBoxes.java
  15. 6
      src/mightypork/rogue/display/screens/screenTextures/ScreenTextureTest.java
  16. 2
      src/mightypork/rogue/input/InputSystem.java
  17. 2
      src/mightypork/rogue/sounds/AudioX.java
  18. 4
      src/mightypork/rogue/sounds/LoopPlayer.java
  19. 2
      src/mightypork/rogue/sounds/SoundSystem.java
  20. 140
      src/mightypork/rogue/textures/MultiTexture.java
  21. 19
      src/mightypork/rogue/textures/Render.java
  22. 124
      src/mightypork/rogue/textures/TextureRegistry.java
  23. 22
      src/mightypork/rogue/textures/TxQuad.java
  24. 47
      src/mightypork/utils/control/bus/EventBus.java
  25. 10
      src/mightypork/utils/control/bus/EventChannel.java
  26. 16
      src/mightypork/utils/control/bus/events/DestroyEvent.java
  27. 3
      src/mightypork/utils/control/bus/events/UpdateEvent.java
  28. 2
      src/mightypork/utils/control/interf/Destroyable.java
  29. 2
      src/mightypork/utils/control/interf/Updateable.java
  30. 2
      src/mightypork/utils/math/Calc.java
  31. 5
      src/mightypork/utils/math/animation/AnimDouble.java
  32. 3
      src/mightypork/utils/math/animation/AnimDoubleDeg.java
  33. 3
      src/mightypork/utils/math/animation/AnimDoubleRad.java
  34. 2
      src/mightypork/utils/math/animation/Easing.java
  35. 7
      src/mightypork/utils/math/constraints/Constraint.java
  36. 34
      src/mightypork/utils/math/constraints/ConstraintFactory.java
  37. 2
      src/mightypork/utils/math/constraints/NumConstraint.java
  38. 2
      src/mightypork/utils/math/constraints/RectConstraint.java
  39. 2
      src/mightypork/utils/math/coord/CoordAnimated.java

@ -14,12 +14,12 @@ import mightypork.rogue.input.InputSystem;
import mightypork.rogue.input.KeyStroke; import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.sounds.SoundSystem; import mightypork.rogue.sounds.SoundSystem;
import mightypork.rogue.tasks.TaskTakeScreenshot; import mightypork.rogue.tasks.TaskTakeScreenshot;
import mightypork.rogue.textures.TextureRegistry;
import mightypork.rogue.util.Utils; import mightypork.rogue.util.Utils;
import mightypork.utils.control.Destroyable;
import mightypork.utils.control.bus.EventBus; import mightypork.utils.control.bus.EventBus;
import mightypork.utils.control.bus.events.DestroyEvent;
import mightypork.utils.control.bus.events.UpdateEvent;
import mightypork.utils.control.timing.TimerDelta; import mightypork.utils.control.timing.TimerDelta;
import mightypork.utils.control.timing.UpdateEvent;
import mightypork.utils.control.timing.Updateable;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
import mightypork.utils.logging.LogInstance; import mightypork.utils.logging.LogInstance;
@ -31,15 +31,17 @@ import org.lwjgl.input.Keyboard;
* *
* @author MightyPork * @author MightyPork
*/ */
public class App implements Destroyable, AppAccess { public class App implements AppAccess {
/** instance pointer */ /** instance pointer */
private static App inst; private static App inst;
private InputSystem input; // modules
private SoundSystem sounds; private InputSystem inputSystem;
private DisplaySystem display; private SoundSystem soundSystem;
private EventBus events; private DisplaySystem displaySystem;
private EventBus eventBus;
private TextureRegistry textureRegistry;
/** current screen */ /** current screen */
private Screen screen; private Screen screen;
@ -50,6 +52,9 @@ public class App implements Destroyable, AppAccess {
/** Log instance; accessible as static via Log. */ /** Log instance; accessible as static via Log. */
private LogInstance log; private LogInstance log;
/** timer */
private TimerDelta timerRender;
/** /**
* @param args * @param args
@ -71,6 +76,43 @@ public class App implements Destroyable, AppAccess {
} }
/**
* Start the application
*/
private void start()
{
initialize();
mainLoop();
shutdown();
}
/**
* App main loop
*/
private void mainLoop()
{
screen = new TestLayeredScreen(this);
screen.setActive(true);
timerRender = new TimerDelta();
while (!displaySystem.isCloseRequested()) {
displaySystem.beginFrame();
eventBus.broadcast(new UpdateEvent(timerRender.getDelta()));
if (scheduledScreenshot) {
takeScreenshot();
scheduledScreenshot = false;
}
displaySystem.endFrame();
}
}
/** /**
* Handle a crash * Handle a crash
* *
@ -87,7 +129,8 @@ public class App implements Destroyable, AppAccess {
@Override @Override
public void shutdown() public void shutdown()
{ {
destroy(); bus().broadcast(new DestroyEvent());
System.exit(0); System.exit(0);
} }
@ -95,21 +138,33 @@ public class App implements Destroyable, AppAccess {
public void initialize() public void initialize()
{ {
Log.i("Initializing subsystems"); Log.i("Initializing subsystems");
// lock working directory
initLock(); initLock();
initBus();
initLogger(); // setup logging
initDisplay(); log = Log.create("runtime", Paths.LOGS, 10);
initSound(); log.enable(Config.LOGGING_ENABLED);
initInput(); log.enableSysout(Config.LOG_TO_STDOUT);
}
// event bus
eventBus = new EventBus();
@Override
public void destroy() // Subsystems
{ textureRegistry = new TextureRegistry(this);
if (sounds != null) sounds.destroy();
if (input != null) input.destroy(); displaySystem = new DisplaySystem(this);
if (display != null) display.destroy(); displaySystem.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR);
displaySystem.setTargetFps(Const.FPS_RENDER);
soundSystem = new SoundSystem(this);
soundSystem.setMasterVolume(1);
inputSystem = new InputSystem(this);
setupGlobalKeystrokes();
// load resources
Resources.load(this);
} }
@ -170,34 +225,9 @@ public class App implements Destroyable, AppAccess {
/** /**
* initialize inputs * initialize inputs
*/ */
private void initBus() private void setupGlobalKeystrokes()
{
events = new EventBus();
events.subscribe(this);
events.createChannel(UpdateEvent.class, Updateable.class);
}
/**
* initialize sound system
*/
private void initSound()
{
sounds = new SoundSystem(this);
sounds.setMasterVolume(1);
}
/**
* initialize inputs
*/
private void initInput()
{ {
input = new InputSystem(this); inputSystem.bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
input.bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
@Override @Override
public void run() public void run()
@ -207,17 +237,17 @@ public class App implements Destroyable, AppAccess {
} }
}); });
input.bindKeyStroke(new KeyStroke(false, Keyboard.KEY_F11), new Runnable() { inputSystem.bindKeyStroke(new KeyStroke(false, Keyboard.KEY_F11), new Runnable() {
@Override @Override
public void run() public void run()
{ {
Log.f3("F11, toggling fullscreen."); Log.f3("F11, toggling fullscreen.");
display.switchFullscreen(); displaySystem.switchFullscreen();
} }
}); });
input.bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() { inputSystem.bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() {
@Override @Override
public void run() public void run()
@ -229,75 +259,13 @@ public class App implements Destroyable, AppAccess {
} }
/**
* initialize display
*/
private void initDisplay()
{
display = new DisplaySystem(this);
display.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR);
display.setTargetFps(Const.FPS_RENDER);
}
/**
* initialize main logger
*/
private void initLogger()
{
log = Log.create("runtime", Paths.LOGS, 10);
log.enable(Config.LOGGING_ENABLED);
log.enableSysout(Config.LOG_TO_STDOUT);
}
private void start()
{
initialize();
mainLoop();
shutdown();
}
/** timer */
private TimerDelta timerRender;
/**
* App main loop
*/
private void mainLoop()
{
screen = new TestLayeredScreen(this);
screen.setActive(true);
timerRender = new TimerDelta();
while (!display.isCloseRequested()) {
display.beginFrame();
events.broadcast(new UpdateEvent(timerRender.getDelta()));
if (scheduledScreenshot) {
takeScreenshot();
scheduledScreenshot = false;
}
display.endFrame();
}
}
/** /**
* Do take a screenshot * Do take a screenshot
*/ */
private void takeScreenshot() private void takeScreenshot()
{ {
sounds.getEffect("gui.shutter").play(1); soundSystem.getEffect("gui.shutter").play(1);
Utils.runAsThread(new TaskTakeScreenshot(display)); Utils.runAsThread(new TaskTakeScreenshot(displaySystem));
} }
@ -307,7 +275,7 @@ public class App implements Destroyable, AppAccess {
@Override @Override
public SoundSystem snd() public SoundSystem snd()
{ {
return sounds; return soundSystem;
} }
@ -317,7 +285,7 @@ public class App implements Destroyable, AppAccess {
@Override @Override
public InputSystem input() public InputSystem input()
{ {
return input; return inputSystem;
} }
@ -327,7 +295,7 @@ public class App implements Destroyable, AppAccess {
@Override @Override
public DisplaySystem disp() public DisplaySystem disp()
{ {
return display; return displaySystem;
} }
@ -337,7 +305,14 @@ public class App implements Destroyable, AppAccess {
@Override @Override
public EventBus bus() public EventBus bus()
{ {
return events; return eventBus;
}
@Override
public TextureRegistry tx()
{
return textureRegistry;
} }
} }

@ -4,6 +4,7 @@ package mightypork.rogue;
import mightypork.rogue.display.DisplaySystem; import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.input.InputSystem; import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem; import mightypork.rogue.sounds.SoundSystem;
import mightypork.rogue.textures.TextureRegistry;
import mightypork.utils.control.bus.EventBus; import mightypork.utils.control.bus.EventBus;
@ -38,6 +39,12 @@ public interface AppAccess {
abstract EventBus bus(); abstract EventBus bus();
/**
* @return texture registry
*/
abstract TextureRegistry tx();
/** /**
* Quit to OS<br> * Quit to OS<br>
* Destroy app & exit VM * Destroy app & exit VM

@ -4,6 +4,7 @@ package mightypork.rogue;
import mightypork.rogue.display.DisplaySystem; import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.input.InputSystem; import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem; import mightypork.rogue.sounds.SoundSystem;
import mightypork.rogue.textures.TextureRegistry;
import mightypork.utils.control.bus.EventBus; import mightypork.utils.control.bus.EventBus;
@ -58,4 +59,11 @@ public class AppAdapter implements AppAccess {
app.shutdown(); app.shutdown();
} }
@Override
public TextureRegistry tx()
{
return app.tx();
}
} }

@ -0,0 +1,33 @@
package mightypork.rogue;
public class Resources {
public static void load(AppAccess app)
{
loadSounds(app);
loadTextures(app);
loadFonts(app);
}
private static void loadFonts(AppAccess app)
{
}
private static void loadTextures(AppAccess app)
{
}
private static void loadSounds(AppAccess app)
{
}
}

@ -2,9 +2,9 @@ package mightypork.rogue.bus;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.utils.control.Destroyable;
import mightypork.utils.control.bus.clients.DelegatingClient; import mightypork.utils.control.bus.clients.DelegatingClient;
import mightypork.utils.control.bus.clients.ToggleableClient; import mightypork.utils.control.bus.clients.ToggleableClient;
import mightypork.utils.control.interf.Destroyable;
/** /**
@ -27,8 +27,6 @@ public abstract class Subsystem extends ChildClient implements DelegatingClient,
{ {
deinit(); deinit();
setListening(false);
bus().unsubscribe(this); bus().unsubscribe(this);
} }

@ -3,7 +3,6 @@ package mightypork.rogue.display;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;

@ -4,7 +4,7 @@ package mightypork.rogue.display;
import java.util.LinkedList; import java.util.LinkedList;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
public abstract class LayeredScreen extends Screen { public abstract class LayeredScreen extends Screen {

@ -8,7 +8,7 @@ import mightypork.rogue.bus.events.ScreenChangeEvent;
import mightypork.rogue.input.KeyBinder; import mightypork.rogue.input.KeyBinder;
import mightypork.rogue.input.KeyBindingPool; import mightypork.rogue.input.KeyBindingPool;
import mightypork.rogue.input.KeyStroke; import mightypork.rogue.input.KeyStroke;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.constraints.ConstraintContext; import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;

@ -3,7 +3,7 @@ package mightypork.rogue.display;
import mightypork.rogue.bus.ChildClient; import mightypork.rogue.bus.ChildClient;
import mightypork.rogue.display.constraints.Renderable; import mightypork.rogue.display.constraints.Renderable;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.constraints.ConstraintContext; import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;

@ -5,11 +5,18 @@ import java.util.LinkedList;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.ChildClient; import mightypork.rogue.bus.ChildClient;
import mightypork.utils.control.bus.EventBus;
import mightypork.utils.math.constraints.ConstraintContext; import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.constraints.RectConstraint; import mightypork.utils.math.constraints.RectConstraint;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
/**
* Bag for {@link RenderableWithContext} elements with constraints.<br>
* Elements are exposed to {@link EventBus}.
*
* @author MightyPork
*/
public class ElementHolder extends ChildClient implements ConstraintContext, RenderableWithContext { public class ElementHolder extends ChildClient implements ConstraintContext, RenderableWithContext {
private LinkedList<RenderableWithContext> elements = new LinkedList<RenderableWithContext>(); private LinkedList<RenderableWithContext> elements = new LinkedList<RenderableWithContext>();
@ -67,8 +74,9 @@ public class ElementHolder extends ChildClient implements ConstraintContext, Ren
/** /**
* Add element to the holder. * Add element to the holder.
* *
* @param elem * @param elem element; it's context will be set to the constraint.
* @param constraint * @param constraint Constraint to be used for the element. It's context
* will be set to this {@link ElementHolder}
*/ */
public void add(RenderableWithContext elem, RectConstraint constraint) public void add(RenderableWithContext elem, RectConstraint constraint)
{ {

@ -0,0 +1,22 @@
package mightypork.rogue.display.screens;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem;
public class ScreenRegistry extends Subsystem {
public ScreenRegistry(AppAccess app) {
super(app);
}
@Override
protected void deinit()
{
// TODO Auto-generated method stub
}
}

@ -1,186 +0,0 @@
package mightypork.rogue.display.screens;
import java.util.Random;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.display.Screen;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.textures.Render;
import mightypork.utils.control.timing.animation.AnimDouble;
import mightypork.utils.control.timing.animation.AnimDoubleDeg;
import mightypork.utils.math.Polar;
import mightypork.utils.math.color.RGB;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.easing.Easing;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Listener {
public ScreenTestAnimations(AppAccess app) {
super(app);
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
@Override
public void run()
{
for (AnimDouble a : anims) {
a.animate(0, 1, 1 + rand.nextDouble() * 1);
}
}
});
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
@Override
public void run()
{
for (AnimDouble a : anims) {
a.animate(1, 0, 1 + rand.nextDouble() * 1);
}
}
});
}
private Random rand = new Random();
private AnimDoubleDeg degAnim = new AnimDoubleDeg(0, Easing.ELASTIC_OUT);
//@formatter:off
private AnimDouble[] anims = new AnimDouble[] {
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
new AnimDouble(0, Easing.BOUNCE_OUT),
// new AnimDouble(0, Easing.NONE),
// new AnimDouble(0, Easing.LINEAR),
//
// new AnimDouble(0, Easing.QUADRATIC_IN),
// new AnimDouble(0, Easing.QUADRATIC_OUT),
// new AnimDouble(0, Easing.QUADRATIC_IN_OUT),
//
// new AnimDouble(0, Easing.CUBIC_IN),
// new AnimDouble(0, Easing.CUBIC_OUT),
// new AnimDouble(0, Easing.CUBIC_IN_OUT),
//
// new AnimDouble(0, Easing.QUADRATIC_IN),
// new AnimDouble(0, Easing.QUADRATIC_OUT),
// new AnimDouble(0, Easing.QUADRATIC_IN_OUT),
//
// new AnimDouble(0, Easing.QUINTIC_IN),
// new AnimDouble(0, Easing.QUINTIC_OUT),
// new AnimDouble(0, Easing.QUINTIC_IN_OUT),
//
// new AnimDouble(0, Easing.EXPO_IN),
// new AnimDouble(0, Easing.EXPO_OUT),
// new AnimDouble(0, Easing.EXPO_IN_OUT),
//
// new AnimDouble(0, Easing.SINE_IN),
// new AnimDouble(0, Easing.SINE_OUT),
// new AnimDouble(0, Easing.SINE_IN_OUT),
//
// new AnimDouble(0, Easing.CIRC_IN),
// new AnimDouble(0, Easing.CIRC_OUT),
// new AnimDouble(0, Easing.CIRC_IN_OUT),
//
// new AnimDouble(0, Easing.BOUNCE_IN),
// new AnimDouble(0, Easing.BOUNCE_OUT),
// new AnimDouble(0, Easing.BOUNCE_IN_OUT),
//
// new AnimDouble(0, Easing.BACK_IN),
// new AnimDouble(0, Easing.BACK_OUT),
// new AnimDouble(0, Easing.BACK_IN_OUT),
//
// new AnimDouble(0, Easing.ELASTIC_IN),
// new AnimDouble(0, Easing.ELASTIC_OUT),
// new AnimDouble(0, Easing.ELASTIC_IN_OUT),
};
//@formatter:on
@Override
protected void deinitScreen()
{
// no impl
}
@Override
protected void onScreenEnter()
{
// no impl
}
@Override
protected void onScreenLeave()
{
// no impl
}
@Override
protected void updateScreen(double delta)
{
degAnim.update(delta);
for (AnimDouble a : anims) {
a.update(delta);
}
}
@Override
protected void renderScreen()
{
double screenH = Display.getHeight();
double screenW = Display.getWidth();
double perBoxH = screenH / anims.length;
double padding = perBoxH * 0.1;
double boxSide = perBoxH - padding * 2;
for (int i = 0; i < anims.length; i++) {
AnimDouble a = anims[i];
Render.setColor(RGB.GREEN);
Render.quadSize(padding + a.getCurrentValue() * (screenW - perBoxH), screenH - perBoxH * i - perBoxH + padding, boxSide, boxSide);
}
Render.setColor(RGB.YELLOW);
Render.translate(new Coord(Display.getWidth() / 2, Display.getHeight() / 2));
Render.rotateZ(degAnim.getCurrentValue());
Render.quadSize(-10, -10, 20, 200);
}
@Override
public void receive(MouseButtonEvent event)
{
if (event.isDown()) {
Coord vec = disp().getSize().half().vecTo(event.getPos());
Polar p = Polar.fromCoord(vec);
degAnim.fadeTo(p.getAngleDeg() - 90, 1.5);
}
}
}

@ -7,14 +7,14 @@ import java.util.Random;
import mightypork.rogue.display.constraints.RenderableWithContext; import mightypork.rogue.display.constraints.RenderableWithContext;
import mightypork.rogue.textures.Render; import mightypork.rogue.textures.Render;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.control.timing.animation.AnimDouble; import mightypork.utils.math.animation.AnimDouble;
import mightypork.utils.math.animation.Easing;
import mightypork.utils.math.color.RGB; import mightypork.utils.math.color.RGB;
import mightypork.utils.math.constraints.ConstraintContext; import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.constraints.NumConstraint; import mightypork.utils.math.constraints.NumConstraint;
import mightypork.utils.math.constraints.RectConstraint; import mightypork.utils.math.constraints.RectConstraint;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
import mightypork.utils.math.easing.Easing;
public class BouncyBox implements RenderableWithContext, Updateable, ConstraintContext { public class BouncyBox implements RenderableWithContext, Updateable, ConstraintContext {
@ -29,13 +29,19 @@ public class BouncyBox implements RenderableWithContext, Updateable, ConstraintC
public BouncyBox() { public BouncyBox() {
// create box
NumConstraint side = c_height(this); NumConstraint side = c_height(this);
RectConstraint abox = c_box_sized(this, side, side);
// move
NumConstraint move_length = c_sub(c_width(this), side); NumConstraint move_length = c_sub(c_width(this), side);
NumConstraint offset = c_mul(move_length, c_n(pos)); NumConstraint offset = c_mul(move_length, c_n(pos));
RectConstraint abox = c_sizedBox(this, offset, c_n(0), side, side); abox = c_move(abox, offset, c_n(0));
NumConstraint margin = c_percent(side, c_n(10));
RectConstraint with_margin = c_shrink(abox, margin); // add padding
box = with_margin; abox = c_shrink(abox, c_percent(side, c_n(10)));
box = abox;
} }

@ -9,6 +9,7 @@ import java.util.List;
import mightypork.rogue.display.Screen; import mightypork.rogue.display.Screen;
import mightypork.rogue.display.ScreenLayer; import mightypork.rogue.display.ScreenLayer;
import mightypork.rogue.display.constraints.ElementHolder; import mightypork.rogue.display.constraints.ElementHolder;
import mightypork.utils.math.constraints.RectConstraint;
public class LayerBouncyBoxes extends ScreenLayer { public class LayerBouncyBoxes extends ScreenLayer {
@ -20,7 +21,9 @@ public class LayerBouncyBoxes extends ScreenLayer {
public LayerBouncyBoxes(Screen screen) { public LayerBouncyBoxes(Screen screen) {
super(screen); super(screen);
layout = new ElementHolder(screen, c_shrink(this, c_percent(c_height(this), c_n(8)))); RectConstraint holder_rect = c_shrink(this, c_percent(c_height(this), c_n(8)));
layout = new ElementHolder(screen, holder_rect);
addChildClient(layout); addChildClient(layout);
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {

@ -0,0 +1,6 @@
package mightypork.rogue.display.screens.screenTextures;
public class ScreenTextureTest {
}

@ -6,7 +6,7 @@ import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.KeyboardEvent; import mightypork.rogue.bus.events.KeyboardEvent;
import mightypork.rogue.bus.events.MouseButtonEvent; import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.bus.events.MouseMotionEvent; import mightypork.rogue.bus.events.MouseMotionEvent;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLException;

@ -1,7 +1,7 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.control.Destroyable; import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.files.FileUtils; import mightypork.utils.files.FileUtils;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;

@ -1,9 +1,9 @@
package mightypork.rogue.sounds; package mightypork.rogue.sounds;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.control.timing.Pauseable; import mightypork.utils.control.timing.Pauseable;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.math.animation.AnimDouble;
import mightypork.utils.control.timing.animation.AnimDouble;
import mightypork.utils.objects.Mutable; import mightypork.utils.objects.Mutable;
import org.lwjgl.openal.AL10; import org.lwjgl.openal.AL10;

@ -9,7 +9,7 @@ import java.util.Set;
import mightypork.rogue.AppAccess; import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem; import mightypork.rogue.bus.Subsystem;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
import mightypork.utils.math.Calc.Buffers; import mightypork.utils.math.Calc.Buffers;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;

@ -0,0 +1,140 @@
package mightypork.rogue.textures;
import mightypork.utils.math.coord.Rect;
import org.newdawn.slick.opengl.Texture;
public class MultiTexture implements Texture {
private Texture backingTexture;
private String resourcePath;
public MultiTexture(String resourcePath) {
this.resourcePath = resourcePath;
}
public TxQuad getQuad(Rect rect)
{
return new TxQuad(this, rect);
}
/**
* Attempt to load the texture.
*/
private void load()
{
if (backingTexture == null) {
backingTexture = Render.loadTexture(resourcePath);
}
}
@Override
public boolean hasAlpha()
{
load();
return backingTexture.hasAlpha();
}
@Override
public String getTextureRef()
{
load();
return backingTexture.getTextureRef();
}
@Override
public void bind()
{
load();
backingTexture.bind();
}
@Override
public int getImageHeight()
{
load();
return backingTexture.getImageHeight();
}
@Override
public int getImageWidth()
{
load();
return backingTexture.getImageWidth();
}
@Override
public float getHeight()
{
load();
return backingTexture.getHeight();
}
@Override
public float getWidth()
{
load();
return backingTexture.getWidth();
}
@Override
public int getTextureHeight()
{
load();
return backingTexture.getTextureHeight();
}
@Override
public int getTextureWidth()
{
load();
return backingTexture.getTextureWidth();
}
@Override
public void release()
{
if (backingTexture == null) return;
backingTexture.release();
}
@Override
public int getTextureID()
{
load();
return backingTexture.getTextureID();
}
@Override
public byte[] getTextureData()
{
load();
return backingTexture.getTextureData();
}
@Override
public void setTextureFilter(int textureFilter)
{
load();
backingTexture.setTextureFilter(textureFilter);
}
}

@ -13,6 +13,7 @@ import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
import org.newdawn.slick.opengl.Texture; import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureImpl;
import org.newdawn.slick.opengl.TextureLoader; import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader; import org.newdawn.slick.util.ResourceLoader;
@ -28,7 +29,6 @@ public class Render {
private static final Coord AXIS_Y = new Coord(0, 1, 0); private static final Coord AXIS_Y = new Coord(0, 1, 0);
private static final Coord AXIS_Z = new Coord(0, 0, 1); private static final Coord AXIS_Z = new Coord(0, 0, 1);
public static Texture lastBinded = null;
private static boolean inited = false; private static boolean inited = false;
@ -998,7 +998,7 @@ public class Render {
} catch (IOException e) { } catch (IOException e) {
Log.e("Loading of texture " + resourcePath + " failed.", e); Log.e("Loading of texture " + resourcePath + " failed.", e);
throw new RuntimeException(e); throw new RuntimeException("Could not load texture " + resourcePath + ".", e);
} }
} }
@ -1012,11 +1012,12 @@ public class Render {
*/ */
public static void bindTexture(Texture texture) throws RuntimeException public static void bindTexture(Texture texture) throws RuntimeException
{ {
if (texture != lastBinded) { texture.bind();
glBindTexture(GL_TEXTURE_2D, 0); // if (texture != lastBinded) {
glBindTexture(GL_TEXTURE_2D, texture.getTextureID()); // glBindTexture(GL_TEXTURE_2D, 0);
lastBinded = texture; // glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
} // lastBinded = texture;
// }
} }
@ -1025,7 +1026,7 @@ public class Render {
*/ */
public static void unbindTexture() public static void unbindTexture()
{ {
glBindTexture(GL_TEXTURE_2D, 0); TextureImpl.bindNone();
lastBinded = null; // glBindTexture(GL_TEXTURE_2D, 0);
} }
} }

@ -0,0 +1,124 @@
package mightypork.rogue.textures;
import java.util.HashMap;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem;
import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.math.coord.Rect;
import org.newdawn.slick.opengl.Texture;
/**
* Texture loader and quad registry
*
* @author MightyPork
*/
public class TextureRegistry extends Subsystem implements Destroyable {
public TextureRegistry(AppAccess app) {
super(app);
}
private HashMap<String, MultiTexture> textures = new HashMap<String, MultiTexture>();
private HashMap<String, TxQuad> quads = new HashMap<String, TxQuad>();
private MultiTexture lastTx;
/**
* Load a {@link Texture} from resource
*
* @param key texture key
* @param resourcePath texture resource path
*/
public void loadTexture(String key, String resourcePath)
{
MultiTexture tx = new MultiTexture(resourcePath);
textures.put(key, tx);
lastTx = tx;
}
/**
* Create a {@link TxQuad} in a texture
*
* @param quadKey quad key
* @param textureKey texture key
* @param quad quad rectangle (absolute pixel coordinates) *
*/
public void makeQuad(String quadKey, String textureKey, Rect quad)
{
MultiTexture tx = textures.get(textureKey);
if (tx == null) throw new RuntimeException("Texture with key " + textureKey + " not defined!");
TxQuad txquad = tx.getQuad(quad);
quads.put(quadKey, txquad);
}
/**
* Create a {@link TxQuad} in the last loaded texture
*
* @param quadKey quad key
* @param quad quad rectangle (absolute pixel coordinates)
*/
public void makeQuad(String quadKey, Rect quad)
{
MultiTexture tx = lastTx;
if (tx == null) throw new RuntimeException("There's no texture loaded yet, can't define quads!");
TxQuad txquad = tx.getQuad(quad);
quads.put(quadKey, txquad);
}
/**
* Get a {@link TxQuad} for key
*
* @param key quad key
* @return the quad
*/
public TxQuad getQuad(String key)
{
TxQuad q = quads.get(key);
if (q == null) throw new RuntimeException("There's no quad called " + key + "!");
return q;
}
/**
* Get a loaded {@link Texture}
*
* @param key texture key
* @return the texture
*/
public Texture getTexture(String key)
{
Texture t = textures.get(key);
if (t == null) throw new RuntimeException("There's no texture called " + key + "!");
return t;
}
@Override
protected void deinit()
{
for (Texture tx : textures.values()) {
tx.release();
}
textures.clear();
quads.clear();
}
}

@ -38,17 +38,6 @@ public class TxQuad {
} }
/**
* @param tx Texture
* @param uvs Rect of texturwe UVs (pixels - from left top)
*/
public TxQuad(Texture tx, Rect uvs) {
this.tx = tx;
this.uvs = uvs.copy();
this.size = uvs.getSize();
}
/** /**
* Make of coords * Make of coords
* *
@ -59,8 +48,17 @@ public class TxQuad {
* @param y2 y2 * @param y2 y2
*/ */
public TxQuad(Texture tx, int x1, int y1, int x2, int y2) { public TxQuad(Texture tx, int x1, int y1, int x2, int y2) {
this(tx, new Rect(x1, y1, x2, y2));
}
/**
* @param tx Texture
* @param uvs Rect of texturwe UVs (pixels - from left top)
*/
public TxQuad(Texture tx, Rect uvs) {
this.tx = tx; this.tx = tx;
this.uvs = new Rect(x1, y1, x2, y2); this.uvs = uvs.copy();
this.size = uvs.getSize(); this.size = uvs.getSize();
} }

@ -2,8 +2,12 @@ package mightypork.utils.control.bus;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashSet; import java.util.concurrent.CopyOnWriteArraySet;
import mightypork.utils.control.bus.events.DestroyEvent;
import mightypork.utils.control.bus.events.UpdateEvent;
import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.logging.Log; import mightypork.utils.logging.Log;
@ -14,11 +18,24 @@ import mightypork.utils.logging.Log;
*/ */
final public class EventBus { final public class EventBus {
private Collection<EventChannel<?, ?>> channels = new LinkedHashSet<EventChannel<?, ?>>(); private Collection<EventChannel<?, ?>> channels = new CopyOnWriteArraySet<EventChannel<?, ?>>();
private Collection<Object> clients = new LinkedHashSet<Object>(); private Collection<Object> clients = new CopyOnWriteArraySet<Object>();
private boolean warn_unsent = true; private boolean logging = false;
public EventBus() {
// default channels
createChannel(DestroyEvent.class, Destroyable.class);
createChannel(UpdateEvent.class, Updateable.class);
}
public void enableLogging(boolean enable)
{
logging = enable;
}
/** /**
@ -33,7 +50,7 @@ final public class EventBus {
// if the channel already exists, return this instance instead. // if the channel already exists, return this instance instead.
for (EventChannel<?, ?> ch : channels) { for (EventChannel<?, ?> ch : channels) {
if (ch.equals(channel)) { if (ch.equals(channel)) {
Log.w("Channel of type " + channel + " already registered."); if (logging) Log.w("Channel of type " + channel + " already registered.");
return ch; return ch;
} }
} }
@ -63,13 +80,15 @@ final public class EventBus {
*/ */
public boolean broadcast(Object message) public boolean broadcast(Object message)
{ {
if (logging) Log.f3("<bus> Broadcasting: " + message);
boolean sent = false; boolean sent = false;
for (EventChannel<?, ?> b : channels) { for (EventChannel<?, ?> b : channels) {
sent |= b.broadcast(message, clients); sent |= b.broadcast(message, clients);
} }
if (!sent && warn_unsent) Log.w("Message not accepted by any channel: " + message); if (!sent && logging) Log.w("Message not accepted by any channel: " + message);
return sent; return sent;
} }
@ -103,17 +122,6 @@ final public class EventBus {
} }
/**
* Enable logging of unsent messages
*
* @param enable
*/
public void enableLoggingUnsent(boolean enable)
{
this.warn_unsent = enable;
}
/** /**
* Add a channel for given message and client type. * Add a channel for given message and client type.
* *
@ -123,8 +131,9 @@ final public class EventBus {
*/ */
public <F_EVENT extends Handleable<F_CLIENT>, F_CLIENT> EventChannel<?, ?> createChannel(Class<F_EVENT> messageClass, Class<F_CLIENT> clientClass) public <F_EVENT extends Handleable<F_CLIENT>, F_CLIENT> EventChannel<?, ?> createChannel(Class<F_EVENT> messageClass, Class<F_CLIENT> clientClass)
{ {
EventChannel<F_EVENT, F_CLIENT> bc = new EventChannel<F_EVENT, F_CLIENT>(messageClass, clientClass); EventChannel<F_EVENT, F_CLIENT> channel = EventChannel.create(messageClass, clientClass);
return addChannel(bc); channel.enableLogging(logging);
return addChannel(channel);
} }
} }

@ -20,6 +20,7 @@ final public class EventChannel<EVENT extends Handleable<CLIENT>, CLIENT> {
private Class<CLIENT> clientClass; private Class<CLIENT> clientClass;
private Class<EVENT> messageClass; private Class<EVENT> messageClass;
private boolean logging = false;
public EventChannel(Class<EVENT> messageClass, Class<CLIENT> clientClass) { public EventChannel(Class<EVENT> messageClass, Class<CLIENT> clientClass) {
@ -31,6 +32,12 @@ final public class EventChannel<EVENT extends Handleable<CLIENT>, CLIENT> {
} }
public void enableLogging(boolean enable)
{
logging = enable;
}
/** /**
* Try to broadcast a message.<br> * Try to broadcast a message.<br>
* If message is of wrong type, <code>false</code> is returned. * If message is of wrong type, <code>false</code> is returned.
@ -57,7 +64,7 @@ final public class EventChannel<EVENT extends Handleable<CLIENT>, CLIENT> {
// circular reference check // circular reference check
if (processed.contains(client)) { if (processed.contains(client)) {
Log.w("Client already served (subscribing twice?)"); if (logging) Log.w("Client already served (subscribing twice?)");
continue; continue;
} }
processed.add(client); processed.add(client);
@ -91,6 +98,7 @@ final public class EventChannel<EVENT extends Handleable<CLIENT>, CLIENT> {
{ {
if (clientClass.isInstance(client)) { if (clientClass.isInstance(client)) {
((Handleable<CLIENT>) message).handleBy((CLIENT) client); ((Handleable<CLIENT>) message).handleBy((CLIENT) client);
if (logging) Log.f3("<bus> Received by: " + client);
} }
} }

@ -0,0 +1,16 @@
package mightypork.utils.control.bus.events;
import mightypork.utils.control.bus.Handleable;
import mightypork.utils.control.interf.Destroyable;
public class DestroyEvent implements Handleable<Destroyable> {
@Override
public void handleBy(Destroyable handler)
{
handler.destroy();
}
}

@ -1,7 +1,8 @@
package mightypork.utils.control.timing; package mightypork.utils.control.bus.events;
import mightypork.utils.control.bus.Handleable; import mightypork.utils.control.bus.Handleable;
import mightypork.utils.control.interf.Updateable;
/** /**

@ -1,4 +1,4 @@
package mightypork.utils.control; package mightypork.utils.control.interf;
/** /**

@ -1,4 +1,4 @@
package mightypork.utils.control.timing; package mightypork.utils.control.interf;
/** /**

@ -6,8 +6,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import mightypork.utils.math.animation.Easing;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.easing.Easing;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;

@ -1,10 +1,9 @@
package mightypork.utils.control.timing.animation; package mightypork.utils.math.animation;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.control.timing.Pauseable; import mightypork.utils.control.timing.Pauseable;
import mightypork.utils.control.timing.Updateable;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
import mightypork.utils.math.easing.Easing;
/** /**

@ -1,9 +1,8 @@
package mightypork.utils.control.timing.animation; package mightypork.utils.math.animation;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
import mightypork.utils.math.Calc.Deg; import mightypork.utils.math.Calc.Deg;
import mightypork.utils.math.easing.Easing;
/** /**

@ -1,9 +1,8 @@
package mightypork.utils.control.timing.animation; package mightypork.utils.math.animation;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;
import mightypork.utils.math.Calc.Rad; import mightypork.utils.math.Calc.Rad;
import mightypork.utils.math.easing.Easing;
/** /**

@ -1,4 +1,4 @@
package mightypork.utils.math.easing; package mightypork.utils.math.animation;
/** /**

@ -9,12 +9,12 @@ import mightypork.utils.math.coord.Coord;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class BaseConstraint implements SettableContext { public abstract class Constraint implements SettableContext {
private ConstraintContext context = null; private ConstraintContext context = null;
public BaseConstraint(ConstraintContext context) { public Constraint(ConstraintContext context) {
this.context = context; this.context = context;
} }
@ -26,6 +26,9 @@ public abstract class BaseConstraint implements SettableContext {
} }
/**
* @return the context
*/
public ConstraintContext getContext() public ConstraintContext getContext()
{ {
return context; return context;

@ -1,7 +1,7 @@
package mightypork.utils.math.constraints; package mightypork.utils.math.constraints;
import mightypork.utils.control.timing.animation.AnimDouble; import mightypork.utils.math.animation.AnimDouble;
import mightypork.utils.math.coord.Coord; import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect; import mightypork.utils.math.coord.Rect;
@ -335,7 +335,35 @@ public class ConstraintFactory {
} }
public static RectConstraint c_sizedBox(ConstraintContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint width, final NumConstraint height) /**
* @param context
* @param width
* @param height
* @return
*/
public static RectConstraint c_box_sized(ConstraintContext context, final NumConstraint width, final NumConstraint height)
{
return new RectConstraint(context) {
@Override
public Rect getRect()
{
Coord origin = getOrigin();
//@formatter:off
return Rect.fromSize(
origin.x,
origin.y,
width.getValue(),
height.getValue()
);
//@formatter:on
}
};
}
public static RectConstraint c_box_sized(ConstraintContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint width, final NumConstraint height)
{ {
return new RectConstraint(context) { return new RectConstraint(context) {
@ -357,7 +385,7 @@ public class ConstraintFactory {
} }
public static RectConstraint c_posBox(ConstraintContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint right, final NumConstraint top) public static RectConstraint c_box_abs(ConstraintContext context, final NumConstraint left, final NumConstraint bottom, final NumConstraint right, final NumConstraint top)
{ {
return new RectConstraint(context) { return new RectConstraint(context) {

@ -6,7 +6,7 @@ package mightypork.utils.math.constraints;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class NumConstraint extends BaseConstraint { public abstract class NumConstraint extends Constraint {
public NumConstraint(ConstraintContext context) { public NumConstraint(ConstraintContext context) {
super(context); super(context);

@ -9,7 +9,7 @@ import mightypork.utils.math.coord.Rect;
* *
* @author MightyPork * @author MightyPork
*/ */
public abstract class RectConstraint extends BaseConstraint implements ConstraintContext { public abstract class RectConstraint extends Constraint implements ConstraintContext {
public RectConstraint(ConstraintContext context) { public RectConstraint(ConstraintContext context) {
super(context); super(context);

@ -1,7 +1,7 @@
package mightypork.utils.math.coord; package mightypork.utils.math.coord;
import mightypork.utils.control.timing.Updateable; import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.Calc; import mightypork.utils.math.Calc;

Loading…
Cancel
Save