// Path: src/engine/util/Vec2.java
// public class Vec2 {
// 
//   private float x, y;
// 
//   public Vec2() {
//     this(0, 0);
//   }
// 
//   public Vec2(Vec2 toCopy) {
//     this(toCopy.x, toCopy.y);
//   }
// 
//   public Vec2(float x, float y) {
//     this.x = x;
//     this.y = y;
//   }
// 
//   public float getX() {
//     return x;
//   }
// 
//   public float getY() {
//     return y;
//   }
//   
//   public Vec2 copy() {
//     return new Vec2(this);
//   }
//   
//   public void add(Vec2 p) {
//     this.x += p.x;
//     this.y += p.y;
//   }
// 
//   public void mul(Vec2 p) {
//     this.x *= p.x;
//     this.y *= p.y;
//   }
//   
//   public void div(float n) {
//     this.x /= n;
//     this.y /= n;
//   }
// 
//   public void normalize() {
//     float mag = mag();
//     if (mag != 0) {
//       div(mag);
//     }
//   }
//   
//   public void set(Vec2 p) {
//     this.x = p.x;
//     this.y = p.y;
//   }
// 
//   public void neg() {
//     x = -x;
//     y = -y;
//   }
// 
//   public float mag() {
//     return (float) Math.sqrt((x * x + y * y));
//   }
// 
//   public Vec2 truncate() {
//     return new Vec2((int) x, (int) y);
//   }
// 
//   @Override
//   public boolean equals(Object obj) {
//     if (obj == null || !(obj instanceof Vec2)) {
//       return false;
//     } else {
//       Vec2 o = (Vec2) obj;
//       return o.x == x && o.y == y;
//     }
//   }
// 
//   @Override
//   public int hashCode() {
//     int hash = 5;
//     hash = 17 * hash + (int) this.x;
//     hash = 17 * hash + (int) this.y;
//     return hash;
//   }
// 
//   @Override
//   public String toString() {
//     StringBuilder str = new StringBuilder();
//     str.append("[").append(x).append(", ").append(y).append("]");
//     return str.toString();
//   }
// 
//   public boolean isZero() {
//     return mag() == 0;
//   }
// 
//   public void zero() {
//     this.set(new Vec2());
//   }
// 
// }
// 
// 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.util.Vec2;
import engine.util.concurrent.MThread;
package engine.surface;


/**
 * The cell is a base class for each cell contained in a SurfaceMap. The Cell
 * has two representations for position. It's grid position which is immutable
 * and the actual position. The actual position is mutable and can be used as a
 * way to describe an 'out of resolution' position.
 *
 * @author Richard DeSilvey
 */
public abstract class Cell {

  private final Vec2 gridPosition, actualPosition;
// Path: src/engine/util/Vec2.java
// public class Vec2 {
// 
//   private float x, y;
// 
//   public Vec2() {
//     this(0, 0);
//   }
// 
//   public Vec2(Vec2 toCopy) {
//     this(toCopy.x, toCopy.y);
//   }
// 
//   public Vec2(float x, float y) {
//     this.x = x;
//     this.y = y;
//   }
// 
//   public float getX() {
//     return x;
//   }
// 
//   public float getY() {
//     return y;
//   }
//   
//   public Vec2 copy() {
//     return new Vec2(this);
//   }
//   
//   public void add(Vec2 p) {
//     this.x += p.x;
//     this.y += p.y;
//   }
// 
//   public void mul(Vec2 p) {
//     this.x *= p.x;
//     this.y *= p.y;
//   }
//   
//   public void div(float n) {
//     this.x /= n;
//     this.y /= n;
//   }
// 
//   public void normalize() {
//     float mag = mag();
//     if (mag != 0) {
//       div(mag);
//     }
//   }
//   
//   public void set(Vec2 p) {
//     this.x = p.x;
//     this.y = p.y;
//   }
// 
//   public void neg() {
//     x = -x;
//     y = -y;
//   }
// 
//   public float mag() {
//     return (float) Math.sqrt((x * x + y * y));
//   }
// 
//   public Vec2 truncate() {
//     return new Vec2((int) x, (int) y);
//   }
// 
//   @Override
//   public boolean equals(Object obj) {
//     if (obj == null || !(obj instanceof Vec2)) {
//       return false;
//     } else {
//       Vec2 o = (Vec2) obj;
//       return o.x == x && o.y == y;
//     }
//   }
// 
//   @Override
//   public int hashCode() {
//     int hash = 5;
//     hash = 17 * hash + (int) this.x;
//     hash = 17 * hash + (int) this.y;
//     return hash;
//   }
// 
//   @Override
//   public String toString() {
//     StringBuilder str = new StringBuilder();
//     str.append("[").append(x).append(", ").append(y).append("]");
//     return str.toString();
//   }
// 
//   public boolean isZero() {
//     return mag() == 0;
//   }
// 
//   public void zero() {
//     this.set(new Vec2());
//   }
// 
// }
// 
// 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/surface/Cell.java
import engine.util.Vec2;
import engine.util.concurrent.MThread;

package engine.surface;


/**
 * The cell is a base class for each cell contained in a SurfaceMap. The Cell
 * has two representations for position. It's grid position which is immutable
 * and the actual position. The actual position is mutable and can be used as a
 * way to describe an 'out of resolution' position.
 *
 * @author Richard DeSilvey
 */
public abstract class Cell {

  private final Vec2 gridPosition, actualPosition;
  private MThread parentThread;