Finished MPROM support. Fixes #10
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / standard / memory / AbstractAssignableBitVectorMemory.java
diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AbstractAssignableBitVectorMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AbstractAssignableBitVectorMemory.java
new file mode 100644 (file)
index 0000000..782a5b6
--- /dev/null
@@ -0,0 +1,110 @@
+package net.mograsim.machine.standard.memory;
+
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Set;
+
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.BitVectorMemory;
+import net.mograsim.machine.BitVectorMemoryDefinition;
+import net.mograsim.machine.Memory.MemoryCellModifiedListener;
+
+public class AbstractAssignableBitVectorMemory<M extends BitVectorMemory> implements BitVectorMemory, MemoryCellModifiedListener
+{
+       private Set<MemoryCellModifiedListener> observers = new HashSet<>();
+       private Set<BitVectorMemoryReassignedListener<M>> reassignmentListeners = new HashSet<>();
+       private M real = null;
+
+       public AbstractAssignableBitVectorMemory(M memory)
+       {
+               real = memory;
+               real.registerCellModifiedListener(this);
+       }
+
+       public void bind(M real)
+       {
+               this.real.deregisterCellModifiedListener(this);
+               this.real = real;
+               real.registerCellModifiedListener(this);
+               notifyMemoryChanged(-1);
+               notifyMemoryReassigned(real);
+       }
+
+       @Override
+       public BitVector getCell(long address)
+       {
+               return real.getCell(address);
+       }
+
+       @Override
+       public BigInteger getCellAsBigInteger(long address)
+       {
+               return real.getCellAsBigInteger(address);
+       }
+
+       @Override
+       public void setCell(long address, BitVector data)
+       {
+               real.setCell(address, data);
+       }
+
+       @Override
+       public void setCellAsBigInteger(long address, BigInteger word)
+       {
+               real.setCellAsBigInteger(address, word);
+       }
+
+       @Override
+       public void registerCellModifiedListener(MemoryCellModifiedListener ob)
+       {
+               observers.add(ob);
+       }
+
+       protected M getReal()
+       {
+               return real;
+       }
+
+       @Override
+       public BitVectorMemoryDefinition getDefinition()
+       {
+               return real.getDefinition();
+       }
+
+       @Override
+       public void deregisterCellModifiedListener(MemoryCellModifiedListener ob)
+       {
+               observers.remove(ob);
+       }
+
+       private void notifyMemoryChanged(long address)
+       {
+               observers.forEach(o -> o.update(address));
+       }
+
+       @Override
+       public void update(long address)
+       {
+               notifyMemoryChanged(address);
+       }
+
+       public void registerMemoryReassignedListener(BitVectorMemoryReassignedListener<M> listener)
+       {
+               reassignmentListeners.add(listener);
+       }
+
+       public void deregisterMemoryReassignedListener(BitVectorMemoryReassignedListener<M> listener)
+       {
+               reassignmentListeners.remove(listener);
+       }
+
+       private void notifyMemoryReassigned(M newAssignee)
+       {
+               reassignmentListeners.forEach(l -> l.reassigned(newAssignee));
+       }
+
+       public interface BitVectorMemoryReassignedListener<M extends BitVectorMemory>
+       {
+               public void reassigned(M newAssignee);
+       }
+}