Improved concurrency, annotations

This commit is contained in:
Ondřej Hruška
2014-04-06 23:11:34 +02:00
parent e2b6752efb
commit 6b69dabbb9
31 changed files with 382 additions and 314 deletions
+12 -8
View File
@@ -5,6 +5,7 @@ import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.logging.Level;
import javax.swing.JOptionPane;
@@ -18,9 +19,8 @@ import mightypork.rogue.input.InputSystem;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.render.DisplaySystem;
import mightypork.rogue.sound.SoundSystem;
import mightypork.rogue.util.SlickLogRedirector;
import mightypork.utils.control.bus.EventBus;
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;
@@ -105,8 +105,10 @@ public class App implements AppAccess {
{
Log.i("Shutting down subsystems...");
bus().send(new DestroyEvent());
bus().destroy();
if(bus() != null) {
bus().send(new DestroyEvent());
bus().destroy();
}
Log.i("Terminating...");
System.exit(0);
@@ -124,8 +126,11 @@ public class App implements AppAccess {
* Setup logging
*/
final LogInstance log = Log.create("runtime", Paths.LOGS, 10);
log.setFileLevel(Level.WARNING);
log.setSysoutLevel(Level.ALL);
log.enable(Config.LOGGING_ENABLED);
log.enableSysout(Config.LOG_TO_STDOUT);
org.newdawn.slick.util.Log.setLogSystem(new SlickLogRedirector(log));
Log.f1("Initializing subsystems...");
@@ -134,7 +139,6 @@ public class App implements AppAccess {
*/
Log.f2("Initializing Event Bus...");
eventBus = new EventBus();
eventBus.enableLogging(Config.LOG_BUS);
initChannels();
/*
@@ -236,7 +240,7 @@ public class App implements AppAccess {
@Override
public void run()
{
bus().queue(new ActionRequest(RequestType.FULLSCREEN));
bus().send(new ActionRequest(RequestType.FULLSCREEN));
}
});
@@ -246,7 +250,7 @@ public class App implements AppAccess {
@Override
public void run()
{
bus().queue(new ActionRequest(RequestType.SCREENSHOT));
bus().send(new ActionRequest(RequestType.SCREENSHOT));
}
});
@@ -256,7 +260,7 @@ public class App implements AppAccess {
@Override
public void run()
{
bus().queue(new ActionRequest(RequestType.SHUTDOWN));
bus().send(new ActionRequest(RequestType.SHUTDOWN));
}
});
}
-2
View File
@@ -76,6 +76,4 @@ public class Config {
public static boolean LOG_TO_STDOUT = true;
public static boolean SINGLE_INSTANCE = true;
public static boolean LOG_BUS = false;
}
+9 -9
View File
@@ -8,11 +8,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import mightypork.rogue.bus.Subsystem;
import mightypork.rogue.bus.events.ActionRequest;
import mightypork.rogue.bus.events.UpdateEvent;
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;
@@ -37,18 +37,18 @@ public class MainLoop extends Subsystem implements ActionRequest.Listener, MainL
{
timer = new TimerDelta();
while (running) {
while (running) {
Runnable r;
while ((r = taskQueue.poll()) != null) {
r.run();
}
disp().beginFrame();
bus().send(new UpdateEvent(timer.getDelta()));
for (final Runnable r : regularTasks) {
r.run();
}
Runnable r;
while ((r = taskQueue.poll()) != null) {
r.run();
for (final Runnable r2 : regularTasks) {
r2.run();
}
disp().endFrame();
@@ -1,8 +1,9 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.control.bus.events.types.SingularEvent;
/**
@@ -11,6 +12,7 @@ import mightypork.utils.control.bus.SingularEvent;
* @author MightyPork
*/
@SingularEvent
@QueuedEvent
public class ActionRequest implements Event<ActionRequest.Listener> {
private final RequestType type;
@@ -0,0 +1,23 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.ImmediateEvent;
import mightypork.utils.control.interf.Destroyable;
/**
* Invoke destroy() method of all subscribers. Used to deinit a system.
*
* @author MightyPork
*/
@ImmediateEvent
public class DestroyEvent implements Event<Destroyable> {
@Override
public void handleBy(Destroyable handler)
{
handler.destroy();
}
}
@@ -1,7 +1,8 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import org.lwjgl.input.Keyboard;
@@ -11,6 +12,7 @@ import org.lwjgl.input.Keyboard;
*
* @author MightyPork
*/
@QueuedEvent
public class KeyboardEvent implements Event<KeyboardEvent.Listener> {
private final int key;
@@ -1,8 +1,9 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.control.bus.events.types.SingularEvent;
/**
@@ -11,6 +12,7 @@ import mightypork.utils.control.bus.SingularEvent;
* @author MightyPork
*/
@SingularEvent
@QueuedEvent
public class MainLoopTaskRequest implements Event<MainLoopTaskRequest.Listener> {
private final Runnable task;
@@ -1,7 +1,8 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.math.coord.Coord;
@@ -10,6 +11,7 @@ import mightypork.utils.math.coord.Coord;
*
* @author MightyPork
*/
@QueuedEvent
public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
public static final int BUTTON_LEFT = 0;
@@ -1,7 +1,8 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.math.coord.Coord;
@@ -10,6 +11,7 @@ import mightypork.utils.math.coord.Coord;
*
* @author MightyPork
*/
@QueuedEvent
public class MouseMotionEvent implements Event<MouseMotionEvent.Listener> {
private final Coord move;
@@ -2,8 +2,9 @@ package mightypork.rogue.bus.events;
import mightypork.rogue.loading.DeferredResource;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.control.bus.events.types.SingularEvent;
/**
@@ -12,6 +13,7 @@ import mightypork.utils.control.bus.SingularEvent;
* @author MightyPork
*/
@SingularEvent
@QueuedEvent
public class ResourceLoadRequest implements Event<ResourceLoadRequest.Listener> {
private final DeferredResource resource;
@@ -1,10 +1,17 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.math.coord.Coord;
/**
* Screen resolution or mode was changed
*
* @author MightyPork
*/
@QueuedEvent
public class ScreenChangeEvent implements Event<ScreenChangeEvent.Listener> {
private final boolean fullscreen;
@@ -1,8 +1,9 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.Event;
import mightypork.utils.control.bus.SingularEvent;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.QueuedEvent;
import mightypork.utils.control.bus.events.types.SingularEvent;
/**
@@ -11,6 +12,7 @@ import mightypork.utils.control.bus.SingularEvent;
* @author MightyPork
*/
@SingularEvent
@QueuedEvent
public class ScreenRequestEvent implements Event<ScreenRequestEvent.Listener> {
private final String scrName;
@@ -0,0 +1,34 @@
package mightypork.rogue.bus.events;
import mightypork.utils.control.bus.events.Event;
import mightypork.utils.control.bus.events.types.ImmediateEvent;
import mightypork.utils.control.interf.Updateable;
/**
* Delta timing update event
*
* @author MightyPork
*/
// sending via queue would hog the bus
@ImmediateEvent
public class UpdateEvent implements Event<Updateable> {
private final double deltaTime;
/**
* @param deltaTime time since last update (sec)
*/
public UpdateEvent(double deltaTime) {
this.deltaTime = deltaTime;
}
@Override
public void handleBy(Updateable handler)
{
handler.update(deltaTime);
}
}
+1 -1
View File
@@ -36,7 +36,7 @@ public class FontBank extends AppAdapter {
*/
public void loadFont(String key, DeferredFont font)
{
bus().queue(new ResourceLoadRequest(font));
bus().send(new ResourceLoadRequest(font));
fonts.put(key, font);
}
@@ -44,7 +44,7 @@ public class ScreenTestBouncy extends LayeredScreen {
@Override
public void run()
{
bus().queue(new ScreenRequestEvent("test.cat"));
bus().send(new ScreenRequestEvent("test.cat"));
}
});
}
@@ -28,7 +28,7 @@ public class ScreenTestCat extends LayeredScreen {
public void run()
{
snd().fadeOutAllLoops();
bus().schedule(new ActionRequest(RequestType.SHUTDOWN), 3);
bus().sendDelayed(new ActionRequest(RequestType.SHUTDOWN), 3);
}
});
@@ -37,7 +37,7 @@ public class ScreenTestCat extends LayeredScreen {
@Override
public void run()
{
bus().queue(new ScreenRequestEvent("test.bouncy"));
bus().send(new ScreenRequestEvent("test.bouncy"));
}
});
}
+4 -4
View File
@@ -92,14 +92,14 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
wasMouse = true;
}
if (wasMouse && !moveSum.isZero()) bus().queue(new MouseMotionEvent(lastPos, moveSum));
if (wasMouse && !moveSum.isZero()) bus().send(new MouseMotionEvent(lastPos, moveSum));
while (Keyboard.next()) {
onKeyEvent();
}
if (Display.isCloseRequested()) {
bus().queue(new ActionRequest(RequestType.SHUTDOWN));
bus().send(new ActionRequest(RequestType.SHUTDOWN));
}
}
@@ -118,7 +118,7 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
}
if (button != -1 || wheeld != 0) {
bus().queue(new MouseButtonEvent(pos, button, down, wheeld));
bus().send(new MouseButtonEvent(pos, button, down, wheeld));
}
moveSum.add_ip(move);
@@ -132,7 +132,7 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
final boolean down = Keyboard.getEventKeyState();
final char c = Keyboard.getEventCharacter();
bus().queue(new KeyboardEvent(key, c, down));
bus().send(new KeyboardEvent(key, c, down));
}
@@ -63,7 +63,10 @@ public class AsyncResourceLoader extends Thread implements ResourceLoadRequest.L
// textures & fonts needs to be loaded in main thread
if (def.getClass().isAnnotationPresent(MustLoadInMainThread.class)) {
app.bus().queue(new MainLoopTaskRequest(new Runnable() {
Log.f3("<LOADER> Loading in main thread:\n "+Log.str(def));
app.bus().send(new MainLoopTaskRequest(new Runnable() {
@Override
public void run()
@@ -75,6 +78,8 @@ public class AsyncResourceLoader extends Thread implements ResourceLoadRequest.L
continue;
}
Log.f3("<LOADER> Loading async:\n "+Log.str(def));
exs.submit(new Runnable() {
@Override
@@ -27,28 +27,28 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya
@Override
public synchronized final void load()
{
if (loadAttempted) return;
loadAttempted = true;
loadFailed = false;
if (isNull()) return;
try {
if (resource == null) throw new NullPointerException("Resource string cannot be null for non-null resource.");
Log.f3("<res> Loading: " + this);
Log.f3("<RES> Loading: " + this);
loadResource(resource);
Log.f3("<res> Loaded: " + this + " loaded.");
Log.f3("<RES> Loaded: " + this + " loaded.");
} catch (final Exception e) {
loadFailed = true;
Log.e("Failed to load resource \"" + resource + "\"", e);
Log.e("<RES> Failed to load \"" + resource + "\"", e);
}
loadAttempted = true;
}
@Override
public synchronized final boolean isLoaded()
public final boolean isLoaded()
{
if (isNull()) return false;
@@ -68,6 +68,7 @@ public abstract class BaseDeferredResource implements DeferredResource, Destroya
if (isLoaded()) {
return true;
} else {
Log.w("<RES> First use, not loaded yet - loading directly\n"+this);
load();
}
@@ -86,7 +86,7 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
Display.update();
}
bus().queue(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
bus().send(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
} catch (final Throwable t) {
Log.e("Failed to toggle fullscreen mode.", t);
@@ -166,7 +166,7 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
{
// handle resize
if (Display.wasResized()) {
bus().queue(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
bus().send(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
}
glLoadIdentity();
@@ -225,7 +225,7 @@ public class DeferredAudio extends BaseDeferredResource {
@Override
public void destroy()
{
if (!isLoaded()) return;
if (!isLoaded() || backingAudio == null) return;
backingAudio.release();
backingAudio = null;
+1 -1
View File
@@ -149,7 +149,7 @@ public class SoundSystem extends Subsystem implements Updateable {
private DeferredAudio getResource(String res)
{
final DeferredAudio a = new DeferredAudio(res);
bus().queue(new ResourceLoadRequest(a));
bus().send(new ResourceLoadRequest(a));
if (resources.contains(a)) throw new IllegalArgumentException("Sound resource " + res + " is already registered.");
resources.add(a);
@@ -58,7 +58,7 @@ public class TextureBank extends AppAdapter {
tx.setFilter(filter_min, filter_mag);
tx.setWrap(wrap);
bus().queue(new ResourceLoadRequest(tx));
bus().send(new ResourceLoadRequest(tx));
textures.put(key, tx);
lastTx = tx;