Class SnapshotJournal<T extends @Nullable Object>

java.lang.Object
net.neoforged.neoforge.transfer.transaction.SnapshotJournal<T>
Type Parameters:
T - The objects that this journal uses to record its state snapshots.
Direct Known Subclasses:
CauldronWrapper, ComposterWrapper, ItemStackResourceHandler, PlayerInventoryWrapper.DroppedItems, RootCommitJournal, SimpleEnergyHandler.EnergyJournal, StacksResourceHandler.StackJournal, TransactionalRandom

public abstract class SnapshotJournal<T extends @Nullable Object> extends Object
A journal that modifies itself during transactions, saving snapshots of its state in objects of type T in case it needs to revert to a previous state.

How to use from subclasses

More technical explanation

updateSnapshots(net.neoforged.neoforge.transfer.transaction.TransactionContext) should be called before any modification. This will record the state in the journal using createSnapshot() if no state was already saved for that transaction. When the transaction is aborted and changes need to be rolled back, revertToSnapshot(T) will be called to signal that the current state should revert to that of the snapshot. The snapshot object is then released, and can be cached for subsequent use, or discarded.

When the root transaction is committed, revertToSnapshot(T) will not be called so that the current state of the journal is retained. onRootCommit(T) will be called after the transaction is closed and then releaseSnapshot(T) will be called because the snapshot is not necessary anymore.

  • Field Details

    • NO_SNAPSHOT

      private static final Object NO_SNAPSHOT
      Used for entries of snapshots that do not correspond to a snapshot. null corresponds to a snapshot that happens to be null.
    • snapshots

      private final ArrayList<T extends @Nullable Object> snapshots
    • originalState

      private @Nullable T extends @Nullable Object originalState
  • Constructor Details

    • SnapshotJournal

      public SnapshotJournal()
  • Method Details

    • createSnapshot

      protected abstract T createSnapshot()
      Return a new nonnull object containing the current state of this journal. null may not be returned, or an exception will be thrown!
    • revertToSnapshot

      protected abstract void revertToSnapshot(T snapshot)
      Roll back to a state previously created by createSnapshot().
    • releaseSnapshot

      protected void releaseSnapshot(T snapshot)
      Signals that the snapshot will not be used anymore, and is safe to cache for future calls to createSnapshot(), or discard entirely.
    • onRootCommit

      protected void onRootCommit(T originalState)
      Called after the root transaction was successfully committed, to perform irreversible actions such as setChanged() or neighbor updates.

      When a root transaction is being closed, all journals for which onRootCommit will be called are stored in a global thread-local queue. The processing of this queue starts immediately after the root transaction is closed. As such, new root transactions can safely be opened from this method.

      When a root transaction is opened from onRootCommit, any journal might be modified, leading to more onRootCommit callbacks being enqueued:

      • A journal that is already enqueued for onRootCommit will not be enqueued a second time. It will thus be notified a single time for changes that spanned multiple transactions. The originalState will be the state at the beginning of the first of these transactions.
      • A journal whose onRootCommit was already processed will be enqueued again. The journal will be notified a second time, with originalState the state at the beginning of the second transaction.
      • In particular, a journal is removed from the queue immediately before onRootCommit is called. Should the journal be modified again from its own onRootCommit, it will be added to the queue, and onRootCommit will be called again later.

      Given the large amount of actions that can happen between the last modification and the call to onRootCommit, journals should not depend on onRootCommit being called immediately for correctness, and implementations of this method should be careful (e.g. in case the journal got removed from the level). For example, skipping block change notifications because the block was removed from the level is preferable than crashing or silently overwriting the block.

      Parameters:
      originalState - state of this journal before the transactional operations. This corresponds to the first snapshot that was created in the transactional operations.
    • updateSnapshots

      public void updateSnapshots(TransactionContext transaction)
      Update the stored snapshots so that the changes happening as part of the passed transaction can be correctly committed or rolled back. This function should be called every time the journal is about to change its internal state as part of a transaction. However, only the first snapshot taken of that depth will be taken.
    • onClose

      void onClose(Transaction transaction, boolean wasAborted)
      Perform the required state management when a transaction is closed.
    • callOnRootCommit

      void callOnRootCommit()