SimpleJavaEngine/src/main/java/speiger/src/coreengine/utils/tasks/MainThreadTaskProcessor.java

147 lines
2.4 KiB
Java

package speiger.src.coreengine.utils.tasks;
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
import speiger.src.collections.objects.utils.ObjectPriorityQueues;
import speiger.src.coreengine.utils.counters.timers.CountdownSync;
public class MainThreadTaskProcessor
{
ObjectPriorityDequeue<ITask> tasks = ObjectPriorityQueues.synchronize(new ObjectArrayFIFOQueue<ITask>());
Watchdog watch;
Thread watchThread;
boolean running = false;
long timeout;
public MainThreadTaskProcessor(long timeout, String name)
{
this.timeout = timeout;
watch = new Watchdog(Thread.currentThread());
watchThread = new Thread(watch, name+"-Thread-Watchdog");
watchThread.start();
}
public void setTimeout(long timeout)
{
this.timeout = timeout;
}
public void addTask(ITask task)
{
tasks.enqueue(task);
}
public void finishAllTasks()
{
if(tasks.isEmpty())
{
return;
}
running = true;
while(!tasks.isEmpty())
{
try
{
tasks.dequeue().execute();
}
catch(InterruptedException e)
{
}
catch(Exception e)
{
e.printStackTrace();
}
}
running = false;
}
public void update()
{
if(tasks.isEmpty())
{
return;
}
watch.unlock();
running = true;
boolean interrupted = false;
while(!tasks.isEmpty() && !(interrupted |= Thread.interrupted()))
{
ITask task = tasks.dequeue();
try
{
task.execute();
}
catch(InterruptedException e)
{
interrupted = true;
}
catch(Exception e)
{
e.printStackTrace();
}
if(!task.isFinished())
{
tasks.enqueue(task);
}
}
running = false;
if(!interrupted)
{
watchThread.interrupt();
}
}
public void kill()
{
if(watchThread != null)
{
return;
}
watch.alive = false;
watchThread.interrupt();
watchThread = null;
}
class Watchdog implements Runnable
{
Thread owner;
boolean alive = true;
CountdownSync timer = new CountdownSync();
Object lock = new Object();
public Watchdog(Thread thread)
{
owner = thread;
}
@Override
public void run()
{
while(alive)
{
try
{
synchronized(lock)
{
lock.wait();
}
timer.sync(timeout);
if(running)
{
owner.interrupt();
}
}
catch(InterruptedException e) {}
}
}
public void unlock()
{
synchronized(lock)
{
lock.notify();
}
}
}
}