Skip to content

Instantly share code, notes, and snippets.

@youxiachai
Created July 19, 2014 02:14
Show Gist options
  • Save youxiachai/5b10b397bfd678bcbc5e to your computer and use it in GitHub Desktop.
Save youxiachai/5b10b397bfd678bcbc5e to your computer and use it in GitHub Desktop.
简单模拟了一下 node 的事件类
public class EventMain {
public static class Emitter {
private ConcurrentMap<String, ConcurrentLinkedQueue<Listener>> mCallbacks = new ConcurrentHashMap<String, ConcurrentLinkedQueue<Listener>>();
private ConcurrentHashMap<Listener, Listener> mOnceCallback = new ConcurrentHashMap<Emitter.Listener, Emitter.Listener>();
public Emitter on(String event, Listener fn) {
ConcurrentLinkedQueue<Listener> callbacks = this.mCallbacks.get(event);
if (callbacks == null) {
callbacks = new ConcurrentLinkedQueue<Emitter.Listener>();
ConcurrentLinkedQueue<Listener> _callbacks = this.mCallbacks
.putIfAbsent(event, callbacks);
if (_callbacks != null) {
callbacks = _callbacks;
}
}
callbacks.add(fn);
return this;
}
/**只用一次的时间
* @param event
* @param fn
* @return
*/
public Emitter once(final String event, final Listener fn){
Listener on = new Listener() {
@Override
public void call(Object... args) {
Emitter.this.off(event, this);
fn.call(args);;
}
};
this.mOnceCallback.put(fn, on);
this.on(event, on);
return this;
}
/**取消某个事件
* @param event
* @param fn
* @return
*/
public Emitter off(String event, Listener fn) {
ConcurrentLinkedQueue<Listener> callbacks = this.mCallbacks.get(event);
if(callbacks != null){
// 优先取消 once 的事件
Listener off = this.mOnceCallback.remove(fn);
callbacks.remove(off != null ? off : fn);
}
return this;
}
public Emitter emit(String event, Object... args){
ConcurrentLinkedQueue<Listener> callbacks = this.mCallbacks.get(event);
if(callbacks != null){
callbacks = new ConcurrentLinkedQueue<Emitter.Listener>(callbacks);
for(Listener fn : callbacks){
fn.call(args);
}
}
return this;
}
public static interface Listener {
public void call(Object... args);
}
}
public static class TestEvent extends Emitter {
}
public static void main(String[] args) {
TestEvent te = new TestEvent();
te.on("fsck", new Listener() {
@Override
public void call(Object... args) {
System.out.println(args[0]);
}
});
te.emit("fsck", "disk");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment