package com.jenjinstudios.io.concurrency;

import com.jenjinstudios.io.ExecutionContext;

import java.util.concurrent.TimeUnit;

/**
 * Represents a task with access to an ExecutionContext that should be repeated at a given interval until it is
 * canceled.
 *
 * @author Caleb Brinkman
 */
public abstract class RecurringTask<T extends ExecutionContext>
{
    private final long interval;
    private long lastExecutionTime;

    /**
     * Construct a RecurringTask that should execute roughly once per second.
     */
    public RecurringTask() { this(TimeUnit.SECONDS); }

    /**
     * Construct a RecurringTask that should execute roughly once per the time unit specified.
     *
     * @param timeUnit The time unit that should pass between each execution.  Note that no time unit will ever cause
     * this task to be executed faster that once per millisecond.  Also note that this specifies the <i>minimum</i>
     * unit
     * of time that must pass before the next time this task executes.
     */
    public RecurringTask(TimeUnit timeUnit) { this(timeUnit.toMillis(1)); }

    /**
     * Construct a RecurringTask that will execute roughly once every {@code interval} milliseconds.
     *
     * @param interval The number of milliseconds that should have passed between executions of this task.  Note that
     * is the <i>minimum</i> number of milliseconds; more may pass between each execution.
     */
    public RecurringTask(long interval) { this.interval = interval; }

    public final long getInterval() { return interval; }

    /**
     * This method is invoked by the execution thread when <i>at least</i> the number of milliseconds specified by
     * {@code getInterval} have passed since the last time it was executed.
     *
     * @param context The ExecutionContext provided to this RecurringTask, specific to the execution thread on which it
     * was scheduled.
     */
    public abstract void execute(T context);

    final boolean shouldExecute(long currentTime) { return (currentTime - lastExecutionTime) >= interval; }

    final void done() { lastExecutionTime = System.currentTimeMillis(); }
}

@@ -350,16 +350,47 @@
 text%3E%0A%7B%0A
+    private boolean cancelled;%0A
     priv
@@ -1977,16 +1977,222 @@
 text);%0A%0A
+    /**%0A     * Cancel this task; after this method is called, the task will not be run again.%0A     */%0A    public void cancel() %7B cancelled = true; %7D%0A%0A    public boolean isCancelled() %7B return cancelled; %7D%0A%0A
     fina
@@ -2234,24 +2234,47 @@
 tTime) %7B
- return 
+%0A        return !cancelled && (
 (current
@@ -2302,33 +2302,38 @@
 ime) %3E= interval
-;
+);%0A   
  %7D%0A%0A    final vo

Add "cancelled" field to RecurringTask