Refactored subsystems for cleaner modularity.

This commit is contained in:
Ondřej Hruška
2014-03-30 23:09:20 +02:00
parent e2e5576664
commit 6013a105ad
20 changed files with 590 additions and 296 deletions
+25 -22
View File
@@ -6,12 +6,13 @@ import static org.lwjgl.opengl.GL11.*;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import mightypork.rogue.App;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.display.constraints.ConstraintContext;
import mightypork.rogue.display.events.ScreenChangeEvent;
import mightypork.utils.logging.Log;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.patterns.Destroyable;
import mightypork.utils.patterns.Initializable;
import mightypork.utils.math.coord.Rect;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
@@ -19,27 +20,29 @@ import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class DisplaySystem implements Initializable, Destroyable {
private boolean initialized;
public class DisplaySystem extends AppSubsystem implements ConstraintContext {
private DisplayMode windowDisplayMode;
private int targetFps;
public DisplaySystem() {
initialize();
public DisplaySystem(AppAccess app) {
super(app, true);
enableUpdates(false);
}
@Override
public void initialize()
protected void init()
{
if (initialized) return;
initChannels();
}
initialized = true;
@Override
public void deinit()
{
Display.destroy();
}
@@ -48,14 +51,7 @@ public class DisplaySystem implements Initializable, Destroyable {
*/
private void initChannels()
{
App.msgbus().registerMessageType(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
}
@Override
public void destroy()
{
Display.destroy();
msgbus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
}
@@ -105,7 +101,7 @@ public class DisplaySystem implements Initializable, Destroyable {
Display.update();
}
App.broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
msgbus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
} catch (Throwable t) {
Log.e("Failed to toggle fullscreen mode.", t);
@@ -182,7 +178,7 @@ public class DisplaySystem implements Initializable, Destroyable {
public void beginFrame()
{
if (Display.wasResized()) {
App.broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
msgbus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
}
glLoadIdentity();
@@ -198,4 +194,11 @@ public class DisplaySystem implements Initializable, Destroyable {
Display.update(false); // don't poll input devices
Display.sync(targetFps);
}
@Override
public Rect getRect()
{
return new Rect(getSize());
}
}
+73 -46
View File
@@ -2,17 +2,15 @@ package mightypork.rogue.display;
import static org.lwjgl.opengl.GL11.*;
import mightypork.rogue.App;
import mightypork.rogue.AppAccess;
import mightypork.rogue.AppSubsystem;
import mightypork.rogue.display.constraints.ConstraintContext;
import mightypork.rogue.display.events.ScreenChangeEvent;
import mightypork.rogue.input.KeyBinder;
import mightypork.rogue.input.KeyBindingPool;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.input.events.KeyboardEvent;
import mightypork.rogue.input.events.MouseButtonEvent;
import mightypork.rogue.input.events.MouseMotionEvent;
import mightypork.utils.math.coord.Coord;
import mightypork.utils.patterns.Initializable;
import mightypork.utils.time.Updateable;
import mightypork.utils.math.coord.Rect;
/**
@@ -22,27 +20,27 @@ import mightypork.utils.time.Updateable;
*
* @author MightyPork
*/
public abstract class Screen implements KeyBinder, Updateable, Initializable, KeyboardEvent.Listener, MouseMotionEvent.Listener, MouseButtonEvent.Listener, ScreenChangeEvent.Listener {
public abstract class Screen extends AppSubsystem implements KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
private KeyBindingPool keybindings = new KeyBindingPool();
private KeyBindingPool keybindings;
private boolean active;
public Screen() {
initialize();
public Screen(AppAccess app) {
super(app, false);
}
@Override
public void bindKeyStroke(KeyStroke stroke, Runnable task)
public final void bindKeyStroke(KeyStroke stroke, Runnable task)
{
keybindings.bindKeyStroke(stroke, task);
}
@Override
public void unbindKeyStroke(KeyStroke stroke)
public final void unbindKeyStroke(KeyStroke stroke)
{
keybindings.unbindKeyStroke(stroke);
}
@@ -59,13 +57,19 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
active = true;
setupGraphics();
setupViewport();
onSizeChanged(App.disp().getSize());
onEnter();
App.msgbus().addSubscriber(this);
onSizeChanged(getRect().getSize());
onScreenEnter();
// subscribe to event bus
enableEvents(true);
} else {
onScreenLeave();
active = false;
onLeave();
App.msgbus().removeSubscriber(this);
// unsusbcribe from event bus
enableEvents(false);
}
}
@@ -99,7 +103,7 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
// fix projection for changed size
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
Coord s = App.disp().getSize();
Coord s = disp().getSize();
glViewport(0, 0, s.xi(), s.yi());
glOrtho(0, s.x, 0, s.y, -1000, 1000);
@@ -108,25 +112,47 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
}
@Override
protected final void init()
{
keybindings = new KeyBindingPool();
addChildSubscriber(keybindings);
initScreen();
}
@Override
protected final void deinit()
{
deinitScreen();
}
/**
* Initialize screen layout and key bindings.<br>
* Called when the screen is created, not when it comes to front. For that,
* use onEnter().
* Called during screen construction.
*/
@Override
public abstract void initialize();
protected abstract void initScreen();
/**
* Clean up before screen is destroyed.
*/
protected abstract void deinitScreen();
/**
* Called when the screen becomes active
*/
protected abstract void onEnter();
protected abstract void onScreenEnter();
/**
* Called when the screen is no longer active
*/
protected abstract void onLeave();
protected abstract void onScreenLeave();
/**
@@ -134,7 +160,10 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
*
* @param size screen size
*/
protected abstract void onSizeChanged(Coord size);
protected void onSizeChanged(Coord size)
{
// no impl
}
/**
@@ -154,7 +183,7 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
/**
* Render screen
*/
private final void renderBegin()
private void renderBegin()
{
glPushAttrib(GL_ENABLE_BIT);
glPushMatrix();
@@ -164,32 +193,17 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
/**
* Render screen
*/
private final void renderEnd()
private void renderEnd()
{
glPopAttrib();
glPopMatrix();
}
/**
* Update and render the screen
*/
@Override
public final void update(double delta)
{
if (!isActive()) return;
updateScreen(delta);
renderBegin();
renderScreen();
renderEnd();
};
/**
* @return true if screen is the curretn screen
*/
protected final boolean isActive()
public final boolean isActive()
{
return active;
}
@@ -206,11 +220,24 @@ public abstract class Screen implements KeyBinder, Updateable, Initializable, Ke
}
/**
* Update and render the screen
*/
@Override
public final void receive(KeyboardEvent event)
public final void update(double delta)
{
if (!isActive()) return;
keybindings.receive(event);
updateScreen(delta);
renderBegin();
renderScreen();
renderEnd();
}
@Override
public final Rect getRect()
{
return disp().getRect();
}
}
@@ -3,10 +3,9 @@ package mightypork.rogue.display;
import java.util.Random;
import mightypork.rogue.App;
import mightypork.rogue.AppAccess;
import mightypork.rogue.input.KeyStroke;
import mightypork.rogue.input.events.MouseButtonEvent;
import mightypork.rogue.input.events.MouseMotionEvent;
import mightypork.rogue.util.RenderUtils;
import mightypork.utils.math.Polar;
import mightypork.utils.math.color.RGB;
@@ -19,8 +18,12 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
public class ScreenTestAnimations extends Screen {
public class ScreenTestAnimations extends Screen implements MouseButtonEvent.Listener {
public ScreenTestAnimations(AppAccess app) {
super(app);
}
private Random rand = new Random();
private AnimDoubleDeg degAnim = new AnimDoubleDeg(0, Easing.ELASTIC_OUT);
@@ -94,7 +97,7 @@ public class ScreenTestAnimations extends Screen {
//@formatter:on
@Override
public void initialize()
public void initScreen()
{
bindKeyStroke(new KeyStroke(Keyboard.KEY_RIGHT), new Runnable() {
@@ -102,7 +105,7 @@ public class ScreenTestAnimations extends Screen {
public void run()
{
for (AnimDouble a : anims) {
a.animate(0, 1, 1+rand.nextDouble()*1);
a.animate(0, 1, 1 + rand.nextDouble() * 1);
}
}
});
@@ -113,13 +116,45 @@ public class ScreenTestAnimations extends Screen {
public void run()
{
for (AnimDouble a : anims) {
a.animate(1, 0, 1+rand.nextDouble()*1);
a.animate(1, 0, 1 + rand.nextDouble() * 1);
}
}
});
}
@Override
protected void deinitScreen()
{
// no impl
}
@Override
protected void onScreenEnter()
{
// no impl
}
@Override
protected void onScreenLeave()
{
// no impl
}
@Override
protected void updateScreen(double delta)
{
degAnim.update(delta);
for (AnimDouble a : anims) {
a.update(delta);
}
}
@Override
protected void renderScreen()
{
@@ -143,18 +178,11 @@ public class ScreenTestAnimations extends Screen {
}
@Override
public void receive(MouseMotionEvent event)
{
//
}
@Override
public void receive(MouseButtonEvent event)
{
if (event.isDown()) {
Coord vec = App.disp().getSize().half().vecTo(event.getPos());
Coord vec = disp().getSize().half().vecTo(event.getPos());
Polar p = Polar.fromCoord(vec);
@@ -162,39 +190,4 @@ public class ScreenTestAnimations extends Screen {
}
}
@Override
protected void onEnter()
{
// TODO Auto-generated method stub
}
@Override
protected void onLeave()
{
// TODO Auto-generated method stub
}
@Override
protected void onSizeChanged(Coord size)
{
// TODO Auto-generated method stub
}
@Override
protected void updateScreen(double delta)
{
degAnim.update(delta);
for (AnimDouble a : anims) {
a.update(delta);
}
}
}
@@ -4,7 +4,15 @@ package mightypork.rogue.display.constraints;
import mightypork.utils.math.coord.Rect;
/**
* Constraints can be based on this
*
* @author MightyPork
*/
public interface ConstraintContext {
/**
* @return bounding rectangle
*/
public Rect getRect();
}
@@ -0,0 +1,33 @@
package mightypork.rogue.display.events;
import mightypork.utils.patterns.subscription.Handleable;
public class UpdateEvent implements Handleable<UpdateEvent.Listener> {
private final double deltaTime;
public UpdateEvent(double deltaTime) {
this.deltaTime = deltaTime;
}
public double getDeltaTime()
{
return deltaTime;
}
@Override
public void handleBy(Listener handler)
{
handler.receive(this);
}
public interface Listener {
public void receive(UpdateEvent event);
}
}