Using Transfer API comparator calculator crashes the game
Juuxel opened this issue ยท 3 comments
- My BE's
SingleVariantStorage<FluidVariant>
has amarkDirty
call inonFinalCommit
. From what I can see, this is standard. - When a transfer is made,
markDirty
callsWorld.updateComparators
. - The same BE's block uses
StorageUtil.calculateComparatorOutput(storage, null)
to calculate the comparator output based on the aforementioned storage.World.updateComparators
then calls this method (indirectly). - This opens another outer transaction while the transfer tx is still going on, and crashes: https://gist.github.com/Juuxel/b40ce8baf93e30865ab8ea18394b33cc
Note: Transaction.getCurrentUnsafe
does not work either because it can't be used in a close callback (which onFinalCommit
is)
When I mentioned this during the original development,
the suggested solution was to mark your block internally as being dirty then do the real markDirty()
on its next tick:
#1356 (comment)
The other way to do it would be move the --depth
so that depth = -1 (no associated transaction)
during after close callbacks but this would likely play badly with other features?
It could also potentially lead to recursive calls seeing incomplete/old/wrong state?
the suggested solution was to mark your block internally as being dirty then do the real markDirty() on its next tick
I had forgotten about this, but this might indeed be the best solution. I wouldn't be against a fabric API helper for this. Maybe just a simple public static void doLater(Runnable runnable) // do something at the end of the current server tick
.
Allowing outer close callbacks to open transactions will probably complicate the implementations of non-trivial inventories even more.
Fixed in 1.19 with #2139.