Add Transaction#getCurrentUnsafe and fix mixin fields (#1685)

* Add Transaction#getCurrentUnsafe and fix mixin fields

* Update fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/transaction/TransactionManagerImpl.java

Co-authored-by: BasiqueEvangelist <basiqueevangelist@yandex.ru>

Co-authored-by: BasiqueEvangelist <basiqueevangelist@yandex.ru>
This commit is contained in:
Technici4n 2021-08-31 14:59:58 +02:00 committed by GitHub
parent 87cc6e4c30
commit 49e84ad51a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 6 deletions

View file

@ -104,6 +104,23 @@ public interface Transaction extends AutoCloseable, TransactionContext {
return maybeParent == null ? openOuter() : maybeParent.openNested(); return maybeParent == null ? openOuter() : maybeParent.openNested();
} }
/**
* Retrieve the currently open transaction, or null if there is none.
*
* <p><b>Usage of this function is strongly discouraged</b>, this is why it is deprecated and contains {@code unsafe} in its name.
* The transaction may be aborted unbeknownst to you and anything you think that you have committed might be undone.
* Only use it if you have no way to pass the transaction down the stack, for example if you are implementing compat with a simulation-based API,
* and you know what you are doing, for example because you opened the outer transaction.
*
* @throws IllegalStateException If called from a close or outer close callback.
* @deprecated Only use if you absolutely need it, there is almost always a better way.
*/
@Deprecated
@Nullable
static TransactionContext getCurrentUnsafe() {
return TransactionManagerImpl.MANAGERS.get().getCurrentUnsafe();
}
/** /**
* Close the current transaction, rolling back all the changes that happened during this transaction and * Close the current transaction, rolling back all the changes that happened during this transaction and
* the transactions opened with {@link #openNested} from this transaction. * the transactions opened with {@link #openNested} from this transaction.

View file

@ -18,6 +18,9 @@ package net.fabricmc.fabric.impl.transfer.transaction;
import java.util.ArrayList; import java.util.ArrayList;
import org.jetbrains.annotations.Nullable;
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
public class TransactionManagerImpl { public class TransactionManagerImpl {
@ -40,6 +43,17 @@ public class TransactionManagerImpl {
return open(); return open();
} }
@Nullable
public TransactionContext getCurrentUnsafe() {
if (currentDepth == -1) {
return null;
} else if (stack.get(currentDepth).isOpen) {
return stack.get(currentDepth);
} else {
throw new IllegalStateException("May not call getCurrentUnsafe() from a close callback.");
}
}
/** /**
* Open a new transaction, outer or nested, without performing any state check. * Open a new transaction, outer or nested, without performing any state check.
*/ */

View file

@ -31,10 +31,10 @@ import net.fabricmc.fabric.impl.transfer.fluid.FluidVariantCache;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class FluidMixin implements FluidVariantCache { public class FluidMixin implements FluidVariantCache {
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
private final FluidVariant cachedFluidVariant = new FluidVariantImpl((Fluid) (Object) this, null); private final FluidVariant fabric_cachedFluidVariant = new FluidVariantImpl((Fluid) (Object) this, null);
@Override @Override
public FluidVariant fabric_getCachedFluidVariant() { public FluidVariant fabric_getCachedFluidVariant() {
return cachedFluidVariant; return fabric_cachedFluidVariant;
} }
} }

View file

@ -17,7 +17,6 @@
package net.fabricmc.fabric.mixin.transfer; package net.fabricmc.fabric.mixin.transfer;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -30,11 +29,11 @@ import net.fabricmc.fabric.impl.transfer.item.ItemVariantImpl;
*/ */
@Mixin(Item.class) @Mixin(Item.class)
public class ItemMixin implements ItemVariantCache { public class ItemMixin implements ItemVariantCache {
@Unique @SuppressWarnings("ConstantConditions")
private final ItemVariant cachedItemVariant = new ItemVariantImpl((Item) (Object) this, null); private final ItemVariant fabric_cachedItemVariant = new ItemVariantImpl((Item) (Object) this, null);
@Override @Override
public ItemVariant fabric_getCachedItemVariant() { public ItemVariant fabric_getCachedItemVariant() {
return cachedItemVariant; return fabric_cachedItemVariant;
} }
} }

View file

@ -60,6 +60,21 @@ class TransactionExceptionsTests {
}, "Exceptions in close callbacks should be propagated through the transaction."); }, "Exceptions in close callbacks should be propagated through the transaction.");
if (callbacksInvoked != 4) throw new AssertionError("All 4 callbacks should have been invoked, only so many were: " + callbacksInvoked); if (callbacksInvoked != 4) throw new AssertionError("All 4 callbacks should have been invoked, only so many were: " + callbacksInvoked);
// Test getCurrentUnsafe.
if (Transaction.getCurrentUnsafe() != null) throw new AssertionError("Should have returned null.");
try (Transaction tx = Transaction.openOuter()) {
if (Transaction.getCurrentUnsafe() != tx) throw new AssertionError("Should have returned the current transaction.");
tx.addCloseCallback(((transaction, result) -> {
ensureException(Transaction::getCurrentUnsafe, "Should have thrown an exception in the close callback.");
}));
tx.addOuterCloseCallback((result) -> {
ensureException(Transaction::getCurrentUnsafe, "Should have thrown an exception in the outer close callback.");
});
}
// Test that transaction state is still OK after these exceptions. // Test that transaction state is still OK after these exceptions.
try (Transaction tx = Transaction.openOuter()) { try (Transaction tx = Transaction.openOuter()) {
tx.commit(); tx.commit();