FInal fields, tweaks to screen system, deferred loading.

This commit is contained in:
Ondřej Hruška
2014-04-05 02:14:35 +02:00
parent 53b7b02609
commit f5929f23b1
54 changed files with 820 additions and 366 deletions
+49 -13
View File
@@ -8,12 +8,16 @@ import java.util.ArrayList;
import javax.swing.JOptionPane;
import mightypork.rogue.audio.SoundSystem;
import mightypork.rogue.bus.events.*;
import mightypork.rogue.gui.screens.ScreenRegistry;
import mightypork.rogue.bus.events.ActionRequest.RequestType;
import mightypork.rogue.gui.ScreenRegistry;
import mightypork.rogue.gui.screens.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.gui.screens.test_cat_sound.ScreenTestCat;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.render.DisplaySystem;
import mightypork.rogue.sound.SoundSystem;
import mightypork.rogue.texture.DeferredLoader;
import mightypork.utils.control.bus.EventBus;
import mightypork.utils.control.bus.events.DestroyEvent;
import mightypork.utils.control.bus.events.UpdateEvent;
@@ -41,8 +45,7 @@ public class App implements AppAccess {
private static SoundSystem soundSystem;
private EventBus eventBus;
private MainLoop mainLoop;
public ScreenRegistry screens;
private ScreenRegistry screens;
/**
@@ -73,6 +76,8 @@ public class App implements AppAccess {
initialize();
Log.i("Starting main loop...");
// open first screen
mainLoop.start();
}
@@ -84,7 +89,12 @@ public class App implements AppAccess {
*/
public static void onCrash(Throwable error)
{
if (Log.ready()) {
Log.e("The game has crashed!", error);
} else {
System.err.println("The game has crashed!");
error.printStackTrace();
}
if (inst != null) inst.shutdown();
}
@@ -93,12 +103,12 @@ public class App implements AppAccess {
@Override
public void shutdown()
{
bus().send(new DestroyEvent());
Log.i("Shutting down subsystems...");
bus().send(new DestroyEvent());
bus().destroy();
Log.i("Shutting down...");
Log.i("Terminating...");
System.exit(0);
}
@@ -142,6 +152,14 @@ public class App implements AppAccess {
soundSystem = new SoundSystem(this);
soundSystem.setMasterVolume(1);
/*
* Load resources
*/
Log.f1("Registering resources...");
bus().subscribe(new DeferredLoader(this));
Res.load(this);
/*
* Input
*/
@@ -154,18 +172,14 @@ public class App implements AppAccess {
*/
Log.f2("Initializing screen registry...");
screens = new ScreenRegistry(this);
/*
* Load resources
*/
Log.f1("Registering resources...");
Res.load(this);
initScreens();
/*
* Prepare main loop
*/
Log.f1("Preparing main loop...");
ArrayList<Runnable> loopTasks = new ArrayList<Runnable>();
loopTasks.add(new Runnable() {
@Override
@@ -179,24 +193,44 @@ public class App implements AppAccess {
}
private void initScreens()
{
Log.f3("Registering game screens...");
screens.add(new ScreenTestBouncy(this));
screens.add(new ScreenTestCat(this));
screens.showScreen("test.cat");
}
private void initChannels()
{
Log.f3("Registering channels...");
// framework events
bus().addChannel(DestroyEvent.class, Destroyable.class);
bus().addChannel(UpdateEvent.class, Updateable.class);
// input events
bus().addChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
bus().addChannel(KeyboardEvent.class, KeyboardEvent.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(ActionRequest.class, ActionRequest.Listener.class);
bus().addChannel(MainLoopTaskRequest.class, MainLoopTaskRequest.Listener.class);
}
private void setupGlobalKeystrokes()
{
Log.f3("Setting up hot keys...");
// Go fullscreen
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_F11), new Runnable() {
@Override
@@ -206,6 +240,7 @@ public class App implements AppAccess {
}
});
// Take screenshot
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
@Override
@@ -215,6 +250,7 @@ public class App implements AppAccess {
}
});
// Exit
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() {
@Override
+1 -1
View File
@@ -1,9 +1,9 @@
package mightypork.rogue;
import mightypork.rogue.audio.SoundSystem;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.render.DisplaySystem;
import mightypork.rogue.sound.SoundSystem;
import mightypork.utils.control.bus.EventBus;
+1 -1
View File
@@ -1,9 +1,9 @@
package mightypork.rogue;
import mightypork.rogue.audio.SoundSystem;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.render.DisplaySystem;
import mightypork.rogue.sound.SoundSystem;
import mightypork.utils.control.bus.EventBus;
+16 -8
View File
@@ -8,15 +8,15 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.ActionRequest;
import mightypork.rogue.bus.events.RequestType;
import mightypork.rogue.bus.events.ScreenRequestEvent;
import mightypork.rogue.bus.events.ActionRequest.RequestType;
import mightypork.rogue.bus.events.MainLoopTaskRequest;
import mightypork.rogue.tasks.TaskTakeScreenshot;
import mightypork.rogue.util.Utils;
import mightypork.utils.control.bus.events.UpdateEvent;
import mightypork.utils.control.timing.TimerDelta;
public class MainLoop extends Subsystem implements ActionRequest.Listener {
public class MainLoop extends Subsystem implements ActionRequest.Listener, MainLoopTaskRequest.Listener {
private Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<Runnable>();
private List<Runnable> regularTasks;
@@ -35,8 +35,6 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener {
public void start()
{
bus().queue(new ScreenRequestEvent("test.texture"));
timer = new TimerDelta();
while (running) {
@@ -70,18 +68,19 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener {
{
switch (request) {
case FULLSCREEN:
taskQueue.add(taskFullscreen);
queueTask(taskFullscreen);
break;
case SCREENSHOT:
taskQueue.add(taskScreenshot);
queueTask(taskScreenshot);
break;
case SHUTDOWN:
taskQueue.add(taskShutdown);
queueTask(taskShutdown);
}
}
/** Take a screenshot */
private final Runnable taskScreenshot = new Runnable() {
@Override
@@ -92,6 +91,7 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener {
}
};
/** Shutdown the application */
private final Runnable taskShutdown = new Runnable() {
@Override
@@ -101,6 +101,7 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener {
}
};
/** Toggle fullscreen */
private final Runnable taskFullscreen = new Runnable() {
@Override
@@ -109,4 +110,11 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener {
disp().switchFullscreen();
}
};
@Override
public void queueTask(Runnable request)
{
taskQueue.add(request);
}
}
+12 -22
View File
@@ -1,13 +1,11 @@
package mightypork.rogue;
import mightypork.rogue.audio.EffectPlayer;
import mightypork.rogue.audio.LoopPlayer;
import mightypork.rogue.audio.SoundBank;
import mightypork.rogue.gui.screens.screenBouncy.ScreenTestAnim;
import mightypork.rogue.gui.screens.screenTextures.ScreenTextureTest;
import mightypork.rogue.render.textures.TextureBank;
import mightypork.rogue.render.textures.TxQuad;
import mightypork.rogue.sound.SoundBank;
import mightypork.rogue.sound.players.EffectPlayer;
import mightypork.rogue.sound.players.LoopPlayer;
import mightypork.rogue.texture.TextureBank;
import mightypork.rogue.texture.TxQuad;
import org.newdawn.slick.opengl.Texture;
@@ -27,26 +25,25 @@ public class Res {
textures = new TextureBank(app);
sounds = new SoundBank(app);
loadSounds(app);
loadTextures(app);
loadFonts(app);
loadScreens(app);
loadSounds();
loadTextures();
loadFonts();
}
private static void loadFonts(App app)
private static void loadFonts()
{
//
}
private static void loadTextures(App app)
private static void loadTextures()
{
textures.loadTexture("test.kitten", "/res/img/kitten.png");
}
private static void loadSounds(App app)
private static void loadSounds()
{
sounds.addEffect("gui.shutter", "/res/audio/shutter.ogg", 1, 1);
@@ -54,13 +51,6 @@ public class Res {
}
private static void loadScreens(App app)
{
app.screens.add("test.anim", new ScreenTestAnim(app));
app.screens.add("test.texture", new ScreenTextureTest(app));
}
public static TxQuad getTxQuad(String key)
{
return textures.getTxQuad(key);
+1 -1
View File
@@ -25,7 +25,7 @@ public class ChildClient extends AppAdapter implements DelegatingClient, Togglea
super(app);
}
private Set<Object> clients = new LinkedHashSet<Object>();
private final Set<Object> clients = new LinkedHashSet<Object>();
private boolean listening = true;
private boolean delegating = true;
@@ -2,16 +2,17 @@ package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
/**
* Request for action that should be performed in the main thread.
* Request for a global sction to be done in the main loop.
*
* @author MightyPork
*/
public class ActionRequest implements Event<ActionRequest.Listener> {
public class ActionRequest implements Event<ActionRequest.Listener>, SingularEvent {
private RequestType type;
private final RequestType type;
public ActionRequest(RequestType request) {
@@ -27,7 +28,16 @@ public class ActionRequest implements Event<ActionRequest.Listener> {
public interface Listener {
/**
* Perform the requested action
*
* @param request
*/
public void requestAction(RequestType request);
}
public static enum RequestType
{
FULLSCREEN, SCREENSHOT, SHUTDOWN;
}
}
@@ -13,9 +13,9 @@ import org.lwjgl.input.Keyboard;
*/
public class KeyboardEvent implements Event<KeyboardEvent.Listener> {
private int key;
private boolean down;
private char c;
private final int key;
private final boolean down;
private final char c;
public KeyboardEvent(int key, char c, boolean down) {
@@ -0,0 +1,38 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
/**
* Request to execute given {@link Runnable} in main loop.
*
* @author MightyPork
*/
public class MainLoopTaskRequest implements Event<MainLoopTaskRequest.Listener>, SingularEvent {
private final Runnable task;
public MainLoopTaskRequest(Runnable task) {
this.task = task;
}
@Override
public void handleBy(Listener handler)
{
handler.queueTask(task);
}
public interface Listener {
/**
* Perform the requested action
*
* @param request
*/
public void queueTask(Runnable request);
}
}
@@ -16,10 +16,10 @@ public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
public static final int BUTTON_MIDDLE = 1;
public static final int BUTTON_RIGHT = 2;
private int button;
private int wheeld;
private Coord pos;
private boolean down;
private final int button;
private final int wheeld;
private final Coord pos;
private final boolean down;
/**
@@ -7,8 +7,8 @@ import mightypork.utils.math.coord.Coord;
public class MouseMotionEvent implements Event<MouseMotionEvent.Listener> {
private Coord move;
private Coord pos;
private final Coord move;
private final Coord pos;
public MouseMotionEvent(Coord pos, Coord move) {
@@ -1,7 +0,0 @@
package mightypork.rogue.bus.events;
public enum RequestType
{
FULLSCREEN, SCREENSHOT, SHUTDOWN;
}
@@ -0,0 +1,39 @@
package mightypork.rogue.bus.events;
import mightypork.rogue.Deferred;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
/**
* Request to schedule loading a deferred resource.
*
* @author MightyPork
*/
public class ResourceLoadRequest implements Event<ResourceLoadRequest.Listener>, SingularEvent {
private final Deferred resource;
public ResourceLoadRequest(Deferred resource) {
this.resource = resource;
}
@Override
public void handleBy(Listener handler)
{
handler.loadResource(resource);
}
public interface Listener {
/**
* Load a resource
*
* @param resource
*/
public void loadResource(Deferred resource);
}
}
@@ -7,9 +7,9 @@ import mightypork.utils.math.coord.Coord;
public class ScreenChangeEvent implements Event<ScreenChangeEvent.Listener> {
private boolean fullscreen;
private Coord screenSize;
private boolean fsChanged;
private final boolean fullscreen;
private final Coord screenSize;
private final boolean fsChanged;
public ScreenChangeEvent(boolean fsChanged, boolean fullscreen, Coord size) {
@@ -2,11 +2,12 @@ package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
public class ScreenRequestEvent implements Event<ScreenRequestEvent.Listener> {
public class ScreenRequestEvent implements Event<ScreenRequestEvent.Listener>, SingularEvent {
private String scrName;
private final String scrName;
public ScreenRequestEvent(String screenKey) {
@@ -1,15 +1,15 @@
package mightypork.rogue.gui.screens;
package mightypork.rogue.gui;
import java.util.Collection;
import java.util.LinkedList;
import mightypork.rogue.AppAccess;
import mightypork.utils.control.interf.Updateable;
public abstract class LayeredScreen extends Screen {
private final LinkedList<ScreenLayer> layers = new LinkedList<ScreenLayer>();
private final Collection<ScreenLayer> layers = new LinkedList<ScreenLayer>();
public LayeredScreen(AppAccess app) {
@@ -17,18 +17,6 @@ public abstract class LayeredScreen extends Screen {
}
@Override
protected abstract void deinitScreen();
@Override
protected abstract void onScreenEnter();
@Override
protected abstract void onScreenLeave();
@Override
protected final void renderScreen()
{
@@ -38,14 +26,6 @@ public abstract class LayeredScreen extends Screen {
}
/**
* Update screen. Layers should implement {@link Updateable} to receive
* updates directly from bus.
*/
@Override
protected abstract void updateScreen(double delta);
/**
* Add a layer to the screen.
*
@@ -1,4 +1,4 @@
package mightypork.rogue.gui.screens;
package mightypork.rogue.gui;
import static org.lwjgl.opengl.GL11.*;
@@ -10,20 +10,17 @@ import mightypork.rogue.input.KeyBindingPool;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.render.Render;
import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect;
/**
* Screen class.<br>
* Screen animates 3D world, while contained panels render 2D overlays, process
* inputs and run the game logic.
* Screen class.
*
* @author MightyPork
*/
public abstract class Screen extends ChildClient implements Destroyable, Updateable, KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
public abstract class Screen extends ChildClient implements Destroyable, KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
private final KeyBindingPool keybindings = new KeyBindingPool();
@@ -127,14 +124,6 @@ public abstract class Screen extends ChildClient implements Destroyable, Updatea
protected abstract void renderScreen();
/**
* Update animations and timing.<br>
*
* @param delta time elapsed
*/
protected abstract void updateScreen(double delta);
/**
* Render screen
*/
@@ -173,16 +162,6 @@ public abstract class Screen extends ChildClient implements Destroyable, Updatea
}
/**
* Update and render the screen
*/
@Override
public final void update(double delta)
{
updateScreen(delta);
}
@Override
public final Rect getRect()
{
@@ -241,4 +220,6 @@ public abstract class Screen extends ChildClient implements Destroyable, Updatea
glMatrixMode(GL_MODELVIEW);
}
public abstract String getId();
}
@@ -1,9 +1,11 @@
package mightypork.rogue.gui.screens;
package mightypork.rogue.gui;
import mightypork.rogue.bus.ChildClient;
import mightypork.rogue.gui.constraints.Renderable;
import mightypork.utils.control.interf.Updateable;
import mightypork.rogue.input.KeyBinder;
import mightypork.rogue.input.KeyBindingPool;
import mightypork.rogue.input.KeyStroke;
import mightypork.utils.math.constraints.ConstraintContext;
import mightypork.utils.math.coord.Rect;
@@ -13,24 +15,33 @@ import mightypork.utils.math.coord.Rect;
*
* @author MightyPork
*/
public abstract class ScreenLayer extends ChildClient implements Renderable, Updateable, ConstraintContext {
public abstract class ScreenLayer extends ChildClient implements Renderable, ConstraintContext, KeyBinder {
private Screen screen;
private final Screen screen;
private final KeyBindingPool keybindings = new KeyBindingPool();
public ScreenLayer(Screen screen) {
super(screen); // screen as AppAccess
this.screen = screen;
addChildClient(keybindings);
}
@Override
public abstract void render();
public final void bindKeyStroke(KeyStroke stroke, Runnable task)
{
keybindings.bindKeyStroke(stroke, task);
}
@Override
public abstract void update(double delta);
public final void unbindKeyStroke(KeyStroke stroke)
{
keybindings.unbindKeyStroke(stroke);
}
protected Screen screen()
@@ -1,4 +1,4 @@
package mightypork.rogue.gui.screens;
package mightypork.rogue.gui;
import java.util.HashMap;
@@ -6,11 +6,12 @@ import java.util.HashMap;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.ScreenRequestEvent;
import mightypork.utils.logging.Log;
public class ScreenRegistry extends Subsystem implements ScreenRequestEvent.Listener {
private HashMap<String, Screen> screens = new HashMap<String, Screen>();
private final HashMap<String, Screen> screens = new HashMap<String, Screen>();
private Screen active = null;
@@ -19,9 +20,9 @@ public class ScreenRegistry extends Subsystem implements ScreenRequestEvent.List
}
public void add(String key, Screen screen)
public void add(Screen screen)
{
screens.put(key, screen);
screens.put(screen.getId(), screen);
addChildClient(screen);
}
@@ -29,6 +30,8 @@ public class ScreenRegistry extends Subsystem implements ScreenRequestEvent.List
@Override
public void showScreen(String key)
{
Log.f3("Request to show screen \"" + key + "\"");
Screen toshow = screens.get(key);
if (toshow == null) throw new RuntimeException("Screen " + key + " not defined.");
@@ -0,0 +1,45 @@
package mightypork.rogue.gui.constraints;
import static mightypork.utils.math.constraints.ConstraintFactory.*;
import mightypork.rogue.AppAccess;
import mightypork.utils.math.constraints.ConstraintContext;
public class ColumnHolder extends ElementHolder {
private final int cols;
private int col = 0;
public ColumnHolder(AppAccess app, ConstraintContext context, int rows) {
super(app, context);
this.cols = rows;
}
public ColumnHolder(AppAccess app, int rows) {
super(app);
this.cols = rows;
}
/**
* Add a row to the holder.
*
* @param elem
*/
public void addRow(RenderableWithContext elem)
{
if (elem == null) return;
add(elem, c_column(null, cols, col++));
}
@Override
public void remove(RenderableWithContext elem)
{
throw new UnsupportedOperationException("Can't remove from ColumnHolder.");
}
}
@@ -19,7 +19,7 @@ import mightypork.utils.math.coord.Rect;
*/
public class ElementHolder extends ChildClient implements ConstraintContext, RenderableWithContext {
private LinkedList<RenderableWithContext> elements = new LinkedList<RenderableWithContext>();
private final LinkedList<RenderableWithContext> elements = new LinkedList<RenderableWithContext>();
private ConstraintContext context;
@@ -57,19 +57,18 @@ public class ElementHolder extends ChildClient implements ConstraintContext, Ren
}
/**
* Add element to the holder.
*
* @param elem
*/
public void add(RenderableWithContext elem)
{
if (elem == null) return;
elem.setContext(this);
elements.add(elem);
addChildClient(elem);
}
// /**
// * Add element to the holder.
// *
// * @param elem
// */
// public void add(RenderableWithContext elem)
// {
// if (elem == null) return;
// elem.setContext(this);
// elements.add(elem);
// addChildClient(elem);
// }
/**
* Add element to the holder.
@@ -0,0 +1,45 @@
package mightypork.rogue.gui.constraints;
import static mightypork.utils.math.constraints.ConstraintFactory.*;
import mightypork.rogue.AppAccess;
import mightypork.utils.math.constraints.ConstraintContext;
public class RowHolder extends ElementHolder {
private final int rows;
private int row = 0;
public RowHolder(AppAccess app, ConstraintContext context, int rows) {
super(app, context);
this.rows = rows;
}
public RowHolder(AppAccess app, int rows) {
super(app);
this.rows = rows;
}
/**
* Add a row to the holder.
*
* @param elem
*/
public void addRow(RenderableWithContext elem)
{
if (elem == null) return;
add(elem, c_row(null, rows, row++));
}
@Override
public void remove(RenderableWithContext elem)
{
throw new UnsupportedOperationException("Can't remove from RowHolder.");
}
}
@@ -1,70 +0,0 @@
package mightypork.rogue.gui.screens.screenBouncy;
import mightypork.rogue.AppAccess;
import mightypork.rogue.gui.screens.LayeredScreen;
import mightypork.rogue.input.KeyStroke;
import org.lwjgl.input.Keyboard;
public class ScreenTestAnim extends LayeredScreen {
private LayerBouncyBoxes layer;
public ScreenTestAnim(AppAccess app) {
super(app);
layer = new LayerBouncyBoxes(this);
addLayer(layer);
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
@Override
public void run()
{
layer.goRight();
}
});
bindKeyStroke(new KeyStroke(Keyboard.KEY_LEFT), new Runnable() {
@Override
public void run()
{
layer.goLeft();
}
});
}
@Override
protected void deinitScreen()
{
// no impl
}
@Override
protected void onScreenEnter()
{
// no impl
}
@Override
protected void onScreenLeave()
{
// no impl
}
@Override
protected void updateScreen(double delta)
{
// no impl
}
}
@@ -1,4 +1,4 @@
package mightypork.rogue.gui.screens.screenBouncy;
package mightypork.rogue.gui.screens.test_bouncyboxes;
import static mightypork.utils.math.constraints.ConstraintFactory.*;
@@ -1,4 +1,4 @@
package mightypork.rogue.gui.screens.screenBouncy;
package mightypork.rogue.gui.screens.test_bouncyboxes;
import static mightypork.utils.math.constraints.ConstraintFactory.*;
@@ -6,29 +6,29 @@ import static mightypork.utils.math.constraints.ConstraintFactory.*;
import java.util.ArrayList;
import java.util.List;
import mightypork.rogue.gui.constraints.ElementHolder;
import mightypork.rogue.gui.screens.Screen;
import mightypork.rogue.gui.screens.ScreenLayer;
import mightypork.rogue.gui.Screen;
import mightypork.rogue.gui.ScreenLayer;
import mightypork.rogue.gui.constraints.RowHolder;
import mightypork.utils.math.constraints.RectConstraint;
public class LayerBouncyBoxes extends ScreenLayer {
List<BouncyBox> boxes = new ArrayList<BouncyBox>();
private ElementHolder layout;
private RowHolder layout;
public LayerBouncyBoxes(Screen screen) {
super(screen);
// shrink screen rect by 8% on all sides
RectConstraint holder_rect = c_shrink(this, c_percent(c_height(this), c_n(8)));
layout = new ElementHolder(screen, holder_rect);
addChildClient(layout);
addChildClient(layout = new RowHolder(screen, holder_rect, 16));
for (int i = 0; i < 32; i++) {
for (int i = 0; i < 16; i++) {
BouncyBox bbr = new BouncyBox();
layout.add(bbr, c_row(null, 32, i));
layout.addRow(bbr);
boxes.add(bbr);
}
@@ -42,13 +42,6 @@ public class LayerBouncyBoxes extends ScreenLayer {
}
@Override
public void update(double delta)
{
// no impl
}
public void goLeft()
{
for (BouncyBox bbr : boxes) {
@@ -0,0 +1,80 @@
package mightypork.rogue.gui.screens.test_bouncyboxes;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.events.ScreenRequestEvent;
import mightypork.rogue.gui.LayeredScreen;
import mightypork.rogue.input.KeyStroke;
import org.lwjgl.input.Keyboard;
public class ScreenTestBouncy extends LayeredScreen {
private LayerBouncyBoxes layer;
public ScreenTestBouncy(AppAccess app) {
super(app);
layer = new LayerBouncyBoxes(this);
addLayer(layer);
bindKeyStroke(new KeyStroke(true, Keyboard.KEY_RIGHT), new Runnable() {
@Override
public void run()
{
layer.goRight();
}
});
bindKeyStroke(new KeyStroke(true, Keyboard.KEY_LEFT), new Runnable() {
@Override
public void run()
{
layer.goLeft();
}
});
bindKeyStroke(new KeyStroke(Keyboard.KEY_C), new Runnable() {
@Override
public void run()
{
bus().queue(new ScreenRequestEvent("test.cat"));
}
});
}
@Override
protected void deinitScreen()
{
// no impl
}
@Override
protected void onScreenEnter()
{
// no impl
}
@Override
protected void onScreenLeave()
{
// no impl
}
@Override
public String getId()
{
return "test.bouncy";
}
}
@@ -1,27 +1,27 @@
package mightypork.rogue.gui.screens.screenTextures;
package mightypork.rogue.gui.screens.test_cat_sound;
import static mightypork.utils.math.constraints.ConstraintFactory.*;
import java.util.Random;
import mightypork.rogue.AppAccess;
import mightypork.rogue.Res;
import mightypork.rogue.bus.events.ActionRequest;
import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.bus.events.RequestType;
import mightypork.rogue.gui.screens.Screen;
import mightypork.rogue.gui.Screen;
import mightypork.rogue.gui.ScreenLayer;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.render.Render;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.animation.AnimDouble;
import mightypork.utils.math.animation.Easing;
import mightypork.utils.math.constraints.RectConstraint;
import mightypork.utils.math.coord.Coord;
import org.lwjgl.input.Keyboard;
import org.newdawn.slick.opengl.Texture;
public class ScreenTextureTest extends Screen implements MouseButtonEvent.Listener {
public class LayerFlyingCat extends ScreenLayer implements Updateable, MouseButtonEvent.Listener {
private RectConstraint kittenbox;
@@ -31,53 +31,28 @@ public class ScreenTextureTest extends Screen implements MouseButtonEvent.Listen
private Random rand = new Random();
private Texture cat_tx = Res.getTexture("test.kitten");
public ScreenTextureTest(AppAccess app) {
super(app);
public LayerFlyingCat(Screen screen) {
super(screen);
kittenbox = c_move(c_box_sized(this, c_n(s), c_n(s)), c_n(x), c_n(y));
bindKeyStroke(new KeyStroke(Keyboard.KEY_ESCAPE), new Runnable() {
bindKeyStroke(new KeyStroke(Keyboard.KEY_RETURN), new Runnable() {
@Override
public void run()
{
snd().fadeOutAllLoops();
bus().schedule(new ActionRequest(RequestType.SHUTDOWN), 3);
x.fadeTo(disp().getWidth() / 2 - s.getTo() / 2, 2);
y.fadeTo(disp().getHeight() / 2 - s.getTo() / 2, 2);
}
});
}
@Override
protected void deinitScreen()
{
}
@Override
protected void onScreenEnter()
{
System.out.println("YOLO");
Res.getLoop("test.wilderness").fadeIn();
}
@Override
protected void onScreenLeave()
{
}
@Override
protected void renderScreen()
{
Render.quadTextured(kittenbox.getRect(), Res.getTexture("test.kitten"));
}
@Override
protected void updateScreen(double delta)
public void update(double delta)
{
s.update(delta);
x.update(delta);
@@ -101,4 +76,11 @@ public class ScreenTextureTest extends Screen implements MouseButtonEvent.Listen
y.fadeTo(pos.y - newSize / 2D, t);
}
@Override
public void render()
{
Render.quadTextured(kittenbox.getRect(), cat_tx);
}
}
@@ -0,0 +1,73 @@
package mightypork.rogue.gui.screens.test_cat_sound;
import mightypork.rogue.AppAccess;
import mightypork.rogue.Res;
import mightypork.rogue.bus.events.ActionRequest;
import mightypork.rogue.bus.events.ActionRequest.RequestType;
import mightypork.rogue.bus.events.ScreenRequestEvent;
import mightypork.rogue.gui.LayeredScreen;
import mightypork.rogue.input.KeyStroke;
import org.lwjgl.input.Keyboard;
public class ScreenTestCat extends LayeredScreen {
LayerFlyingCat layer;
public ScreenTestCat(AppAccess app) {
super(app);
addLayer(layer = new LayerFlyingCat(this));
bindKeyStroke(new KeyStroke(Keyboard.KEY_ESCAPE), new Runnable() {
@Override
public void run()
{
snd().fadeOutAllLoops();
bus().schedule(new ActionRequest(RequestType.SHUTDOWN), 3);
}
});
bindKeyStroke(new KeyStroke(Keyboard.KEY_B), new Runnable() {
@Override
public void run()
{
bus().queue(new ScreenRequestEvent("test.bouncy"));
}
});
}
@Override
protected void deinitScreen()
{
}
@Override
protected void onScreenEnter()
{
snd().fadeOutAllLoops();
Res.getLoop("test.wilderness").fadeIn();
}
@Override
protected void onScreenLeave()
{
Res.getLoop("test.wilderness").fadeOut();
}
@Override
public String getId()
{
return "test.cat";
}
}
+15 -2
View File
@@ -4,10 +4,10 @@ package mightypork.rogue.input;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.ActionRequest;
import mightypork.rogue.bus.events.ActionRequest.RequestType;
import mightypork.rogue.bus.events.KeyboardEvent;
import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.bus.events.MouseMotionEvent;
import mightypork.rogue.bus.events.RequestType;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.coord.Coord;
@@ -20,7 +20,7 @@ import org.lwjgl.opengl.Display;
public class InputSystem extends Subsystem implements Updateable, KeyBinder {
// listeners
private KeyBindingPool keybindings;
private final KeyBindingPool keybindings;
private boolean yAxisDown = true;
@@ -127,6 +127,7 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
int key = Keyboard.getEventKey();
boolean down = Keyboard.getEventKeyState();
char c = Keyboard.getEventCharacter();
bus().queue(new KeyboardEvent(key, c, down));
}
@@ -137,4 +138,16 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
c.setY_ip(disp().getSize().y - c.y);
}
}
/**
* Set whether Y axis should go top-down instead of LWJGL default bottom-up.<br>
* Default = true.
*
* @param yAxisDown
*/
public void setYDown(boolean yAxisDown)
{
this.yAxisDown = yAxisDown;
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ import mightypork.rogue.bus.events.KeyboardEvent;
public class KeyBinding implements KeyboardEvent.Listener {
private KeyStroke keystroke;
private final KeyStroke keystroke;
private Runnable handler;
private boolean wasActive = false;
@@ -16,7 +16,7 @@ import mightypork.utils.logging.Log;
*/
public class KeyBindingPool implements KeyBinder, KeyboardEvent.Listener {
private Set<KeyBinding> bindings = new HashSet<KeyBinding>();
private final Set<KeyBinding> bindings = new HashSet<KeyBinding>();
/**
+10 -15
View File
@@ -10,18 +10,18 @@ import org.lwjgl.input.Keyboard;
public class KeyStroke {
private Set<Integer> keys = new LinkedHashSet<Integer>();
private boolean down = true;
private final Set<Integer> keys = new LinkedHashSet<Integer>();
private final boolean fallingEdge;
/**
* KeyStroke
*
* @param down true for falling edge, up for rising edge
* @param fallingEdge true for falling edge, up for rising edge
* @param keys keys that must be pressed
*/
public KeyStroke(boolean down, int... keys) {
this.down = down;
public KeyStroke(boolean fallingEdge, int... keys) {
this.fallingEdge = fallingEdge;
for (int k : keys) {
this.keys.add(k);
}
@@ -29,11 +29,12 @@ public class KeyStroke {
/**
* Falling edge keystroke
* Rising edge keystroke
*
* @param keys
*/
public KeyStroke(int... keys) {
fallingEdge = false;
for (int k : keys) {
this.keys.add(k);
}
@@ -47,13 +48,7 @@ public class KeyStroke {
st &= Keyboard.isKeyDown(k);
}
return down ? st : !st;
}
public void setKeys(Set<Integer> keys)
{
this.keys = keys;
return fallingEdge ? st : !st;
}
@@ -81,7 +76,7 @@ public class KeyStroke {
return false;
}
if (down != other.down) return false;
if (fallingEdge != other.fallingEdge) return false;
return true;
}
@@ -99,7 +94,7 @@ public class KeyStroke {
s += Keyboard.getKeyName(i.next());
}
s += down ? ",DOWN" : "UP";
s += fallingEdge ? ",DOWN" : ",UP";
s += ")";
+13 -1
View File
@@ -140,7 +140,19 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
*/
public Coord getSize()
{
return new Coord(Display.getWidth(), Display.getHeight());
return new Coord(getWidth(), getHeight());
}
public int getWidth()
{
return Display.getWidth();
}
public int getHeight()
{
return Display.getHeight();
}
+6 -4
View File
@@ -5,7 +5,7 @@ import static org.lwjgl.opengl.GL11.*;
import java.io.IOException;
import mightypork.rogue.render.textures.TxQuad;
import mightypork.rogue.texture.TxQuad;
import mightypork.utils.files.FileUtils;
import mightypork.utils.logging.Log;
import mightypork.utils.math.color.RGB;
@@ -110,14 +110,16 @@ public class Render {
* @param resourcePath
* @return the loaded texture
*/
public static Texture loadTexture(String resourcePath)
public synchronized static Texture loadTexture(String resourcePath)
{
if (!inited) {
inited = true;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
inited = true;
}
try {
@@ -187,7 +189,7 @@ public class Render {
{
double left = quad.xMin();
double bottom = quad.yMin();
double right = quad.yMax();
double right = quad.xMax();
double top = quad.yMax();
// draw with color
@@ -1,4 +1,4 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound;
import mightypork.rogue.Deferred;
@@ -90,14 +90,14 @@ public class DeferredAudio implements Destroyable, Deferred {
* @return resource is loaded
*/
@Override
public boolean isLoaded()
public synchronized boolean isLoaded()
{
return audio != null;
}
@Override
public void load()
public synchronized void load()
{
ensureLoaded();
}
@@ -108,7 +108,7 @@ public class DeferredAudio implements Destroyable, Deferred {
*
* @return is loaded
*/
protected boolean ensureLoaded()
protected synchronized boolean ensureLoaded()
{
if (isLoaded()) return true; // already loaded
if (loadFailed || resourcePath == null) return false;
@@ -295,4 +295,11 @@ public class DeferredAudio implements Destroyable, Deferred {
return true;
}
@Override
public String toString()
{
return "Audio(\"" + resourcePath + "\")";
}
}
@@ -1,4 +1,4 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound;
import mightypork.utils.math.Calc;
@@ -12,7 +12,7 @@ import mightypork.utils.objects.Mutable;
*/
public class JointVolume extends Mutable<Double> {
private Mutable<Double>[] volumes;
private final Mutable<Double>[] volumes;
/**
@@ -1,4 +1,4 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound;
public class NullAudio extends DeferredAudio {
@@ -1,4 +1,4 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound;
import java.util.HashMap;
@@ -6,6 +6,8 @@ import java.util.Map;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppAdapter;
import mightypork.rogue.sound.players.EffectPlayer;
import mightypork.rogue.sound.players.LoopPlayer;
import mightypork.utils.logging.Log;
@@ -15,8 +17,8 @@ public class SoundBank extends AppAdapter {
private static final LoopPlayer NULL_LOOP = new LoopPlayer(NO_SOUND, 0, 0, null);
private static final EffectPlayer NULL_EFFECT = new EffectPlayer(NO_SOUND, 0, 0, null);
private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
private final Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
private final Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
public SoundBank(AppAccess app) {
@@ -1,4 +1,4 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound;
import java.nio.FloatBuffer;
@@ -7,6 +7,9 @@ import java.util.Set;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.ResourceLoadRequest;
import mightypork.rogue.sound.players.EffectPlayer;
import mightypork.rogue.sound.players.LoopPlayer;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.math.Calc.Buffers;
import mightypork.utils.math.coord.Coord;
@@ -69,12 +72,12 @@ public class SoundSystem extends Subsystem implements Updateable {
// -- instance --
public Mutable<Double> masterVolume = new Mutable<Double>(1D);
public Mutable<Double> effectsVolume = new JointVolume(masterVolume);
public Mutable<Double> loopsVolume = new JointVolume(masterVolume);
public final Mutable<Double> masterVolume = new Mutable<Double>(1D);
public final Mutable<Double> effectsVolume = new JointVolume(masterVolume);
public final Mutable<Double> loopsVolume = new JointVolume(masterVolume);
private Set<LoopPlayer> loopPlayers = new HashSet<LoopPlayer>();
private Set<DeferredAudio> resources = new HashSet<DeferredAudio>();
private final Set<LoopPlayer> loopPlayers = new HashSet<LoopPlayer>();
private final Set<DeferredAudio> resources = new HashSet<DeferredAudio>();
public SoundSystem(AppAccess app) {
@@ -146,6 +149,8 @@ public class SoundSystem extends Subsystem implements Updateable {
private DeferredAudio getResource(String res)
{
DeferredAudio a = new DeferredAudio(res);
bus().queue(new ResourceLoadRequest(a));
if (resources.contains(a)) throw new IllegalArgumentException("Sound resource " + res + " is already registered.");
resources.add(a);
return a;
@@ -1,22 +1,24 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound.players;
import mightypork.rogue.sound.DeferredAudio;
import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.objects.Mutable;
public abstract class BaseAudioPlayer {
public abstract class BaseAudioPlayer implements Destroyable {
/** the track */
private DeferredAudio audio;
private final DeferredAudio audio;
/** base gain for sfx */
private double baseGain = 1;
private final double baseGain;
/** base pitch for sfx */
private double basePitch = 1;
private final double basePitch;
/** dedicated volume control */
private Mutable<Double> gainMultiplier = null;
private final Mutable<Double> gainMultiplier;
public BaseAudioPlayer(DeferredAudio track, double baseGain, Mutable<Double> gainMultiplier) {
@@ -36,10 +38,10 @@ public abstract class BaseAudioPlayer {
}
@Override
public void destroy()
{
audio.destroy();
audio = null;
}
@@ -1,6 +1,7 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound.players;
import mightypork.rogue.sound.DeferredAudio;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.objects.Mutable;
@@ -1,6 +1,7 @@
package mightypork.rogue.audio;
package mightypork.rogue.sound.players;
import mightypork.rogue.sound.DeferredAudio;
import mightypork.utils.control.interf.Updateable;
import mightypork.utils.control.timing.Pauseable;
import mightypork.utils.math.animation.AnimDouble;
@@ -14,7 +15,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
private int sourceID = -1;
/** animator for fade in and fade out */
private AnimDouble fadeAnim = new AnimDouble(0);
private final AnimDouble fadeAnim = new AnimDouble(0);
private double lastUpdateGain = 0;
@@ -0,0 +1,102 @@
package mightypork.rogue.texture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import mightypork.rogue.AppAccess;
import mightypork.rogue.Deferred;
import mightypork.rogue.bus.events.MainLoopTaskRequest;
import mightypork.rogue.bus.events.ResourceLoadRequest;
import mightypork.utils.control.interf.Destroyable;
import mightypork.utils.logging.Log;
/**
* Asynchronous resource loading thread.
*
* @author MightyPork
*/
public class DeferredLoader extends Thread implements ResourceLoadRequest.Listener, Destroyable {
public static void launch(AppAccess app)
{
(new DeferredLoader(app)).start();
}
private ExecutorService exs = Executors.newCachedThreadPool();
private LinkedBlockingQueue<Deferred> toLoad = new LinkedBlockingQueue<Deferred>();
private boolean stopped;
private AppAccess app;
public DeferredLoader(AppAccess app) {
super("Deferred loader");
this.app = app;
}
@Override
public void loadResource(Deferred resource)
{
toLoad.add(resource);
}
@Override
public void run()
{
while (!stopped) {
try {
final Deferred def = toLoad.take();
if (def == null) continue;
if (!def.isLoaded()) {
// texture needs to be loaded in main thread, unfortunately.
// -> delegate to MainLoop
if (def instanceof DeferredTexture) {
app.bus().queue(new MainLoopTaskRequest(new Runnable() {
@Override
public void run()
{
Log.f3("<DEFERRED> Loading \"" + Log.str(def) + "\"");
def.load();
}
}));
continue;
}
Log.f3("<DEFERRED> Loading \"" + Log.str(def) + "\"");
exs.submit(new Runnable() {
@Override
public void run()
{
def.load();
}
});
}
} catch (InterruptedException ignored) {
//
}
}
}
@Override
public void destroy()
{
stopped = true;
exs.shutdownNow();
}
}
@@ -1,4 +1,4 @@
package mightypork.rogue.render.textures;
package mightypork.rogue.texture;
import mightypork.rogue.Deferred;
@@ -8,13 +8,13 @@ import mightypork.utils.math.coord.Rect;
import org.newdawn.slick.opengl.Texture;
public class MultiTexture implements Texture, Deferred {
public class DeferredTexture implements Texture, Deferred {
private Texture backingTexture;
private String resourcePath;
private final String resourcePath;
public MultiTexture(String resourcePath) {
public DeferredTexture(String resourcePath) {
this.resourcePath = resourcePath;
}
@@ -26,7 +26,7 @@ public class MultiTexture implements Texture, Deferred {
@Override
public void load()
public synchronized void load()
{
if (!isLoaded()) {
backingTexture = Render.loadTexture(resourcePath);
@@ -144,4 +144,11 @@ public class MultiTexture implements Texture, Deferred {
backingTexture.setTextureFilter(textureFilter);
}
@Override
public String toString()
{
return "Texture(\"" + resourcePath + "\")";
}
}
@@ -1,10 +1,11 @@
package mightypork.rogue.render.textures;
package mightypork.rogue.texture;
import java.util.HashMap;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppAdapter;
import mightypork.rogue.bus.events.ResourceLoadRequest;
import mightypork.utils.math.coord.Rect;
import org.newdawn.slick.opengl.Texture;
@@ -21,11 +22,11 @@ public class TextureBank extends AppAdapter {
super(app);
}
private HashMap<String, MultiTexture> textures = new HashMap<String, MultiTexture>();
private final HashMap<String, DeferredTexture> textures = new HashMap<String, DeferredTexture>();
private HashMap<String, TxQuad> quads = new HashMap<String, TxQuad>();
private final HashMap<String, TxQuad> quads = new HashMap<String, TxQuad>();
private MultiTexture lastTx;
private DeferredTexture lastTx;
/**
@@ -36,7 +37,9 @@ public class TextureBank extends AppAdapter {
*/
public void loadTexture(String key, String resourcePath)
{
MultiTexture tx = new MultiTexture(resourcePath);
DeferredTexture tx = new DeferredTexture(resourcePath);
bus().queue(new ResourceLoadRequest(tx));
textures.put(key, tx);
lastTx = tx;
}
@@ -51,7 +54,7 @@ public class TextureBank extends AppAdapter {
*/
public void makeQuad(String quadKey, String textureKey, Rect quad)
{
MultiTexture tx = textures.get(textureKey);
DeferredTexture tx = textures.get(textureKey);
if (tx == null) throw new RuntimeException("Texture with key " + textureKey + " not defined!");
TxQuad txquad = tx.getQuad(quad);
@@ -68,7 +71,7 @@ public class TextureBank extends AppAdapter {
*/
public void makeQuad(String quadKey, Rect quad)
{
MultiTexture tx = lastTx;
DeferredTexture tx = lastTx;
if (tx == null) throw new RuntimeException("There's no texture loaded yet, can't define quads!");
TxQuad txquad = tx.getQuad(quad);
@@ -1,4 +1,4 @@
package mightypork.rogue.render.textures;
package mightypork.rogue.texture;
import mightypork.utils.math.coord.Rect;
@@ -14,9 +14,9 @@ import org.newdawn.slick.opengl.Texture;
public class TxQuad {
/** The texture */
public Texture tx;
public final Texture tx;
/** Coords in texture (0-1) */
public Rect uvs;
public final Rect uvs;
/**
+34 -8
View File
@@ -16,17 +16,30 @@ import mightypork.utils.logging.Log;
*/
final public class EventBus implements Destroyable {
/** Message channels */
private BufferedHashSet<EventChannel<?, ?>> channels = new BufferedHashSet<EventChannel<?, ?>>();
private BufferedHashSet<Object> clients = new BufferedHashSet<Object>();
private DelayQueue<DelayedMessage> sendQueue = new DelayQueue<DelayedMessage>();
private BusThread busThread;
/** Registered clients */
private BufferedHashSet<Object> clients = new BufferedHashSet<Object>();
/** Messages queued for delivery */
private DelayQueue<DelayedMessage> sendQueue = new DelayQueue<DelayedMessage>();
/** Queue polling thread */
private QueuePollingThread busThread;
/** Log all */
private boolean logging = false;
/** Whether the bus was destroyed */
private boolean dead = false;
/**
* Make a new bus and start it's queue thread.
*/
public EventBus() {
busThread = new BusThread();
busThread = new QueuePollingThread();
busThread.start();
}
@@ -153,12 +166,18 @@ final public class EventBus implements Destroyable {
if (logging) Log.f3("<bus> - [ Sending: " + Log.str(message) + " ]");
boolean sent = false;
boolean channelAccepted = false;
for (EventChannel<?, ?> b : channels) {
if (b.canBroadcast(message)) channelAccepted = true;
sent |= b.broadcast(message, clients);
}
if (!sent) Log.w("<bus> Not accepted by any channel: " + Log.str(message));
// more severe
if (!channelAccepted) Log.w("<bus> Not accepted by any channel: " + Log.str(message));
// less severe
if (logging && !sent) Log.w("<bus> Not delivered to any client: " + Log.str(message));
channels.setBuffering(false);
clients.setBuffering(false);
@@ -248,16 +267,23 @@ final public class EventBus implements Destroyable {
}
private class BusThread extends Thread {
private class QueuePollingThread extends Thread {
public boolean stopped;
public boolean stopped = false;
public QueuePollingThread() {
super("Queue Polling Thread");
}
@Override
public void run()
{
DelayedMessage dm;
while (!stopped) {
DelayedMessage dm = null;
dm = null;
try {
dm = sendQueue.take();
@@ -55,7 +55,7 @@ final public class EventChannel<EVENT extends Event<CLIENT>, CLIENT> {
*
* @param message a message to be sent
* @param clients collection of clients
* @return true if message was accepted by this channel
* @return true if message was sent
*/
public boolean broadcast(Event<?> message, Collection<Object> clients)
{
@@ -63,9 +63,7 @@ final public class EventChannel<EVENT extends Event<CLIENT>, CLIENT> {
EVENT evt = messageClass.cast(message);
doBroadcast(evt, clients, new HashSet<Object>());
return true;
return doBroadcast(evt, clients, new HashSet<Object>());
}
@@ -75,14 +73,20 @@ final public class EventChannel<EVENT extends Event<CLIENT>, CLIENT> {
* @param message sent message
* @param clients subscribing clients
* @param processed clients already processed
* @return success
*/
private void doBroadcast(final EVENT message, final Collection<Object> clients, final Collection<Object> processed)
private boolean doBroadcast(final EVENT message, final Collection<Object> clients, final Collection<Object> processed)
{
boolean sent = false;
for (Object client : clients) {
// exclude obvious non-clients
if (!isClientValid(client)) {
continue;
}
// avoid executing more times
if (processed.contains(client)) {
Log.w("<bus> Client already served: " + Log.str(client));
continue;
@@ -97,17 +101,28 @@ final public class EventChannel<EVENT extends Event<CLIENT>, CLIENT> {
}
}
sendTo(client, message);
sent |= sendTo(client, message);
// singular event ain't no whore, handled once only.
if (sent && message instanceof SingularEvent) return true;
// pass on to delegated clients
if (client instanceof DelegatingClient) {
if (((DelegatingClient) client).doesDelegate()) {
Collection<Object> children = ((DelegatingClient) client).getChildClients();
if (children != null && children.size() > 0) doBroadcast(message, children, processed);
if (children != null && children.size() > 0) {
sent |= doBroadcast(message, children, processed);
}
} else {
if (logging) Log.f3("<bus> Client not delegating: " + Log.str(client));
}
}
}
return sent;
}
@@ -116,14 +131,17 @@ final public class EventChannel<EVENT extends Event<CLIENT>, CLIENT> {
*
* @param client target client
* @param message message to send
* @return success
*/
@SuppressWarnings("unchecked")
private void sendTo(Object client, EVENT message)
private boolean sendTo(Object client, EVENT message)
{
if (isClientOfType(client)) {
if (logging) Log.f3("<bus> Delivered " + Log.str(message) + " to " + Log.str(client));
((Event<CLIENT>) message).handleBy((CLIENT) client);
return true;
}
return false;
}
@@ -0,0 +1,11 @@
package mightypork.utils.control.bus;
/**
* Event handled by only single client.
*
* @author MightyPork
*/
public interface SingularEvent {
}
@@ -5,6 +5,11 @@ import mightypork.utils.control.bus.Event;
import mightypork.utils.control.interf.Destroyable;
/**
* Invoke destroy() method of all subscribers. Used to deinit a system.
*
* @author MightyPork
*/
public class DestroyEvent implements Event<Destroyable> {
@Override
@@ -95,7 +95,6 @@ public class TimerFps {
*/
public void startNewFrame()
{
// System.out.println("! start new frame !");
long time = getTime();
lastFrame = time;
nextFrame = time + FRAME;
+17 -11
View File
@@ -18,7 +18,7 @@ public class Log {
*/
public static void f1(String msg)
{
if (esl && main != null) main.f1(msg);
if (esl && ready()) main.f1(msg);
}
@@ -29,7 +29,7 @@ public class Log {
*/
public static void f2(String msg)
{
if (esl && main != null) main.f2(msg);
if (esl && ready()) main.f2(msg);
}
@@ -40,7 +40,7 @@ public class Log {
*/
public static void f3(String msg)
{
if (esl && main != null) main.f3(msg);
if (esl && ready()) main.f3(msg);
}
@@ -51,7 +51,7 @@ public class Log {
*/
public static void i(String msg)
{
if (esl && main != null) main.i(msg);
if (esl && ready()) main.i(msg);
}
@@ -62,7 +62,7 @@ public class Log {
*/
public static void w(String msg)
{
if (esl && main != null) main.w(msg);
if (esl && ready()) main.w(msg);
}
@@ -73,7 +73,7 @@ public class Log {
*/
public static void e(String msg)
{
if (esl && main != null) main.e(msg);
if (esl && ready()) main.e(msg);
}
@@ -85,7 +85,7 @@ public class Log {
*/
public static void e(String msg, Throwable thrown)
{
if (esl && main != null) main.e(msg, thrown);
if (esl && ready()) main.e(msg, thrown);
}
@@ -96,13 +96,13 @@ public class Log {
*/
public static void e(Throwable thrown)
{
if (esl && main != null) main.e(thrown);
if (esl && ready()) main.e(thrown);
}
public static void enable(boolean flag)
{
if (esl && main != null) main.enable(flag);
if (esl && ready()) main.enable(flag);
}
@@ -163,7 +163,7 @@ public class Log {
public int addMonitor(LogMonitor mon)
{
if (main == null) throw new IllegalStateException("Main logger not initialized.");
if (!ready()) throw new IllegalStateException("Main logger not initialized.");
return main.addMonitor(mon);
}
@@ -171,7 +171,7 @@ public class Log {
public void removeMonitor(int id)
{
if (main == null) throw new IllegalStateException("Main logger not initialized.");
if (!ready()) throw new IllegalStateException("Main logger not initialized.");
main.removeMonitor(id);
}
@@ -207,4 +207,10 @@ public class Log {
return (enclosing == null ? "" : enclosing.getSimpleName() + ".") + cls.getSimpleName();
}
public static boolean ready()
{
return main != null;
}
}
@@ -245,7 +245,7 @@ public class ConstraintFactory {
double height = getContext().getRect().getSize().y;
double perRow = height / rows;
return Rect.fromSize(getOrigin().add(0, perRow * (rows - index - 1)), getSize().setY(perRow));
return Rect.fromSize(getOrigin().add(0, perRow * index), getSize().setY(perRow));
}
};
}
+4 -4
View File
@@ -239,7 +239,7 @@ public class Rect {
*/
public Coord getCenterBottom()
{
return new Coord((max.x + min.x) / 2, min.y);
return new Coord((max.x + min.x) / 2D, min.y);
}
@@ -250,7 +250,7 @@ public class Rect {
*/
public Coord getCenterLeft()
{
return new Coord(min.x, (max.y + min.y) / 2);
return new Coord(min.x, (max.y + min.y) / 2D);
}
@@ -261,7 +261,7 @@ public class Rect {
*/
public Coord getCenterRight()
{
return new Coord(max.x, (max.y + min.y) / 2);
return new Coord(max.x, (max.y + min.y) / 2D);
}
@@ -272,7 +272,7 @@ public class Rect {
*/
public Coord getCenterTop()
{
return new Coord((max.x + min.x) / 2, max.y);
return new Coord((max.x + min.x) / 2D, max.y);
}