/*
ChangeBlock.java
(c) 2014-2015 Edward Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.common.cpu;
import java.util.Arrays;
import v9t9.common.asm.RawInstruction;
/**
* This represents the changes made by an instruction,
* which may be applied and reverted from the CPU.
* @author ejs
*
*/
public abstract class ChangeBlock /*implements Cloneable*/ {
private static final IChangeElement[] NONE = new IChangeElement[0];
private IChangeElement[] elements;
private int elementIdx;
public RawInstruction inst;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + elementIdx;
for (int i = 0; i < elementIdx; i++)
result = prime * result + elements[i].hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ChangeBlock other = (ChangeBlock) obj;
if (elementIdx != other.elementIdx)
return false;
for (int i = 0; i < elementIdx; i++)
if (!elements[i].equals(other.elements[i]))
return false;
return true;
}
public void push(IChangeElement element) {
if (elements == null) {
elements = new IChangeElement[12];
}
elements[elementIdx++] = element;
}
public IChangeElement last() {
return elementIdx > 0 ? elements[elementIdx - 1] : null;
}
public void apply(ICpu cpu) {
for (int i = 0; i < elementIdx; i++)
elements[i].apply(cpu.getState());
}
public void revert(ICpu cpu) {
for (int i = elementIdx - 1; i >= 0; i--)
elements[i].revert(cpu.getState());
}
public IChangeElement[] copyElements() {
if (elements != null && elementIdx == elements.length)
return elements;
if (elements == null)
return NONE;
return Arrays.copyOf(elements, elementIdx);
}
public int getCount() {
return elementIdx;
}
public IChangeElement getElement(int index) {
return elements[index];
}
public void insert(int pos, ChangeBlock newBlock) {
System.arraycopy(elements, pos, elements, pos + newBlock.elementIdx, elementIdx - pos);
System.arraycopy(newBlock.elements, 0, elements, pos, newBlock.elementIdx);
elementIdx += newBlock.elementIdx;
}
public void delete(int pos) {
System.arraycopy(elements, pos + 1, elements, pos, elementIdx - pos - 1);
elementIdx --;
}
abstract public int getPC();
//
// @Override
// public ChangeBlock clone() {
// try {
// ChangeBlock block = (ChangeBlock) super.clone();
// for (int i = 0; i < elementIdx; i++)
// block.elements[i] = block.elements[i].clone();
// return block;
// } catch (CloneNotSupportedException e) {
// assert false;
// return null;
// }
// }
}