// Path: src/engine/surface/Cell.java
// public abstract class Cell {
// 
//   private final Vec2 gridPosition, actualPosition;
//   private MThread parentThread;
// 
//   public Cell(int x, int y) {
//     gridPosition = new Vec2(x, y);
//     actualPosition = new Vec2(x, y);
//   }
//   
//   public void setParentThread(MThread parentThread) {
//     this.parentThread = parentThread;
//   }
//   
//   public MThread getParentThread() {
//     return parentThread;
//   }
//   
//   public int getX() {
//     return (int) gridPosition.getX();
//   }
// 
//   public int getY() {
//     return (int) gridPosition.getY();
//   }
// 
//   /**
//    * The position in the hash map as x and y componets.
//    *
//    * @return The copy of the cell position object.
//    */
//   public Vec2 getGridPosition() {
//     return gridPosition.copy();
//   }
// 
//   /**
//    * The actual position of this cell. By default this position will be equal to
//    * it's grid position.
//    *
//    * @return
//    */
//   public Vec2 getActualPosition() {
//     return actualPosition;
//   }
// 
// //  public abstract List<Integer[]> render(List<Integer[]> settings);
// 
//   public String toString() {
//     return "[" + gridPosition.getX() + ", " + gridPosition.getY() + "]"
//             + "[" + actualPosition.getX() + ", " + actualPosition.getY() + "]";
//   }
// 
// }
// 
// Path: src/engine/util/concurrent/MThread.java
// public class MThread extends TaskRunner {
// 
//   private final TaskManager manager;
//   /**
//    * Other threads may want to update or apply an event to other cells
//    * not belonging to that thread. The other thread will post an update to
//    * this thread to process the event using the queue.
//    */
//   private final ConcurrentLinkedDeque<Event> eventQueue;
//   
//   private static final boolean CONTINUOUS = true;
// 
//   private final CyclicBarrier waitingGate;
// 
//   public MThread(int delay) {
//     this(delay, new Boundaries(0, 0), new CyclicBarrier(1));
//   }
//   
//   public MThread(int delay, Boundaries bounds) {
//     this(delay, bounds, new CyclicBarrier(1));
//   }
//   
//   /**
//    * Constructs a new MapThread.
//    *
//    * @param delay The amount of time to delay each frame in milliseconds
//    * @param bounds The surface boundaries
//    * @param waitingGate The CyclicBarrier to synchronize with other threads
//    */
//   public MThread(int delay, Boundaries bounds, CyclicBarrier waitingGate) {
//     super(delay, CONTINUOUS);
//     this.waitingGate = waitingGate;
//     manager = new TaskManager(bounds);
//     eventQueue = new ConcurrentLinkedDeque<>();
//   }
// 
//   @Override
//   public final void update() throws Exception {
//     waitingGate.await();
//     processEventQueue();
//     manager.performTasks();
//     manager.trimTasks();
//   }
// 
//   public void pushEvent(Event event) {
//     eventQueue.push(event);
//   }
//   
//   public void processEventQueue() {
//     eventQueue.forEach(event -> {
//       event.execute();
//     });
//   }
// 
//   public final void addTask(Task task) {
//     task.setThread(this);
//     manager.addTask(task);
//   }
// 
//   public TaskManager getManager() {
//     return manager;
//   }
// }


import engine.surface.Cell;
import engine.util.concurrent.MThread;
package engine.util.task;


/**
 * A Task is something the simulation will perform given a condition.
 *
 * @author Richard DeSilvey
 */
public abstract class Task {

  /**
   * A public, mutable, reference to the thread working on this task. If this
   * object reference is null then this task is not part of a TaskFactory.
   */
  private MThread parentThread = null;
  
  /**
   * Marks this Task as being a single task to run only once. By default
   * this is set to false.
   */
  protected boolean singleTask = false;

  public void setThread(MThread thread) {
    parentThread = thread;
  }

  public final MThread getThread() {
    return parentThread;
  }

// Path: src/engine/surface/Cell.java
// public abstract class Cell {
// 
//   private final Vec2 gridPosition, actualPosition;
//   private MThread parentThread;
// 
//   public Cell(int x, int y) {
//     gridPosition = new Vec2(x, y);
//     actualPosition = new Vec2(x, y);
//   }
//   
//   public void setParentThread(MThread parentThread) {
//     this.parentThread = parentThread;
//   }
//   
//   public MThread getParentThread() {
//     return parentThread;
//   }
//   
//   public int getX() {
//     return (int) gridPosition.getX();
//   }
// 
//   public int getY() {
//     return (int) gridPosition.getY();
//   }
// 
//   /**
//    * The position in the hash map as x and y componets.
//    *
//    * @return The copy of the cell position object.
//    */
//   public Vec2 getGridPosition() {
//     return gridPosition.copy();
//   }
// 
//   /**
//    * The actual position of this cell. By default this position will be equal to
//    * it's grid position.
//    *
//    * @return
//    */
//   public Vec2 getActualPosition() {
//     return actualPosition;
//   }
// 
// //  public abstract List<Integer[]> render(List<Integer[]> settings);
// 
//   public String toString() {
//     return "[" + gridPosition.getX() + ", " + gridPosition.getY() + "]"
//             + "[" + actualPosition.getX() + ", " + actualPosition.getY() + "]";
//   }
// 
// }
// 
// Path: src/engine/util/concurrent/MThread.java
// public class MThread extends TaskRunner {
// 
//   private final TaskManager manager;
//   /**
//    * Other threads may want to update or apply an event to other cells
//    * not belonging to that thread. The other thread will post an update to
//    * this thread to process the event using the queue.
//    */
//   private final ConcurrentLinkedDeque<Event> eventQueue;
//   
//   private static final boolean CONTINUOUS = true;
// 
//   private final CyclicBarrier waitingGate;
// 
//   public MThread(int delay) {
//     this(delay, new Boundaries(0, 0), new CyclicBarrier(1));
//   }
//   
//   public MThread(int delay, Boundaries bounds) {
//     this(delay, bounds, new CyclicBarrier(1));
//   }
//   
//   /**
//    * Constructs a new MapThread.
//    *
//    * @param delay The amount of time to delay each frame in milliseconds
//    * @param bounds The surface boundaries
//    * @param waitingGate The CyclicBarrier to synchronize with other threads
//    */
//   public MThread(int delay, Boundaries bounds, CyclicBarrier waitingGate) {
//     super(delay, CONTINUOUS);
//     this.waitingGate = waitingGate;
//     manager = new TaskManager(bounds);
//     eventQueue = new ConcurrentLinkedDeque<>();
//   }
// 
//   @Override
//   public final void update() throws Exception {
//     waitingGate.await();
//     processEventQueue();
//     manager.performTasks();
//     manager.trimTasks();
//   }
// 
//   public void pushEvent(Event event) {
//     eventQueue.push(event);
//   }
//   
//   public void processEventQueue() {
//     eventQueue.forEach(event -> {
//       event.execute();
//     });
//   }
// 
//   public final void addTask(Task task) {
//     task.setThread(this);
//     manager.addTask(task);
//   }
// 
//   public TaskManager getManager() {
//     return manager;
//   }
// }


// Path: src/engine/util/task/Task.java
import engine.surface.Cell;
import engine.util.concurrent.MThread;

package engine.util.task;


/**
 * A Task is something the simulation will perform given a condition.
 *
 * @author Richard DeSilvey
 */
public abstract class Task {

  /**
   * A public, mutable, reference to the thread working on this task. If this
   * object reference is null then this task is not part of a TaskFactory.
   */
  private MThread parentThread = null;
  
  /**
   * Marks this Task as being a single task to run only once. By default
   * this is set to false.
   */
  protected boolean singleTask = false;

  public void setThread(MThread thread) {
    parentThread = thread;
  }

  public final MThread getThread() {
    return parentThread;
  }

  public boolean isNotChildCell(Cell cell) {