Skip to content

Instantly share code, notes, and snippets.

@tell
Created September 28, 2012 23:50
Show Gist options
  • Save tell/3802655 to your computer and use it in GitHub Desktop.
Save tell/3802655 to your computer and use it in GitHub Desktop.
Forwarding Events
package com.github.gist._3802655;
public interface EventCall <LISTENER> {
public void addListener(LISTENER listener);
public void removeListener(LISTENER listener);
}
package com.github.gist._3802655;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ForwardingHoge implements EventCall<ForwardingHoge.Listener> {
public interface Listener {
public void onUpdated(ForwardingHoge hoge);
}
private class ForwardingCallback implements Hoge.Listener {
private final Listener listener;
public ForwardingCallback(Listener listener) {
this.listener = listener;
}
public void onUpdated(Hoge hoge) {
System.err.printf(
"identityHashCode of the object held by receiver is %x%n",
System.identityHashCode(ForwardingHoge.this.hoge));
System.err.printf("identityHashCode of the given object is %x%n",
System.identityHashCode(hoge));
assert ForwardingHoge.this.hoge == hoge;
listener.onUpdated(ForwardingHoge.this);
}
}
private final Hoge hoge;
private ConcurrentMap<Listener, ForwardingCallback> callbackMapping = new ConcurrentHashMap<Listener, ForwardingCallback>();
public ForwardingHoge(final Hoge hoge) {
this.hoge = hoge;
}
public void finalize() throws Throwable {
System.err.printf("finalize at %x for %x%n",
System.identityHashCode(this), System.identityHashCode(hoge));
for (final Entry<Listener, ForwardingCallback> e : callbackMapping
.entrySet()) {
hoge.removeListener(e.getValue());
}
super.finalize();
}
public String toString() {
return String.format("ForwardingHoge(%s)@%x", hoge,
System.identityHashCode(this));
}
public int getValue() {
return hoge.getValue();
}
public void setValue(final int value) {
hoge.setValue(value);
}
public void addListener(Listener listener) {
callbackMapping.putIfAbsent(listener, new ForwardingCallback(listener));
hoge.addListener(callbackMapping.get(listener));
}
public void removeListener(Listener listener) {
final ForwardingCallback callback = callbackMapping.get(listener);
hoge.removeListener(callback);
}
public void sendUpdatedMessage() {
System.err.println("send updated message to wrapped object");
hoge.sendUpdatedMessage();
}
}
package com.github.gist._3802655;
import java.util.concurrent.CopyOnWriteArrayList;
public final class Hoge implements EventCall<Hoge.Listener> {
public interface Listener {
public void onUpdated(Hoge hoge);
}
private CopyOnWriteArrayList<Listener> listeners = new CopyOnWriteArrayList<Hoge.Listener>();
private int value;
public int getValue() {
System.err.printf("current value @%h is %s%n", this, value);
return value;
}
public void setValue(final int value) {
this.value = value;
System.err.printf("new value @%h is %s%n", this, this.value);
}
public Hoge(final int value) {
this.value = value;
}
public String toString() {
return String.format("Hoge[%s]@%x", value,
System.identityHashCode(this));
}
public void addListener(Listener listener) {
listeners.addIfAbsent(listener);
System.err.printf("current listeners after add: %s%n", listeners);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
System.err.printf("current listeners after remove: %s%n", listeners);
}
public void sendUpdatedMessage() {
for (final Listener listener : listeners) {
System.err.printf("send updated message to %s%n", listener);
listener.onUpdated(this);
}
}
}
package com.github.gist._3802655;
public class Main {
private static class Foo implements ForwardingHoge.Listener {
public void onUpdated(ForwardingHoge hoge) {
System.out.printf("updated: %s%n", hoge);
}
}
/**
* @param args
*/
public static void main(String[] args) {
final Hoge a = new Hoge(0);
System.out.printf("%s%n", a);
final ForwardingHoge b = new ForwardingHoge(a);
System.out.printf("%s%n", b);
final Foo c = new Foo();
b.addListener(c);
a.setValue(1);
a.sendUpdatedMessage();
b.sendUpdatedMessage();
b.addListener(c);
a.setValue(2);
a.sendUpdatedMessage();
b.sendUpdatedMessage();
b.setValue(3);
a.sendUpdatedMessage();
b.sendUpdatedMessage();
b.removeListener(c);
a.sendUpdatedMessage();
b.sendUpdatedMessage();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment