115 lines
2.6 KiB
Java
115 lines
2.6 KiB
Java
package com.dougkeen.bart.controls;
|
|
|
|
import java.util.Iterator;
|
|
import java.util.WeakHashMap;
|
|
|
|
import android.content.Context;
|
|
import android.os.Handler;
|
|
|
|
public class Ticker {
|
|
public static interface TickSubscriber {
|
|
int getTickInterval();
|
|
|
|
void onTick(long mTickCount);
|
|
}
|
|
|
|
private static Ticker sInstance;
|
|
|
|
private WeakHashMap<TickSubscriber, Object> mSubscribers;
|
|
|
|
private WeakHashMap<Context, Object> mTickerHosts;
|
|
|
|
private TickerEngine mEngine;
|
|
|
|
private static class TickerEngine implements Runnable {
|
|
|
|
private static final int TICK_INTERVAL_MILLIS = 1000;
|
|
private Ticker publisher;
|
|
private Handler mHandler;
|
|
private boolean mPendingRequest = false;
|
|
private boolean mForceStop = false;
|
|
private long mTickCount = 0;
|
|
|
|
public TickerEngine(Ticker publisher) {
|
|
this.publisher = publisher;
|
|
this.mHandler = new Handler();
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
mPendingRequest = false;
|
|
if (mForceStop) {
|
|
mForceStop = false;
|
|
return;
|
|
}
|
|
|
|
long startTimeNanos = System.nanoTime();
|
|
Iterator<TickSubscriber> iterator = publisher.mSubscribers.keySet()
|
|
.iterator();
|
|
boolean stillHasListeners = false;
|
|
while (iterator.hasNext()) {
|
|
TickSubscriber subscriber = iterator.next();
|
|
if (subscriber == null) {
|
|
continue;
|
|
}
|
|
|
|
stillHasListeners = true;
|
|
if (subscriber.getTickInterval() > 0
|
|
&& mTickCount % subscriber.getTickInterval() == 0)
|
|
subscriber.onTick(mTickCount);
|
|
}
|
|
long endTimeNanos = System.nanoTime();
|
|
|
|
if (stillHasListeners && !mPendingRequest) {
|
|
mHandler.postDelayed(this, TICK_INTERVAL_MILLIS
|
|
- ((endTimeNanos - startTimeNanos) / 1000000));
|
|
mPendingRequest = true;
|
|
mTickCount++;
|
|
} else {
|
|
mPendingRequest = false;
|
|
}
|
|
}
|
|
|
|
public boolean isOn() {
|
|
return mPendingRequest;
|
|
}
|
|
|
|
public void stop() {
|
|
mForceStop = true;
|
|
}
|
|
|
|
};
|
|
|
|
public synchronized static Ticker getInstance() {
|
|
if (sInstance == null) {
|
|
sInstance = new Ticker();
|
|
}
|
|
return sInstance;
|
|
}
|
|
|
|
public void addSubscriber(TickSubscriber subscriber, Context host) {
|
|
if (!mSubscribers.containsKey(subscriber) && subscriber != null) {
|
|
mSubscribers.put(subscriber, null);
|
|
startTicking(host);
|
|
}
|
|
}
|
|
|
|
private Ticker() {
|
|
mSubscribers = new WeakHashMap<TickSubscriber, Object>();
|
|
mTickerHosts = new WeakHashMap<Context, Object>();
|
|
mEngine = new TickerEngine(this);
|
|
}
|
|
|
|
public void startTicking(Context host) {
|
|
mTickerHosts.put(host, true);
|
|
if (!mEngine.isOn())
|
|
mEngine.run();
|
|
}
|
|
|
|
public void stopTicking(Context host) {
|
|
mTickerHosts.remove(host);
|
|
if (mEngine.isOn() && mTickerHosts.isEmpty())
|
|
mEngine.stop();
|
|
}
|
|
}
|