Update storage API documentation to lay out some decisions

This commit is contained in:
DBotThePony 2022-06-29 22:00:09 +07:00
parent eb74baffb8
commit 4d7ab09e27
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 33 additions and 2 deletions

View File

@ -240,7 +240,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val item = craftingGrid[i] val item = craftingGrid[i]
if (!item.isEmpty) { if (!item.isEmpty) {
poweredView[ItemStackWrapper(item).key()].let(craftingGridTuples[i]::addAll) poweredView[ItemStackWrapper(item).key()]?.let(craftingGridTuples[i]::add)
} }
} }
} }
@ -248,7 +248,6 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
} }
private val craftingGridTuples = Array(3 * 3) { HashSet<UUID>() } private val craftingGridTuples = Array(3 * 3) { HashSet<UUID>() }
private val craftingGridTuplesFuzzy = Array(3 * 3) { HashSet<UUID>() }
private val craftingMenu = object : AbstractContainerMenu(null, Int.MIN_VALUE) { private val craftingMenu = object : AbstractContainerMenu(null, Int.MIN_VALUE) {
override fun stillValid(p_38874_: Player): Boolean { override fun stillValid(p_38874_: Player): Boolean {

View File

@ -101,6 +101,9 @@ interface IStorageEventConsumer<T : IStorageStack> : IStorage<T> {
fun removeStack(stack: T, id: UUID) fun removeStack(stack: T, id: UUID)
} }
/**
* Storage acceptor, accepts (insert only) stacks provided via [insertStack] method.
*/
interface IStorageAcceptor<T : IStorageStack> : IStorage<T> { interface IStorageAcceptor<T : IStorageStack> : IStorage<T> {
/** /**
* Inserts an item into system. * Inserts an item into system.
@ -109,14 +112,40 @@ interface IStorageAcceptor<T : IStorageStack> : IStorage<T> {
fun insertStack(stack: T, simulate: Boolean): T fun insertStack(stack: T, simulate: Boolean): T
} }
/**
* Storage provider, provides (extract only) stacks to whoever needs them (the "warehouse").
*
* [get] methods work as in bidirectional map.
*
* It is **required** for storage having **exactly one or none** of mappings of one stack [T]
* to one [UUID] (exactly one *UUID -> stack* and exactly one *stack -> UUID*).
*
* What this means is that [get] with [T] as an argument shall never experience a situation where
* two stacks match provided key.
*
* Technical decision of using [UUID]s for primary key for locating stacks is performance.
* This allows us to avoid burden of constantly constructing keys out of stacks (e.g. [net.minecraft.world.item.ItemStack]s)
* which may or may not produce performance hit; [UUID]s are lightweight, semantically not bound to anything and are
* very good for distributed ID generation (so nothing in game has to be bound to one sequential number generator).
*/
interface IStorageProvider<T : IStorageStack> : IStorageEventProducer<T> { interface IStorageProvider<T : IStorageStack> : IStorageEventProducer<T> {
/** /**
* Attempts to retrieve stored stack by its [id].
*
* Returns stored stack as-is. If no stack with [id] exists, then
* "empty stack" is returned.
*
* @param id identifier of stack * @param id identifier of stack
* @return stored object (not a copy). Do not edit it. * @return stored object (not a copy). Do not edit it.
*/ */
operator fun get(id: UUID): T operator fun get(id: UUID): T
/** /**
* Attempts to map given [key] to [UUID] inside this storage provider.
*
* Implementation requirement: There should **never** be a situation where one [key]
* matches two or more stacks. **Exactly one or none**.
*
* @param key stack we want to find UUID of * @param key stack we want to find UUID of
* @return UUID of stack if present * @return UUID of stack if present
*/ */
@ -169,6 +198,9 @@ fun <T : IStorageStack> IStorageProvider<T>.addListenerAuto(listener: IStorageEv
return false return false
} }
/**
* Storage component, which basically implement Input and Output
*/
interface IStorageComponent<T : IStorageStack> : IStorageProvider<T>, IStorageAcceptor<T> interface IStorageComponent<T : IStorageStack> : IStorageProvider<T>, IStorageAcceptor<T>
fun <T : IStorageStack> IStorageEventConsumer<T>.changeStack(tuple: IStorageTuple<T>, oldCount: BigInteger) { fun <T : IStorageStack> IStorageEventConsumer<T>.changeStack(tuple: IStorageTuple<T>, oldCount: BigInteger) {