org.microemu.app.util.MIDletTimer Maven / Gradle / Ivy
/**
* MicroEmulator
* Copyright (C) 2006-2007 Bartek Teodorczyk
* Copyright (C) 2006-2007 Vlad Skarzhevskyy
*
* It is licensed under the following two licenses as alternatives:
* 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
* 2. Apache License (the "AL") Version 2.0
*
* You may not use this file except in compliance with at least one of
* the above two licenses.
*
* You may obtain a copy of the LGPL at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
*
* You may obtain a copy of the AL at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the LGPL or the AL for the specific language governing permissions and
* limitations.
*
* @version $Id: MIDletTimer.java 2092 2009-06-13 10:14:45Z barteo $
*/
package org.microemu.app.util;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.WeakHashMap;
import org.microemu.MIDletBridge;
import org.microemu.MIDletContext;
import org.microemu.log.Logger;
/**
* Terminate all timers on MIDlet exit. TODO Name all the timer Threads created
* by MIDlet in Java 5
*
* @author vlads
*/
public class MIDletTimer extends Timer implements Runnable {
private static Map midlets = new WeakHashMap();
private String name;
private MIDletContext midletContext;
// TODO use better data structure
List tasks;
private boolean cancelled;
private MIDletThread thread;
public MIDletTimer() {
super();
StackTraceElement[] ste = new Throwable().getStackTrace();
name = ste[1].getClassName() + "." + ste[1].getMethodName();
tasks = new ArrayList();
cancelled = false;
thread = new MIDletThread(this);
thread.start();
}
// TODO exceptions
public void schedule(TimerTask task, Date time) {
register(this);
schedule(task, time.getTime(), -1, false);
}
// TODO exceptions
public void schedule(TimerTask task, Date firstTime, long period) {
register(this);
schedule(task, firstTime.getTime(), period, false);
}
// TODO exceptions
public void schedule(TimerTask task, long delay) {
register(this);
schedule(task, System.currentTimeMillis() + delay, -1, false);
}
// TODO exceptions
public void schedule(TimerTask task, long delay, long period) {
register(this);
schedule(task, System.currentTimeMillis() + delay, period, false);
}
// TODO exceptions
public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
register(this);
schedule(task, firstTime.getTime(), period, true);
}
// TODO exceptions
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
register(this);
schedule(task, System.currentTimeMillis() + delay, period, true);
}
public void cancel() {
unregister(this);
terminate();
}
public void run() {
while (!cancelled) {
MIDletTimerTask task = null;
long nextTimeTask = Long.MAX_VALUE;
synchronized (tasks) {
Iterator it = tasks.iterator();
while (it.hasNext()) {
MIDletTimerTask candidate = (MIDletTimerTask) it.next();
if (candidate.time > System.currentTimeMillis()) {
if (candidate.time < nextTimeTask) {
nextTimeTask = candidate.time;
}
continue;
}
if (task == null) {
task = candidate;
} else if (candidate.time < task.time) {
if (task.time < nextTimeTask) {
nextTimeTask = task.time;
}
task = candidate;
} else if (candidate.time < nextTimeTask) {
nextTimeTask = candidate.time;
}
}
if (task != null) {
if (task.period > 0) {
task.oneTimeTaskExcecuted = true;
}
tasks.remove(task);
}
}
if (task != null) {
try {
task.run();
synchronized (tasks) {
// TODO implement scheduling for fixed rate tasks
if (task.period > 0) {
task.time = System.currentTimeMillis() + task.period;
tasks.add(task);
if (task.time < nextTimeTask) {
nextTimeTask = task.time;
}
}
}
} catch (Throwable t) {
Logger.debug("MIDletTimerTask throws", t);
}
}
synchronized (tasks) {
try {
if (nextTimeTask == Long.MAX_VALUE) {
tasks.wait();
} else {
long timeout = nextTimeTask - System.currentTimeMillis();
if (timeout > 0) {
tasks.wait(timeout);
}
}
} catch (InterruptedException e) {
}
}
}
}
private void terminate() {
cancelled = true;
}
private void schedule(TimerTask task, long time, long period, boolean fixedRate) {
synchronized (tasks) {
((MIDletTimerTask) task).timer = this;
((MIDletTimerTask) task).time = time;
((MIDletTimerTask) task).period = period;
tasks.add(task);
tasks.notify();
}
}
private static void register(MIDletTimer timer) {
if (timer.midletContext == null) {
timer.midletContext = MIDletBridge.getMIDletContext();
}
if (timer.midletContext == null) {
Logger.error("Creating Timer with no MIDlet context", new Throwable());
return;
}
Map timers = (Map) midlets.get(timer.midletContext);
if (timers == null) {
// Can't use WeakHashMap Timers are disposed by JVM
timers = new HashMap();
midlets.put(timer.midletContext, timers);
}
// Logger.debug("Register timer created from [" + timer.name + "]");
timers.put(timer, timer.midletContext);
}
private static void unregister(MIDletTimer timer) {
if (timer.midletContext == null) {
// Logger.error("Timer with no MIDlet context", new Throwable());
return;
}
Map timers = (Map) midlets.get(timer.midletContext);
if (timers == null) {
return;
}
// Logger.debug("Unregister timer created from [" + timer.name + "]");
timers.remove(timer);
}
/**
* Terminate all Threads created by MIDlet
*/
public static void contextDestroyed(MIDletContext midletContext) {
if (midletContext == null) {
return;
}
Map timers = (Map) midlets.get(midletContext);
if (timers != null) {
terminateTimers(timers);
midlets.remove(midletContext);
}
}
private static void terminateTimers(Map timers) {
for (Iterator iter = timers.keySet().iterator(); iter.hasNext();) {
Object o = iter.next();
if (o == null) {
continue;
}
if (o instanceof MIDletTimer) {
MIDletTimer tm = (MIDletTimer) o;
Logger.warn("MIDlet timer created from [" + tm.name + "] still running");
tm.terminate();
} else {
Logger.debug("unrecognized Object [" + o.getClass().getName() + "]");
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy