/** * 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; } }