BartRunnerAndroid/app/src/main/java/com/dougkeen/bart/controls/Ticker.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();
}
}