/**
* Copyright (c) 2014 Tom Zhou
* @author tomzhou
*
*/
package com.iwebpp;
import java.nio.ByteBuffer;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.iwebpp.node.EventEmitter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
/*
* @description
* Node.js EvenEmitter implementation with Android Handler
* */
public class EventHandler
extends SimpleDebug
implements EventEmitter {
private final static String TAG = "EventHandler";
private msgHdl hdl;
private Map<String, List<Listener>> events;
private Map<String, Integer> maxEvents;
// @description message handler
private class msgHdl extends Handler {
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
public void handleMessage (Message msg) {
Bundle bdl = msg.getData();
String event = bdl.getString("event");
Object data = msg.obj;
if (events.containsKey(event)) {
for (Listener cb : events.get(event))
try {
// always create new one to share in case ByteBuffer, etc
if (data!=null && data instanceof ByteBuffer) {
ByteBuffer bb = ((ByteBuffer)data).slice();
cb.onEvent(bb);
} else
cb.onEvent(data);
} catch (Exception e) {
e.printStackTrace();
error(TAG, "Exception event "+event+","+e);
}
} else {
warn(TAG, "unknown event "+event);
}
}
}
public EventHandler() {
this.hdl = new msgHdl();
this.events = new Hashtable<String, List<Listener>>();
this.maxEvents = new Hashtable<String, Integer>();
}
@Override
public boolean emit(final String event, final Object data) throws Exception {
Message msg = hdl.obtainMessage();
Bundle bdl = new Bundle();
// event string
bdl.putString("event", event);
msg.setData(bdl);
// data object
msg.obj = data;
return hdl.sendMessage(msg) && events.containsKey(event);
}
@Override
public boolean emit(String event) throws Exception {
return emit(event, null);
}
@Override
public EventEmitter on(final String event, final Listener cb) {
return addListener(event, cb);
}
@Override
public EventEmitter once(final String event, final Listener ocb) {
return addListener(event, new Listener(){
@Override
public void onEvent(final Object data) throws Exception {
ocb.onEvent(data);
// remove listener
removeListener(event, this);
}
});
}
@Override
public EventEmitter addListener(final String event, final Listener cb) {
// check maxListens
if (maxEvents.containsKey(event) &&
maxEvents.get(event) < listenerCount(event)) {
warn(TAG, "exceed maxListeners@"+event+" at="+this);
///return this;
}
if (!events.containsKey(event))
events.put(event, new LinkedList<Listener>());
events.get(event).add(cb);
return this;
}
@Override
public EventEmitter addListener(String event, Listener cb, int priority) {
// check maxListens
if (maxEvents.containsKey(event) &&
maxEvents.get(event) < listenerCount(event)) {
warn(TAG, "exceed maxListeners@"+event+" at="+this);
///return this;
}
if (!events.containsKey(event))
events.put(event, new LinkedList<Listener>());
if (priority < listenerCount(event))
events.get(event).add(priority, cb);
else
events.get(event).add(cb);
return this;
}
@Override
public EventEmitter removeListener(final String event, final Listener cb) {
if (events.containsKey(event) && events.get(event).contains(cb))
events.get(event).remove(cb);
return this;
}
@Override
public EventEmitter removeListener(final String event) {
if (events.containsKey(event))
events.get(event).clear();
return this;
}
@Override
public EventEmitter removeListener() {
events.clear();
return this;
}
@Override
public EventEmitter removeAllListeners() {
events.clear();
return this;
}
@Override
public EventEmitter setMaxListeners(final String event, final int n) {
this.maxEvents.put(event, n);
return this;
}
@Override
public List<Listener> listeners(final String event) {
return events.containsKey(event) ? events.get(event) : null;
}
@Override
public int listenerCount(final String event) {
return events.containsKey(event) ? events.get(event).size() : 0;
}
}