/*
Copyright 2012-2013, Polyvi Inc. (http://polyvi.github.io/openxface)
This program is distributed under the terms of the GNU General Public License.
This file is part of xFace.
xFace is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
xFace is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with xFace. If not, see <http://www.gnu.org/licenses/>.
*/
package com.polyvi.xface.event;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
/**
* 系统事件中心 处理系统事件的分发以及注册事件接收器
*
*/
public class XSystemEventCenter {
static final int MSG_EXEC_PENDING_EVENT = 1;
private final Context mContext;
private final Handler mHandler;
private Map<Integer, ArrayList<XISystemEventReceiver>> mReceivers;
private List<EventReceiverRecord> mEvtReceiverRecords;
public XSystemEventCenter(Context context) {
mContext = context;
mEvtReceiverRecords = new ArrayList<XSystemEventCenter.EventReceiverRecord>();
mReceivers = new ConcurrentHashMap<Integer, ArrayList<XISystemEventReceiver>>();
mHandler = new Handler(context.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_EXEC_PENDING_EVENT:
notifyPendingEvent();
break;
default:
super.handleMessage(msg);
}
}
};
}
/**
* 表示等待执行的事件记录
*
*/
private static class EventReceiverRecord {
public XEvent evt;
public ArrayList<XISystemEventReceiver> receivers;
public EventReceiverRecord(XEvent event,
ArrayList<XISystemEventReceiver> recevierList) {
evt = event;
receivers = recevierList;
}
}
/**
* 注册事件接收器
*
* @param receiver
* @param evtType
*/
public void registerReceiver(XISystemEventReceiver receiver,
int evtType) {
synchronized (mReceivers) {
ArrayList<XISystemEventReceiver> receivers = mReceivers
.get(evtType);
if (null == receivers) {
receivers = new ArrayList<XISystemEventReceiver>();
mReceivers.put(evtType, receivers);
}
receivers.add(receiver);
}
}
/**
* 反注册事件接收器
*
* @param receiver
*/
public void unregisterReceiver(XISystemEventReceiver receiver) {
synchronized (mReceivers) {
Iterator<Entry<Integer, ArrayList<XISystemEventReceiver>>> iter = mReceivers
.entrySet().iterator();
while (iter.hasNext()) {
Entry<Integer, ArrayList<XISystemEventReceiver>> entry = iter
.next();
ArrayList<XISystemEventReceiver> receivers = entry.getValue();
if (null != receivers) {
for (int k = 0; k < receivers.size(); k++) {
if (receivers.get(k) == receiver) {
receivers.remove(k);
k--;
}
}
int evtType = entry.getKey();
if (receivers.size() <= 0) {
mReceivers.remove(evtType);
}
}
}
}
}
/**
* 发送事件(同步)
*
* @param evt
*/
public void sendEventSync(XEvent evt) {
ArrayList<XISystemEventReceiver> pendingReceivers = null;
synchronized (mReceivers) {
pendingReceivers = findReceivers(evt);
}
if(null == pendingReceivers) {
return;
}
if (pendingReceivers.size() > 0) {
notifyReceivers(pendingReceivers, evt);
}
}
/**
* 发送事件(异步)
*
* @param evt
* @return
*/
public boolean sendEventAsync(XEvent evt) {
synchronized (mReceivers) {
ArrayList<XISystemEventReceiver> pendingReceivers = findReceivers(evt);
if (pendingReceivers.size() > 0) {
EventReceiverRecord record = new EventReceiverRecord(evt,
pendingReceivers);
mEvtReceiverRecords.add(record);
if (!mHandler.hasMessages(MSG_EXEC_PENDING_EVENT)) {
mHandler.sendEmptyMessage(MSG_EXEC_PENDING_EVENT);
}
return true;
}
}
return false;
}
/**
* 查找对应的事件接收器
* @param sendEvt 发送的事件
* @return
*/
private ArrayList<XISystemEventReceiver> findReceivers(
XEvent evt) {
int sendEvt = evt.getType();
Iterator<Entry<Integer, ArrayList<XISystemEventReceiver>>> iter = mReceivers
.entrySet().iterator();
ArrayList<XISystemEventReceiver> pendingReceivers = new ArrayList<XISystemEventReceiver>();
while (iter.hasNext()) {
Entry<Integer, ArrayList<XISystemEventReceiver>> entry = iter
.next();
int evtType = entry.getKey();
if (sendEvt == evtType) {
ArrayList<XISystemEventReceiver> receivers = entry
.getValue();
if (null != receivers) {
for (int k = 0; k < receivers.size(); k++) {
XISystemEventReceiver receiver = receivers.get(k);
pendingReceivers.add(receiver);
}
}
}
}
return pendingReceivers;
}
/**
* 通知事件接收器
*/
private void notifyPendingEvent() {
while (true) {
EventReceiverRecord[] per = null;
synchronized (mReceivers) {
int size = mEvtReceiverRecords.size();
if (size <= 0) {
return;
}
per = new EventReceiverRecord[size];
mEvtReceiverRecords.toArray(per);
mEvtReceiverRecords.clear();
}
for (int i = 0; i < per.length; i++) {
EventReceiverRecord er = per[i];
notifyReceivers(er.receivers, er.evt);
}
}
}
/**
* 通知每个事件接收器
* @param receivers
* @param event
*/
private void notifyReceivers(
ArrayList<XISystemEventReceiver> receivers,
XEvent event) {
for (int index = 0; index < receivers.size(); index++) {
receivers.get(index).onReceived(mContext, event);
}
}
}