parent
6013a105ad
commit
4a1a84fd87
@ -1,2 +1,3 @@ |
||||
/bin/ |
||||
/target/ |
||||
*.log |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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; |
@ -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(); |
||||
|
||||
} |
@ -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); |
||||
} |
||||
} |
@ -1,26 +0,0 @@ |
||||
package mightypork.utils.patterns.subscription; |
||||
|
||||
|
||||
/** |
||||
* Subscribable object |
||||
* |
||||
* @author MightyPork |
||||
*/ |
||||
public interface Subscribable { |
||||
|
||||
/** |
||||
* Subscribe a client to messages from this object |
||||
* |
||||
* @param client a subscribing client |
||||
* @return true if client is now subscribed |
||||
*/ |
||||
public boolean addSubscriber(Object client); |
||||
|
||||
|
||||
/** |
||||
* Unsubscribe a client from from this object |
||||
* |
||||
* @param client a clientto unsubscribe |
||||
*/ |
||||
public void removeSubscriber(Object client); |
||||
} |
@ -0,0 +1,25 @@ |
||||
package mightypork.utils.patterns.subscription.clients; |
||||
|
||||
|
||||
import java.util.Collection; |
||||
|
||||
|
||||
/** |
||||
* Client containing child clients |
||||
* |
||||
* @author MightyPork |
||||
*/ |
||||
public interface DelegatingClient { |
||||
|
||||
/** |
||||
* @return collection of child clients. Can not be null. |
||||
*/ |
||||
public Collection<Object> getChildClients(); |
||||
|
||||
|
||||
/** |
||||
* @return true if delegating is active |
||||
*/ |
||||
public boolean doesDelegate(); |
||||
|
||||
} |
@ -0,0 +1,16 @@ |
||||
package mightypork.utils.patterns.subscription.clients; |
||||
|
||||
|
||||
/** |
||||
* Client that can toggle receiving messages. |
||||
* |
||||
* @author MightyPork |
||||
*/ |
||||
public interface ToggleableClient { |
||||
|
||||
/** |
||||
* @return true if the client wants to receive messages |
||||
*/ |
||||
public boolean doesSubscribe(); |
||||
|
||||
} |
Loading…
Reference in new issue