package worldData;
import util.EfficientList;
import android.os.SystemClock;
import android.util.Log;
public class SystemUpdater implements Runnable {
private final String LOG_TAG = "SystemUpdater";
/*
* delay should be reduced if the game process gets more complecated! TODO
* do this dynamically so that each update cycle is about 20ms long
*/
private static final long GAME_THREAD_DELAY = 20;
private boolean running = true;
/**
* this is the delay the WorldUpdater checks if it has to return from
* sleeping when paused and a resume request happens
*/
private static final long GAME_THREAD_NOT_KILLED_DELAY = 700;
private boolean notKilled = true;
private long lastTimeInMs;
private EfficientList<Updateable> myObjectsToUpdate = new EfficientList<Updateable>();
@Override
public void run() {
/*
* When the systemUpdater is started the first time, it will check for a
* special type of UpdatableObjects, the UpdatableWithInit objects and
* call their init method before executing the actual update loop
*/
for (int i = 0; i < myObjectsToUpdate.myLength; i++) {
if (myObjectsToUpdate.get(i) instanceof UpdatableWithInit)
((UpdatableWithInit) myObjectsToUpdate.get(i)).init();
}
lastTimeInMs = SystemClock.uptimeMillis();
while (notKilled) {
while (running) {
final long currentTime = SystemClock.uptimeMillis();
final float timeDelta = (currentTime - lastTimeInMs) / 1000.0f;
lastTimeInMs = currentTime;
for (int i = 0; i < myObjectsToUpdate.myLength; i++) {
if (!myObjectsToUpdate.get(i).update(timeDelta, null)) {
myObjectsToUpdate.remove(myObjectsToUpdate.get(i));
}
}
try {
Thread.sleep(GAME_THREAD_DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
killUpdaterThread();
}
}
try {
Thread.sleep(GAME_THREAD_NOT_KILLED_DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
killUpdaterThread();
}
}
}
public void addObjectToUpdateCycle(Updateable updateableObject) {
if (myObjectsToUpdate.contains(updateableObject) == -1)
myObjectsToUpdate.add(updateableObject);
else
Log.e(LOG_TAG, "The object " + updateableObject
+ " will not be added twice to the Updater! "
+ "Only add it once, check the code!");
}
public boolean removeObjectFromUpdateCylce(Updateable updateableObject) {
return myObjectsToUpdate.remove(updateableObject);
}
public void pauseUpdater() {
running = false;
}
public void resumeUpdater() {
running = true;
}
/**
* This can't be undone! If you want to stop the {@link SystemUpdater} use
* pauseUpdater() only if you do not need any updates anymore you can kill
* it completely with this method
*/
public void killUpdaterThread() {
notKilled = false;
running = false;
}
}