package org.cellularautomaton.state;

import java.util.ArrayList;

/**
 * A state memory is the memory of a cell. It keeps the previous states of the
 * cell.
 * 
 * @author Matthieu Vergne (matthieu.vergne@gmail.com)
 * 
 * @param <StateType>
 *            the type of data used by the cell, it can be {@link Boolean} for a
 *            simple "On/Off" state, a numeral state like {@link Integer} or
 *            {@link Float} for arithmetical states, or any specific type of
 *            data for particular uses.
 */
public class StateMemory<StateType> {
	/**
	 * The states memorized.
	 */
	private final ArrayList<StateType> states = new ArrayList<StateType>();

	/**
	 * 
	 * @param size
	 *            the size of the memory
	 * @param initialState
	 *            the state to fill the memory with
	 */
	public StateMemory(int size, StateType initialState) {
		assert initialState != null;

		for (int i = 0; i < size; i++) {
			states.add(initialState);
		}
	}

	/**
	 * @param state
	 *            the new state to push in the memory, which forgets the oldest
	 *            state
	 */
	public void pushNewState(StateType state) {
		assert state != null;

		states.remove(0);
		states.add(state);
	}

	/**
	 * @param the
	 *            age of the state asked, 0 is the most recent
	 * @return the asked memorized state
	 */
	public StateType getState(int age) {
		int size = getMemorySize();
		assert age >= 0 && age < size : "the age must be in [0;" + (size - 1) + "]";

		return states.get(size - age - 1);
	}

	/**
	 * 
	 * @return the size of the memory
	 */
	public int getMemorySize() {
		return states.size();
	}

	/**
	 * 
	 * @param state
	 *            the state to apply instead of the current state, the state is
	 *            not pushed so the previous state is not kept in memory
	 */
	public void forceCurrentState(StateType state) {
		states.set(states.size() - 1, state);
	}
}

@@ -1142,31 +1142,33 @@
 %7B%0A%09%09
-assert state != null;%0A%0A
+synchronized (states) %7B%0A%09
 %09%09st
@@ -1183,16 +1183,17 @@
 ove(0);%0A
+%09
 %09%09states
@@ -1205,16 +1205,20 @@
 state);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09/**
@@ -1380,116 +1380,33 @@
 %7B%0A%09%09
-int size = getMemorySize();%0A%09%09assert age %3E= 0 && age %3C size : %22the age must be in %5B0;%22 + (size - 1) + %22%5D%22;%0A%0A
+synchronized (states) %7B%0A%09
 %09%09re
@@ -1421,20 +1421,31 @@
 tes.get(
-s
+getMemoryS
 ize
+()
  - age -
@@ -1449,16 +1449,20 @@
 e - 1);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09/**
@@ -1537,16 +1537,43 @@
 ize() %7B%0A
+%09%09synchronized (states) %7B%0A%09
 %09%09return
@@ -1588,16 +1588,20 @@
 size();%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09/**
@@ -1825,16 +1825,43 @@
 tate) %7B%0A
+%09%09synchronized (states) %7B%0A%09
 %09%09states
@@ -1892,13 +1892,17 @@
 state);%0A
+%09%09%7D%0A
 %09%7D%0A%7D%0A

Remove assertions (not used) + synchronize the states access (conccurrent problems with the ant sample).