Refactoring of subsystems and eventbus

This commit is contained in:
Ondřej Hruška
2014-04-01 00:55:43 +02:00
parent 6013a105ad
commit 4a1a84fd87
38 changed files with 801 additions and 512 deletions
+16 -14
View File
@@ -7,10 +7,10 @@ import java.nio.channels.FileLock;
import javax.swing.JOptionPane;
import mightypork.rogue.bus.events.UpdateEvent;
import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.display.Screen;
import mightypork.rogue.display.ScreenTestAnimations;
import mightypork.rogue.display.events.UpdateEvent;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.sounds.SoundSystem;
@@ -25,6 +25,11 @@ import mightypork.utils.time.TimerDelta;
import org.lwjgl.input.Keyboard;
/**
* Main class
*
* @author MightyPork
*/
public class App implements Destroyable, AppAccess {
/** instance pointer */
@@ -61,7 +66,7 @@ public class App implements Destroyable, AppAccess {
/**
* Show crash report dialog with error stack trace.
* Handle a crash
*
* @param error
*/
@@ -69,15 +74,12 @@ public class App implements Destroyable, AppAccess {
{
Log.e("The game has crashed.", error);
if (inst != null) inst.exit();
if (inst != null) inst.shutdown();
}
/**
* Quit to OS<br>
* Destroy app & exit VM
*/
public void exit()
@Override
public void shutdown()
{
destroy();
System.exit(0);
@@ -121,7 +123,7 @@ public class App implements Destroyable, AppAccess {
);
//@formatter:on
exit();
shutdown();
return;
}
}
@@ -165,7 +167,7 @@ public class App implements Destroyable, AppAccess {
private void initBus()
{
events = new MessageBus();
events.addSubscriber(this);
events.subscribe(this);
events.createChannel(UpdateEvent.class, UpdateEvent.Listener.class);
}
@@ -214,7 +216,7 @@ public class App implements Destroyable, AppAccess {
public void run()
{
Log.f3("CTRL+Q, shutting down.");
exit();
shutdown();
}
});
}
@@ -246,7 +248,7 @@ public class App implements Destroyable, AppAccess {
{
initialize();
mainLoop();
exit();
shutdown();
}
/** timer */
@@ -293,7 +295,7 @@ public class App implements Destroyable, AppAccess {
* @return sound system of the running instance
*/
@Override
public SoundSystem soundsys()
public SoundSystem snd()
{
return sounds;
}
@@ -323,7 +325,7 @@ public class App implements Destroyable, AppAccess {
* @return event bus
*/
@Override
public MessageBus msgbus()
public MessageBus bus()
{
return events;
}
+9 -2
View File
@@ -17,7 +17,7 @@ public interface AppAccess {
/**
* @return sound system
*/
abstract SoundSystem soundsys();
abstract SoundSystem snd();
/**
@@ -35,6 +35,13 @@ public interface AppAccess {
/**
* @return event bus
*/
abstract MessageBus msgbus();
abstract MessageBus bus();
/**
* Quit to OS<br>
* Destroy app & exit VM
*/
abstract void shutdown();
}
+61
View File
@@ -0,0 +1,61 @@
package mightypork.rogue;
import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem;
import mightypork.utils.patterns.subscription.MessageBus;
/**
* App access adapter
*
* @author MightyPork
*/
public class AppAdapter implements AppAccess {
private AppAccess app;
public AppAdapter(AppAccess app) {
if (app == null) throw new NullPointerException("AppAccess instance cannot be null.");
this.app = app;
}
@Override
public final SoundSystem snd()
{
return app.snd();
}
@Override
public final InputSystem input()
{
return app.input();
}
@Override
public final DisplaySystem disp()
{
return app.disp();
}
@Override
public final MessageBus bus()
{
return app.bus();
}
@Override
public void shutdown()
{
app.shutdown();
}
}
-209
View File
@@ -1,209 +0,0 @@
package mightypork.rogue;
import java.util.HashSet;
import java.util.Set;
import mightypork.rogue.display.DisplaySystem;
import mightypork.rogue.display.events.UpdateEvent;
import mightypork.rogue.input.InputSystem;
import mightypork.rogue.sounds.SoundSystem;
import mightypork.utils.logging.Log;
import mightypork.utils.patterns.Destroyable;
import mightypork.utils.patterns.subscription.MessageBus;
import mightypork.utils.time.Updateable;
public abstract class AppSubsystem implements AppAccess, UpdateEvent.Listener, Updateable, Destroyable {
private AppAccess app;
private boolean wantUpdates;
private boolean destroyed = false;
/** Subsystem children subscribing to MessageBus */
private Set<Object> childSubscribers = new HashSet<Object>();
/**
* Create a subsystem
*
* @param app app instance access
* @param joinBus whether to initially join msgbus
*/
public AppSubsystem(AppAccess app, boolean joinBus) {
this.app = app;
// add to subscriber group
childSubscribers.add(this);
enableEvents(joinBus);
enableUpdates(true);
init();
}
/**
* Set whether events should be received.<br>
* This includes {@link UpdateEvent}, so disabling events also disables
* updates.
*
* @param enable
*/
protected final void enableEvents(boolean enable)
{
assertLive();
// this & child subscribers
for (Object o : childSubscribers) {
if (enable) {
app.msgbus().addSubscriber(o);
} else {
app.msgbus().removeSubscriber(o);
}
}
}
/**
* Set whether to receive {@link UpdateEvent}s (delta timing, one each
* frame).<br>
*
* @param enable
*/
protected final void enableUpdates(boolean enable)
{
assertLive();
wantUpdates = enable;
}
@Override
public final void receive(UpdateEvent event)
{
assertLive();
if (wantUpdates) update(event.getDeltaTime());
}
// /**
// * @return app instance
// */
// protected AppAccess app()
// {
// assertLive();
//
// return app;
// }
@Override
public void update(double delta)
{
Log.w("Subsystem " + getClass().getSimpleName() + " receives updates, but does not override the update() method.");
}
/**
* Initialize the subsystem<br>
* (called during construction)
*/
protected abstract void init();
/**
* Deinitialize the subsystem<br>
* (called during destruction)<br>
* <br>
* All child eventbus subscribers will be removed from the eventbus.
*/
protected abstract void deinit();
/**
* Add a child subscriber to the {@link MessageBus}.<br>
* Child subscribers are removed when subsystem is destroyed, and can be
* connected/disconnected using the <code>enableEvents()</code> method.
*
* @param client
* @return true on success
*/
public final boolean addChildSubscriber(Object client)
{
assertLive();
if (client == null) return false;
msgbus().addSubscriber(client);
childSubscribers.add(client);
return true;
}
public final void removeChildSubscriber(Object client)
{
assertLive();
childSubscribers.remove(client);
msgbus().removeSubscriber(client);
}
@Override
public final void destroy()
{
assertLive();
deinit();
enableEvents(false); // remove all subscribers from bus
app = null;
destroyed = true;
}
@Override
public MessageBus msgbus()
{
assertLive();
return app.msgbus();
}
@Override
public SoundSystem soundsys()
{
assertLive();
return app.soundsys();
}
@Override
public InputSystem input()
{
assertLive();
return app.input();
}
@Override
public DisplaySystem disp()
{
assertLive();
return app.disp();
}
private void assertLive()
{
if (destroyed) throw new IllegalStateException("Subsystem already destroyed.");
}
}
@@ -0,0 +1,162 @@
package mightypork.rogue.bus;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppAdapter;
import mightypork.rogue.bus.events.UpdateEvent;
import mightypork.utils.logging.Log;
import mightypork.utils.patterns.Destroyable;
import mightypork.utils.patterns.subscription.MessageBus;
import mightypork.utils.patterns.subscription.clients.DelegatingClient;
import mightypork.utils.patterns.subscription.clients.ToggleableClient;
import mightypork.utils.time.Updateable;
/**
* App event bus client, to be used for subsystems, screens and anything that
* needs access to the eventbus
*
* @author MightyPork
*/
public abstract class DelegatingBusClient extends AppAdapter implements DelegatingClient, ToggleableClient, Destroyable, Updateable, UpdateEvent.Listener {
/** Subsystem children subscribing to MessageBus */
private Set<Object> childSubscribers = new HashSet<Object>();
private boolean wantUpdates = true;
private boolean eventsEnabled = true;
public DelegatingBusClient(AppAccess app, boolean updates) {
super(app);
bus().subscribe(this);
enableUpdates(updates);
init();
}
/**
* Add a child subscriber to the {@link MessageBus}.<br>
*
* @param client
* @return true on success
*/
public final boolean addChildSubscriber(Object client)
{
if (client == null) return false;
childSubscribers.add(client);
return true;
}
/**
* Remove a child subscriber
*
* @param client subscriber to remove
*/
public final void removeChildSubscriber(Object client)
{
if (client == null) return;
childSubscribers.remove(client);
}
@Override
public final Collection<Object> getChildClients()
{
return childSubscribers;
}
@Override
public final boolean doesDelegate()
{
return doesSubscribe();
}
/**
* Set whether to receive {@link UpdateEvent}s (delta timing, one each
* frame).<br>
*
* @param enable
*/
public final void enableUpdates(boolean enable)
{
wantUpdates = enable;
}
@Override
public final boolean doesSubscribe()
{
return eventsEnabled;
}
/**
* Set whether events should be received.
*
* @param enable
*/
public final void enableEvents(boolean enable)
{
this.eventsEnabled = enable;
}
@Override
public final void receive(UpdateEvent event)
{
if (wantUpdates) update(event.getDeltaTime());
}
@Override
public final void destroy()
{
deinit();
enableUpdates(false);
bus().unsubscribe(this);
}
@Override
public void update(double delta)
{
Log.w("Client " + getClass().getSimpleName() + " receives updates, but does not override the update() method.");
}
/**
* Initialize the subsystem<br>
* (called during construction)
*/
protected void init()
{
// no impl
}
/**
* Deinitialize the subsystem<br>
* (called during destruction)
*/
protected void deinit()
{
// no impl
}
}
@@ -0,0 +1,23 @@
package mightypork.rogue.bus;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppAdapter;
/**
* Simplest event bus client with app access
*
* @author MightyPork
*/
public class SimpleBusClient extends AppAdapter {
/**
* @param app app access
*/
public SimpleBusClient(AppAccess app) {
super(app);
bus().subscribe(this);
}
}
@@ -0,0 +1,26 @@
package mightypork.rogue.bus;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.events.UpdateEvent;
import mightypork.utils.time.Updateable;
public abstract class UpdateReceiver extends SimpleBusClient implements UpdateEvent.Listener, Updateable {
public UpdateReceiver(AppAccess app) {
super(app);
}
@Override
public void receive(UpdateEvent event)
{
update(event.getDeltaTime());
}
@Override
public abstract void update(double delta);
}
@@ -1,4 +1,4 @@
package mightypork.rogue.input.events;
package mightypork.rogue.bus.events;
import mightypork.utils.patterns.subscription.Handleable;
@@ -1,4 +1,4 @@
package mightypork.rogue.input.events;
package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord;
@@ -1,4 +1,4 @@
package mightypork.rogue.input.events;
package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord;
@@ -1,4 +1,4 @@
package mightypork.rogue.display.events;
package mightypork.rogue.bus.events;
import mightypork.utils.math.coord.Coord;
@@ -1,4 +1,4 @@
package mightypork.rogue.display.events;
package mightypork.rogue.bus.events;
import mightypork.utils.patterns.subscription.Handleable;
@@ -7,9 +7,9 @@ import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.display.constraints.ConstraintContext;
import mightypork.rogue.display.events.ScreenChangeEvent;
import mightypork.rogue.bus.DelegatingBusClient;
import mightypork.rogue.bus.events.ScreenChangeEvent;
import mightypork.rogue.display.constraints.Bounding;
import mightypork.utils.logging.Log;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect;
@@ -20,7 +20,7 @@ import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class DisplaySystem extends AppSubsystem implements ConstraintContext {
public class DisplaySystem extends DelegatingBusClient implements Bounding {
private DisplayMode windowDisplayMode;
private int targetFps;
@@ -51,7 +51,7 @@ public class DisplaySystem extends AppSubsystem implements ConstraintContext {
*/
private void initChannels()
{
msgbus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
bus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
}
@@ -101,7 +101,7 @@ public class DisplaySystem extends AppSubsystem implements ConstraintContext {
Display.update();
}
msgbus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
bus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
} catch (Throwable t) {
Log.e("Failed to toggle fullscreen mode.", t);
@@ -178,7 +178,7 @@ public class DisplaySystem extends AppSubsystem implements ConstraintContext {
public void beginFrame()
{
if (Display.wasResized()) {
msgbus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
bus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
}
glLoadIdentity();
+8 -5
View File
@@ -3,9 +3,9 @@ package mightypork.rogue.display;
import static org.lwjgl.opengl.GL11.*;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.display.constraints.ConstraintContext;
import mightypork.rogue.display.events.ScreenChangeEvent;
import mightypork.rogue.bus.DelegatingBusClient;
import mightypork.rogue.bus.events.ScreenChangeEvent;
import mightypork.rogue.display.constraints.Bounding;
import mightypork.rogue.input.KeyBinder;
import mightypork.rogue.input.KeyBindingPool;
import mightypork.rogue.input.KeyStroke;
@@ -20,7 +20,7 @@ import mightypork.utils.math.coord.Rect;
*
* @author MightyPork
*/
public abstract class Screen extends AppSubsystem implements KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
public abstract class Screen extends DelegatingBusClient implements KeyBinder, Bounding, ScreenChangeEvent.Listener {
private KeyBindingPool keybindings;
@@ -28,7 +28,10 @@ public abstract class Screen extends AppSubsystem implements KeyBinder, Constrai
public Screen(AppAccess app) {
super(app, false);
super(app, true);
// disable events initially
enableEvents(false);
}
@@ -4,8 +4,8 @@ package mightypork.rogue.display;
import java.util.Random;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.input.events.MouseButtonEvent;
import mightypork.rogue.util.RenderUtils;
import mightypork.utils.math.Polar;
import mightypork.utils.math.color.RGB;
@@ -5,11 +5,11 @@ import mightypork.utils.math.coord.Rect;
/**
* Constraints can be based on this
* Bounding box provider - context for {@link Constraint}
*
* @author MightyPork
*/
public interface ConstraintContext {
public interface Bounding {
/**
* @return bounding rectangle
@@ -2,39 +2,58 @@ package mightypork.rogue.display.constraints;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect;
public abstract class Constraint implements ConstraintContext {
public abstract class Constraint implements Bounding {
protected ConstraintContext context;
protected Bounding context;
public Constraint(ConstraintContext context) {
public Constraint(Bounding context) {
this.context = context;
}
public void setContext(ConstraintContext context)
/**
* Assign a context
*
* @param context
*/
public void setContext(Bounding context)
{
this.context = context;
}
public ConstraintContext getContext()
/**
* @return context
*/
public Bounding getContext()
{
return context;
}
/**
* @return context rect origin
*/
protected Coord origin()
{
return context.getRect().getOrigin();
}
/**
* @return context rect size
*/
protected Coord size()
{
return context.getRect().getSize();
}
@Override
public abstract Rect getRect();
}
@@ -0,0 +1,8 @@
package mightypork.rogue.display.rendering;
public interface Renderable {
public void render();
}
@@ -0,0 +1,18 @@
package mightypork.rogue.display.rendering;
import mightypork.rogue.AppAccess;
import mightypork.rogue.bus.DelegatingBusClient;
public abstract class ScreenLayer extends DelegatingBusClient implements Renderable {
public ScreenLayer(AppAccess app) {
super(app, true);
}
@Override
public abstract void render();
}
+31 -31
View File
@@ -2,10 +2,10 @@ package mightypork.rogue.input;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.input.events.KeyboardEvent;
import mightypork.rogue.input.events.MouseButtonEvent;
import mightypork.rogue.input.events.MouseMotionEvent;
import mightypork.rogue.bus.DelegatingBusClient;
import mightypork.rogue.bus.events.KeyboardEvent;
import mightypork.rogue.bus.events.MouseButtonEvent;
import mightypork.rogue.bus.events.MouseMotionEvent;
import mightypork.utils.math.coord.Coord;
import org.lwjgl.LWJGLException;
@@ -14,7 +14,7 @@ import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
public class InputSystem extends AppSubsystem implements KeyBinder {
public class InputSystem extends DelegatingBusClient implements KeyBinder {
// listeners
private KeyBindingPool keybindings;
@@ -60,9 +60,9 @@ public class InputSystem extends AppSubsystem implements KeyBinder {
private void initChannels()
{
msgbus().createChannel(KeyboardEvent.class, KeyboardEvent.Listener.class);
msgbus().createChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
msgbus().createChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
bus().createChannel(KeyboardEvent.class, KeyboardEvent.Listener.class);
bus().createChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
bus().createChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
}
@@ -80,32 +80,10 @@ public class InputSystem extends AppSubsystem implements KeyBinder {
}
private void onMouseEvent()
{
int button = Mouse.getEventButton();
boolean down = Mouse.getEventButtonState();
Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY());
Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
int wheeld = Mouse.getEventDWheel();
if (button != -1 || wheeld != 0) msgbus().broadcast(new MouseButtonEvent(pos, button, down, wheeld));
if (!move.isZero()) msgbus().broadcast(new MouseMotionEvent(pos, move));
}
private void onKeyEvent()
{
int key = Keyboard.getEventKey();
boolean down = Keyboard.getEventKeyState();
char c = Keyboard.getEventCharacter();
msgbus().broadcast(new KeyboardEvent(key, c, down));
}
@Override
public void update(double delta)
{
Display.processMessages(); // redundant if Display.update() is called in main loop
Display.processMessages();
while (Mouse.next()) {
onMouseEvent();
@@ -115,4 +93,26 @@ public class InputSystem extends AppSubsystem implements KeyBinder {
onKeyEvent();
}
}
private void onMouseEvent()
{
int button = Mouse.getEventButton();
boolean down = Mouse.getEventButtonState();
Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY());
Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
int wheeld = Mouse.getEventDWheel();
if (button != -1 || wheeld != 0) bus().broadcast(new MouseButtonEvent(pos, button, down, wheeld));
if (!move.isZero()) bus().broadcast(new MouseMotionEvent(pos, move));
}
private void onKeyEvent()
{
int key = Keyboard.getEventKey();
boolean down = Keyboard.getEventKeyState();
char c = Keyboard.getEventCharacter();
bus().broadcast(new KeyboardEvent(key, c, down));
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
package mightypork.rogue.input;
import mightypork.rogue.input.events.KeyboardEvent;
import mightypork.rogue.bus.events.KeyboardEvent;
public class KeyBinding implements KeyboardEvent.Listener {
@@ -5,7 +5,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import mightypork.rogue.input.events.KeyboardEvent;
import mightypork.rogue.bus.events.KeyboardEvent;
import mightypork.utils.logging.Log;
+2 -2
View File
@@ -8,7 +8,7 @@ import java.util.Map;
import java.util.Set;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.bus.DelegatingBusClient;
import mightypork.utils.logging.Log;
import mightypork.utils.math.Calc.Buffers;
import mightypork.utils.math.coord.Coord;
@@ -25,7 +25,7 @@ import org.newdawn.slick.openal.SoundStore;
* @author MightyPork
*/
@SuppressWarnings("unchecked")
public class SoundSystem extends AppSubsystem {
public class SoundSystem extends DelegatingBusClient {
private static final Coord INITIAL_LISTENER_POS = new Coord(0, 0, 0);
private static final int MAX_SOURCES = 256;
@@ -1,8 +1,8 @@
package mightypork.rogue.testing;
import mightypork.rogue.display.constraints.Bounding;
import mightypork.rogue.display.constraints.Constraint;
import mightypork.rogue.display.constraints.ConstraintContext;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.math.coord.Rect;
@@ -11,7 +11,7 @@ public class TestConstraints {
public static void main(String[] args)
{
ConstraintContext context = new ConstraintContext() {
Bounding context = new Bounding() {
@Override
public Rect getRect()
@@ -25,7 +25,7 @@ public class TestConstraints {
private double height;
public Navbar(ConstraintContext context, double height) {
public Navbar(Bounding context, double height) {
super(context);
this.height = height;
}
@@ -44,7 +44,7 @@ public class TestConstraints {
private int tile;
public TileHorizontal(ConstraintContext context, int tileCount, int aTile) {
public TileHorizontal(Bounding context, int tileCount, int aTile) {
super(context);
this.count = tileCount;
setTile(aTile);
@@ -0,0 +1,219 @@
package mightypork.rogue.testing;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import mightypork.utils.logging.Log;
import mightypork.utils.patterns.subscription.Handleable;
import mightypork.utils.patterns.subscription.MessageBus;
import mightypork.utils.patterns.subscription.clients.DelegatingClient;
import mightypork.utils.patterns.subscription.clients.ToggleableClient;
public class TestMsgbus {
public static void main(String[] args)
{
Log.create("runtime", new File("."), 0);
MessageBus bus = new MessageBus();
bus.createChannel(StringMessage.class, StringMessage.Listener.class);
bus.createChannel(IntMessage.class, IntMessage.Listener.class);
Delegator deleg1 = new Delegator("Deleg1");
Delegator deleg2 = new Delegator("Deleg2");
Toggleable togg1 = new Toggleable("Tog1");
Toggleable togg2 = new Toggleable("Tog2");
Toggleable plain1 = new Toggleable("Plain1");
Toggleable plain2 = new Toggleable("Plain2");
Toggleable plain3 = new Toggleable("Plain3");
PlainInt pint = new PlainInt("Ints");
PlainBoth pboth = new PlainBoth("Both");
bus.subscribe(deleg1);
deleg1.clients.add(togg1);
deleg1.clients.add(plain2);
deleg1.clients.add(deleg2);
deleg1.clients.add(pint);
deleg2.clients.add(deleg1);
deleg2.clients.add(togg1);
deleg2.clients.add(plain3);
deleg2.clients.add(pboth);
bus.subscribe(plain1);
bus.subscribe(togg2);
bus.broadcast(new StringMessage("<MSG>"));
bus.broadcast(new IntMessage(7));
bus.broadcast(new IntMessage(13));
deleg2.delegating = false;
bus.broadcast(new IntMessage(44));
deleg2.delegating = true;
bus.broadcast(new IntMessage(45));
}
}
class Delegator extends Plain implements DelegatingClient {
List<Object> clients = new ArrayList<Object>();
boolean delegating = true;
public Delegator(String name) {
super(name);
}
@Override
public Collection<Object> getChildClients()
{
return clients;
}
@Override
public boolean doesDelegate()
{
return delegating;
}
}
class Toggleable extends Plain implements ToggleableClient {
boolean subscribing = true;
public Toggleable(String name) {
super(name);
}
@Override
public boolean doesSubscribe()
{
return subscribing;
}
}
class Plain implements StringMessage.Listener {
String name;
public Plain(String name) {
this.name = name;
}
@Override
public void receive(StringMessage message)
{
System.out.println(name + " (STR) RECV: " + message.s);
}
}
class PlainInt implements IntMessage.Listener {
String name;
public PlainInt(String name) {
this.name = name;
}
@Override
public void receive(IntMessage message)
{
System.out.println(name + " (INT) RECV: " + message.i);
}
}
class PlainBoth implements IntMessage.Listener, StringMessage.Listener {
String name;
public PlainBoth(String name) {
this.name = name;
}
@Override
public void receive(IntMessage message)
{
System.out.println(name + " (both-INT) RECV: " + message.i);
}
@Override
public void receive(StringMessage message)
{
System.out.println(name + " (both-STR) RECV: " + message.s);
}
}
class StringMessage implements Handleable<StringMessage.Listener> {
String s;
StringMessage(String str) {
this.s = str;
}
public interface Listener {
public void receive(StringMessage message);
}
@Override
public void handleBy(Listener handler)
{
handler.receive(this);
}
}
class IntMessage implements Handleable<IntMessage.Listener> {
int i;
IntMessage(int i) {
this.i = i;
}
public interface Listener {
public void receive(IntMessage message);
}
@Override
public void handleBy(Listener handler)
{
handler.receive(this);
}
}
+3 -102
View File
@@ -6,6 +6,8 @@ import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.opengl.Texture;
// TODO rewrite to use hashmap with keys
/**
* Texture loading class
*
@@ -13,62 +15,15 @@ import org.newdawn.slick.opengl.Texture;
*/
public class Textures {
protected static Texture buttons_menu;
protected static Texture buttons_small;
// patterns need raw access (are repeated)
public static Texture steel_small_dk;
public static Texture steel_small_lt;
public static Texture steel_big_dk;
public static Texture steel_big_lt;
public static Texture steel_big_scratched;
public static Texture steel_brushed;
public static Texture steel_rivet_belts;
public static Texture water;
// particles need direct access
public static Texture snow;
public static Texture leaves;
public static Texture rain;
public static Texture circle;
protected static Texture logo;
protected static Texture widgets;
public static Texture program;
protected static Texture icons;
public static Texture map_tiles;
public static Texture map_shading;
// spotted
public static Texture turtle_blue;
public static Texture turtle_green;
public static Texture turtle_purple;
public static Texture turtle_yellow;
// misc
public static Texture turtle_red;
public static Texture turtle_brown_dk;
public static Texture turtle_brown_lt;
public static Texture turtle_brown_orn;
// a shadow sheet
public static Texture turtle_shadows;
public static Texture food;
public static Texture food_shadows;
private static final String GUI = "res/images/gui/";
private static final String PATTERNS = "res/images/patterns/";
private static final String PROGRAM = "res/images/program/";
private static final String TILES = "res/images/tiles/";
private static final String SPRITES = "res/images/sprites/";
private static final String PARTICLES = "res/images/particles/";
/**
* Load what's needed for splash
*/
public static void loadForSplash()
public static void load()
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -76,63 +31,9 @@ public class Textures {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
logo = TextureManager.load(GUI + "logo.png");
steel_small_dk = TextureManager.load(PATTERNS + "steel.png");
Tx.initForSplash();
}
/**
* Load textures
*/
public static void load()
{
// gui
buttons_menu = TextureManager.load(GUI + "buttons_menu.png");
buttons_small = TextureManager.load(GUI + "buttons_small.png");
widgets = TextureManager.load(GUI + "widgets.png");
icons = TextureManager.load(GUI + "icons.png");
// patterns
steel_small_lt = TextureManager.load(PATTERNS + "steel_light.png"); // XXX Unused texture
steel_big_dk = TextureManager.load(PATTERNS + "steel_big.png");
steel_big_lt = TextureManager.load(PATTERNS + "steel_big_light.png");
steel_big_scratched = TextureManager.load(PATTERNS + "steel_big_scratched.png");
steel_brushed = TextureManager.load(PATTERNS + "steel_brushed.png");
steel_rivet_belts = TextureManager.load(PATTERNS + "rivet_belts.png");
water = TextureManager.load(PATTERNS + "water.png");
// particles
snow = TextureManager.load(PARTICLES + "snow.png");
leaves = TextureManager.load(PARTICLES + "leaves.png");
rain = TextureManager.load(PARTICLES + "rain.png");
circle = TextureManager.load(PARTICLES + "circle.png");
// program tiles
program = TextureManager.load(PROGRAM + "program.png");
// map tiles
map_tiles = TextureManager.load(TILES + "tiles.png");
map_shading = TextureManager.load(TILES + "shading.png");
// turtle
turtle_blue = TextureManager.load(SPRITES + "HD-blue.png");
turtle_yellow = TextureManager.load(SPRITES + "HD-yellow.png");
turtle_green = TextureManager.load(SPRITES + "HD-green.png");
turtle_purple = TextureManager.load(SPRITES + "HD-purple.png");
turtle_red = TextureManager.load(SPRITES + "HD-red.png");
turtle_brown_dk = TextureManager.load(SPRITES + "HD-brown-dk.png");
turtle_brown_lt = TextureManager.load(SPRITES + "HD-brown-lt.png");
turtle_brown_orn = TextureManager.load(SPRITES + "HD-brown-ornamental.png");
turtle_shadows = TextureManager.load(SPRITES + "HD-shadow.png");
food = TextureManager.load(SPRITES + "food.png");
food_shadows = TextureManager.load(SPRITES + "food-shadow.png");
glDisable(GL_TEXTURE_2D);
Tx.init();
}
+2
View File
@@ -1,6 +1,8 @@
package mightypork.rogue.textures;
// TODO rewrite
/**
* List of texture quads for GUIs
*