Merge remote-tracking branch 'origin/GP-1-dragonmacher-domain-object-with-transaction--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-08-22 13:12:08 -04:00
commit b261137b40
2 changed files with 92 additions and 35 deletions

View File

@ -272,48 +272,36 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> {
break;
}
if (!name.equals(block.getName())) {
int id = program.startTransaction("Rename Memory Block");
try {
block.setName(name);
program.endTransaction(id, true);
}
catch (LockException e) {
program.endTransaction(id, false);
this.provider.setStatusText(e.getMessage());
return;
}
catch (RuntimeException e1) {
program.endTransaction(id, false);
throw e1;
}
program.withTransaction("Rename Memory Block", () -> {
try {
block.setName(name);
}
catch (LockException e) {
provider.setStatusText(e.getMessage());
}
});
}
break;
case READ: {
int id = program.startTransaction("Set Read State");
try {
program.withTransaction("Set Read State", () -> {
boolean value = ((Boolean) aValue).booleanValue();
block.setRead(value);
provider.setStatusText("");
program.endTransaction(id, true);
}
catch (RuntimeException e) {
program.endTransaction(id, false);
throw e;
}
});
break;
}
case WRITE: {
int id = program.startTransaction("Set Write State");
try {
program.withTransaction("Set Write State", () -> {
boolean value = ((Boolean) aValue).booleanValue();
block.setWrite(value);
provider.setStatusText("");
program.endTransaction(id, true);
}
catch (RuntimeException e) {
program.endTransaction(id, false);
throw e;
}
});
break;
}
case EXECUTE: {
@ -514,8 +502,9 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> {
}
private String getByteSourceDescription(List<MemoryBlockSourceInfo> sourceInfos) {
List<MemoryBlockSourceInfo> limited = sourceInfos.size() < 5 ? sourceInfos : sourceInfos.subList(0, 4);
List<MemoryBlockSourceInfo> limited =
sourceInfos.size() < 5 ? sourceInfos : sourceInfos.subList(0, 4);
//@formatter:off
String description = limited
.stream()

View File

@ -18,6 +18,8 @@ package ghidra.framework.model;
import db.TerminatedTransactionException;
import db.Transaction;
import ghidra.framework.store.LockException;
import utility.function.ExceptionalCallback;
import utility.function.ExceptionalSupplier;
/**
* <code>UndoableDomainObject</code> extends a domain object to provide transaction
@ -48,6 +50,72 @@ public interface UndoableDomainObject extends DomainObject, Undoable {
*/
public Transaction openTransaction(String description) throws IllegalStateException;
/**
* Performs the given callback inside of a transaction. Use this method in place of the more
* verbose try/catch/finally semantics.
* <p>
* <pre>
* program.withTransaction("My Description", () -> {
* // ... Do something
* });
* </pre>
*
* <p>
* Note: the transaction created by this method will always be committed when the call is
* finished. If you need the ability to abort transactions, then you need to use the other
* methods on this interface.
*
* @param description brief description of transaction
* @param callback the callback that will be called inside of a transaction
* @throws E any exception that may be thrown in the given callback
*/
public default <E extends Exception> void withTransaction(String description,
ExceptionalCallback<E> callback) throws E {
int id = startTransaction(description);
try {
callback.call();
}
finally {
endTransaction(id, true);
}
}
/**
* Calls the given supplier inside of a transaction. Use this method in place of the more
* verbose try/catch/finally semantics.
* <p>
* <pre>
* program.withTransaction("My Description", () -> {
* // ... Do something
* return result;
* });
* </pre>
* <p>
* If you do not need to supply a result, then use
* {@link #withTransaction(String, ExceptionalCallback)} instead.
*
* @param <E> the exception that may be thrown from this method
* @param <T> the type of result returned by the supplier
* @param description brief description of transaction
* @param supplier the supplier that will be called inside of a transaction
* @return the result returned by the supplier
* @throws E any exception that may be thrown in the given callback
*/
public default <E extends Exception, T> T withTransaction(String description,
ExceptionalSupplier<T, E> supplier) throws E {
T t = null;
boolean success = false;
int id = startTransaction(description);
try {
t = supplier.get();
success = true;
}
finally {
endTransaction(id, success);
}
return t;
}
/**
* Start a new transaction in order to make changes to this domain object.
* All changes must be made in the context of a transaction.
@ -90,8 +158,8 @@ public interface UndoableDomainObject extends DomainObject, Undoable {
public TransactionInfo getCurrentTransactionInfo();
/**
* Returns true if the last transaction was terminated externally from the action that
* started it.
* Returns true if the last transaction was terminated from the action that started it.
* @return true if the last transaction was terminated from the action that started it.
*/
public boolean hasTerminatedTransaction();
@ -108,7 +176,7 @@ public interface UndoableDomainObject extends DomainObject, Undoable {
* using a shared transaction manager. If either or both is already shared,
* a transition to a single shared transaction manager will be
* performed.
* @param domainObj
* @param domainObj the domain object
* @throws LockException if lock or open transaction is active on either
* this or the specified domain object
*/