/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
package com.cburch.logisim.circuit;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import com.cburch.logisim.circuit.appear.CircuitPins;
public abstract class CircuitTransaction {
public static final Integer READ_ONLY = Integer.valueOf(1);
public static final Integer READ_WRITE = Integer.valueOf(2);
protected abstract Map<Circuit,Integer> getAccessedCircuits();
protected abstract void run(CircuitMutator mutator);
public final CircuitTransactionResult execute() {
CircuitMutatorImpl mutator = new CircuitMutatorImpl();
Map<Circuit,Lock> locks = CircuitLocker.acquireLocks(this, mutator);
CircuitTransactionResult result;
try {
this.run(mutator);
// Let the port locations of each subcircuit's appearance be
// updated to reflect the changes - this needs to happen before
// wires are repaired because it could lead to some wires being
// split
Collection<Circuit> modified = mutator.getModifiedCircuits();
for (Circuit circuit : modified) {
CircuitMutatorImpl circMutator = circuit.getLocker().getMutator();
if (circMutator == mutator) {
CircuitPins pins = circuit.getAppearance().getCircuitPins();
ReplacementMap repl = mutator.getReplacementMap(circuit);
if (repl != null) {
pins.transactionCompleted(repl);
}
}
}
// Now go through each affected circuit and repair its wires
for (Circuit circuit : modified) {
CircuitMutatorImpl circMutator = circuit.getLocker().getMutator();
if (circMutator == mutator) {
WireRepair repair = new WireRepair(circuit);
repair.run(mutator);
} else {
// this is a transaction executed within a transaction -
// wait to repair wires until overall transaction is done
circMutator.markModified(circuit);
}
}
result = new CircuitTransactionResult(mutator);
for (Circuit circuit : result.getModifiedCircuits()) {
circuit.fireEvent(CircuitEvent.TRANSACTION_DONE, result);
}
} finally {
CircuitLocker.releaseLocks(locks);
}
return result;
}
}