Some helper functions, split "Filtered" into own subclass with own "Simple" factory
This commit is contained in:
parent
ab1446b682
commit
9f6b9ad85b
@ -56,7 +56,7 @@ fun Container.vanishCursedItems() {
|
||||
}
|
||||
}
|
||||
|
||||
fun Container.balance(slots: IntSet, checkForEmpty: Boolean = true) {
|
||||
fun Container.balance(slots: IntCollection, checkForEmpty: Boolean = true) {
|
||||
if (slots.isEmpty() || checkForEmpty && !slots.any { getItem(it).isNotEmpty }) return
|
||||
|
||||
val empty = IntArrayList()
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.player.Player
|
||||
@ -32,10 +33,10 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack> {
|
||||
}
|
||||
|
||||
fun nonEmptySlotIterator(): Iterator<IContainerSlot> {
|
||||
return (0 until containerSize).iterator().map { containerSlot(it) }.filter { it.isNotEmpty }
|
||||
return slotIterator().filter { it.isNotEmpty }
|
||||
}
|
||||
|
||||
private fun slotIterator(allowedSlots: IntSet, predicate: Predicate<ItemStack>): IntIterator {
|
||||
private fun slotIterator(allowedSlots: IntCollection, predicate: Predicate<ItemStack>): IntIterator {
|
||||
return object : IntIterator() {
|
||||
private val parent = allowedSlots.intIterator()
|
||||
private var foundNext = false
|
||||
@ -76,15 +77,15 @@ interface IEnhancedContainer : IContainer, RecipeInput, Iterable<ItemStack> {
|
||||
}
|
||||
}
|
||||
|
||||
fun emptySlotIterator(allowedSlots: IntSet = slotRange): IntIterator {
|
||||
fun emptySlotIterator(allowedSlots: IntCollection = slotRange): IntIterator {
|
||||
return slotIterator(allowedSlots) { it.isEmpty }
|
||||
}
|
||||
|
||||
fun nonEmptySlotIterator(allowedSlots: IntSet = slotRange): IntIterator {
|
||||
fun nonEmptySlotIterator(allowedSlots: IntCollection = slotRange): IntIterator {
|
||||
return slotIterator(allowedSlots) { it.isNotEmpty }
|
||||
}
|
||||
|
||||
fun slotWithItemIterator(item: Item, allowedSlots: IntSet = slotRange): IntIterator {
|
||||
fun slotWithItemIterator(item: Item, allowedSlots: IntCollection = slotRange): IntIterator {
|
||||
return slotIterator(allowedSlots) { it.isNotEmpty && it.item === item }
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -9,17 +10,9 @@ import ru.dbotthepony.mc.otm.core.collect.filter
|
||||
import ru.dbotthepony.mc.otm.core.collect.map
|
||||
|
||||
/**
|
||||
* Container which revolve around embedding slot objects rather than providing direct item access
|
||||
* Skeletal implementation for containers which revolve around [IContainerSlot]
|
||||
*/
|
||||
interface ISlottedContainer : IEnhancedContainer {
|
||||
override fun slotIterator(): Iterator<IContainerSlot> {
|
||||
return (0 until containerSize).iterator().map { containerSlot(it) }
|
||||
}
|
||||
|
||||
override fun nonEmptySlotIterator(): Iterator<IContainerSlot> {
|
||||
return (0 until containerSize).iterator().map { containerSlot(it) }.filter { it.isNotEmpty }
|
||||
}
|
||||
|
||||
override fun setChanged(slot: Int) {
|
||||
containerSlot(slot).setChanged()
|
||||
}
|
||||
@ -44,7 +37,7 @@ interface ISlottedContainer : IEnhancedContainer {
|
||||
containerSlot(slot).item = itemStack
|
||||
}
|
||||
|
||||
private fun addItem(stack: ItemStack, simulate: Boolean, filterPass: Boolean, slots: IntSet, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack {
|
||||
private fun addItem(stack: ItemStack, simulate: Boolean, filterPass: Boolean, slots: IntCollection, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
@ -129,7 +122,7 @@ interface ISlottedContainer : IEnhancedContainer {
|
||||
val hasFilterableSlots: Boolean
|
||||
get() = slotIterator().any { it is IFilteredContainerSlot }
|
||||
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, slots: IntSet = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): ItemStack {
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): ItemStack {
|
||||
if (stack.isEmpty || slots.isEmpty())
|
||||
return stack
|
||||
|
||||
@ -148,7 +141,7 @@ interface ISlottedContainer : IEnhancedContainer {
|
||||
*
|
||||
* @return Whenever [stack] was modified
|
||||
*/
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntSet = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
if (stack.isEmpty)
|
||||
return false
|
||||
|
||||
@ -157,7 +150,7 @@ interface ISlottedContainer : IEnhancedContainer {
|
||||
return result.count != stack.count
|
||||
}
|
||||
|
||||
fun fullyAddItem(stack: ItemStack, slots: IntSet = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
fun fullyAddItem(stack: ItemStack, slots: IntCollection = slotRange, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean): Boolean {
|
||||
if (!addItem(stack, true, slots, popTime = popTime, onlyIntoExisting = onlyIntoExisting, ignoreFilters = ignoreFilters).isEmpty)
|
||||
return false
|
||||
|
||||
|
@ -109,11 +109,15 @@ open class ContainerSlot(
|
||||
notifyChanged(ItemStack.EMPTY)
|
||||
}
|
||||
|
||||
open class Simple(
|
||||
protected val listener: (new: ItemStack, old: ItemStack) -> Unit,
|
||||
protected val maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE,
|
||||
) : SlottedContainer.SlotProvider {
|
||||
protected open inner class Instance(container: SlottedContainer, slot: Int) : ContainerSlot(container, slot) {
|
||||
class Simple(
|
||||
private val listener: (new: ItemStack, old: ItemStack) -> Unit = { _, _ -> },
|
||||
private val maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE,
|
||||
private val canAutomationPlaceItem: AutomationPlaceItem<ContainerSlot> = AutomationPlaceItem { _, _ -> true },
|
||||
private val canAutomationTakeItem: AutomationTakeItem<ContainerSlot> = AutomationTakeItem { _, _ -> true },
|
||||
private val modifyAutomationPlaceCount: AutomationModifyPlaceCount<ContainerSlot> = AutomationModifyPlaceCount { _, item -> item.count },
|
||||
private val modifyAutomationExtractionCount: AutomationModifyExtractionCount<ContainerSlot> = AutomationModifyExtractionCount { _, desired -> desired },
|
||||
) : SlottedContainer.SlotProvider<ContainerSlot> {
|
||||
private open inner class Instance(container: SlottedContainer, slot: Int) : ContainerSlot(container, slot) {
|
||||
override val maxStackSize: Int
|
||||
get() = this@Simple.maxStackSize
|
||||
|
||||
@ -121,45 +125,21 @@ open class ContainerSlot(
|
||||
super.notifyChanged(old)
|
||||
listener(item, old)
|
||||
}
|
||||
}
|
||||
|
||||
override fun create(container: SlottedContainer, index: Int): ContainerSlot {
|
||||
return Instance(container, index)
|
||||
}
|
||||
}
|
||||
|
||||
open class Filtered(
|
||||
listener: (new: ItemStack, old: ItemStack) -> Unit,
|
||||
maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE,
|
||||
) : Simple(listener, maxStackSize) {
|
||||
protected open inner class Instance(container: SlottedContainer, slot: Int) : Simple.Instance(container, slot),
|
||||
IFilteredAutomatedContainerSlot {
|
||||
override var filter: Item? = null
|
||||
set(value) {
|
||||
if (field !== value) {
|
||||
field = value
|
||||
container.notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
super.clear()
|
||||
filter = null
|
||||
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
|
||||
return super.canAutomationPlaceItem(itemStack) && canAutomationPlaceItem.canAutomationPlaceItem(this, itemStack)
|
||||
}
|
||||
|
||||
override fun serializeNBT(provider: HolderLookup.Provider): CompoundTag {
|
||||
return super.serializeNBT(provider).also {
|
||||
if (filter != null)
|
||||
it["filter"] = filter!!.registryName!!.toString()
|
||||
}
|
||||
override fun canAutomationTakeItem(desired: Int): Boolean {
|
||||
return super.canAutomationTakeItem(desired) && canAutomationTakeItem.canAutomationTakeItem(this, desired)
|
||||
}
|
||||
|
||||
override fun deserializeNBT(provider: HolderLookup.Provider, nbt: CompoundTag) {
|
||||
super.deserializeNBT(provider, nbt)
|
||||
override fun modifyAutomationPlaceCount(itemStack: ItemStack): Int {
|
||||
return modifyAutomationPlaceCount.modifyAutomationPlaceCount(this, itemStack)
|
||||
}
|
||||
|
||||
if ("filter" in nbt) {
|
||||
filter = BuiltInRegistries.ITEM.get(ResourceLocation.parse(nbt.getString("filter")))
|
||||
}
|
||||
override fun modifyAutomationExtractionCount(desired: Int): Int {
|
||||
return modifyAutomationExtractionCount.modifyAutomationExtractionCount(this, desired)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,83 @@
|
||||
package ru.dbotthepony.mc.otm.container.slotted
|
||||
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.container.IFilteredAutomatedContainerSlot
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
|
||||
open class FilteredContainerSlot(
|
||||
container: SlottedContainer,
|
||||
slot: Int
|
||||
) : ContainerSlot(container, slot), IFilteredAutomatedContainerSlot {
|
||||
override var filter: Item? = null
|
||||
set(value) {
|
||||
if (field !== value) {
|
||||
field = value
|
||||
container.notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
super.clear()
|
||||
filter = null
|
||||
}
|
||||
|
||||
override fun serializeNBT(provider: HolderLookup.Provider): CompoundTag {
|
||||
return super.serializeNBT(provider).also {
|
||||
if (filter != null)
|
||||
it["filter"] = filter!!.registryName!!.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserializeNBT(provider: HolderLookup.Provider, nbt: CompoundTag) {
|
||||
super.deserializeNBT(provider, nbt)
|
||||
|
||||
if ("filter" in nbt) {
|
||||
filter = BuiltInRegistries.ITEM.get(ResourceLocation.parse(nbt.getString("filter")))
|
||||
}
|
||||
}
|
||||
|
||||
class Simple(
|
||||
private val listener: (new: ItemStack, old: ItemStack) -> Unit = { _, _ -> },
|
||||
private val maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE,
|
||||
private val canAutomationPlaceItem: AutomationPlaceItem<FilteredContainerSlot> = AutomationPlaceItem { _, _ -> true },
|
||||
private val canAutomationTakeItem: AutomationTakeItem<FilteredContainerSlot> = AutomationTakeItem { _, _ -> true },
|
||||
private val modifyAutomationPlaceCount: AutomationModifyPlaceCount<FilteredContainerSlot> = AutomationModifyPlaceCount { _, item -> item.count },
|
||||
private val modifyAutomationExtractionCount: AutomationModifyExtractionCount<FilteredContainerSlot> = AutomationModifyExtractionCount { _, desired -> desired },
|
||||
) : SlottedContainer.SlotProvider<FilteredContainerSlot> {
|
||||
private open inner class Instance(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) {
|
||||
override val maxStackSize: Int
|
||||
get() = this@Simple.maxStackSize
|
||||
|
||||
override fun notifyChanged(old: ItemStack) {
|
||||
super.notifyChanged(old)
|
||||
listener(item, old)
|
||||
}
|
||||
|
||||
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
|
||||
return super.canAutomationPlaceItem(itemStack) && canAutomationPlaceItem.canAutomationPlaceItem(this, itemStack)
|
||||
}
|
||||
|
||||
override fun canAutomationTakeItem(desired: Int): Boolean {
|
||||
return super.canAutomationTakeItem(desired) && canAutomationTakeItem.canAutomationTakeItem(this, desired)
|
||||
}
|
||||
|
||||
override fun modifyAutomationPlaceCount(itemStack: ItemStack): Int {
|
||||
return modifyAutomationPlaceCount.modifyAutomationPlaceCount(this, itemStack)
|
||||
}
|
||||
|
||||
override fun modifyAutomationExtractionCount(desired: Int): Int {
|
||||
return modifyAutomationExtractionCount.modifyAutomationExtractionCount(this, desired)
|
||||
}
|
||||
}
|
||||
|
||||
override fun create(container: SlottedContainer, index: Int): FilteredContainerSlot {
|
||||
return Instance(container, index)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package ru.dbotthepony.mc.otm.container.slotted
|
||||
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
fun interface AutomationPlaceItem<S : ContainerSlot> {
|
||||
fun canAutomationPlaceItem(self: S, itemStack: ItemStack): Boolean
|
||||
}
|
||||
|
||||
fun interface AutomationTakeItem<S : ContainerSlot> {
|
||||
fun canAutomationTakeItem(self: S, desired: Int): Boolean
|
||||
}
|
||||
|
||||
fun interface AutomationModifyPlaceCount<S : ContainerSlot> {
|
||||
fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int
|
||||
}
|
||||
|
||||
fun interface AutomationModifyExtractionCount<S : ContainerSlot> {
|
||||
fun modifyAutomationExtractionCount(self: S, desired: Int): Int
|
||||
}
|
@ -2,6 +2,11 @@ package ru.dbotthepony.mc.otm.container.slotted
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntList
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
@ -14,24 +19,106 @@ import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.neoforged.neoforge.common.util.INBTSerializable
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.kommons.util.Either
|
||||
import ru.dbotthepony.mc.otm.container.IAutomatedContainer
|
||||
import ru.dbotthepony.mc.otm.container.IAutomatedContainerSlot
|
||||
import ru.dbotthepony.mc.otm.container.IFilteredContainerSlot
|
||||
import ru.dbotthepony.mc.otm.container.balance
|
||||
import ru.dbotthepony.mc.otm.container.slotRange
|
||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||
import java.util.function.Predicate
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class SlottedContainer(
|
||||
slots: Collection<SlotProvider>,
|
||||
slots: Collection<MarkedSlotProvider<*>>,
|
||||
private val stillValid: Predicate<Player>,
|
||||
private val globalChangeListeners: Array<Runnable>
|
||||
) : IAutomatedContainer, INBTSerializable<Tag> {
|
||||
interface ISlotGroup<T : ContainerSlot> : List<T> {
|
||||
/**
|
||||
* @see IAutomatedContainer.addItem
|
||||
*/
|
||||
fun addItem(stack: ItemStack, simulate: Boolean, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): ItemStack
|
||||
|
||||
/**
|
||||
* @see IAutomatedContainer.consumeItem
|
||||
*/
|
||||
fun consumeItem(stack: ItemStack, simulate: Boolean, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean
|
||||
|
||||
/**
|
||||
* @see IAutomatedContainer.fullyAddItem
|
||||
*/
|
||||
fun fullyAddItem(stack: ItemStack, onlyIntoExisting: Boolean = false, popTime: Int? = null, ignoreFilters: Boolean = false): Boolean
|
||||
|
||||
fun balance()
|
||||
}
|
||||
|
||||
private inner class SlotGroup<T : ContainerSlot> : ISlotGroup<T>, AbstractList<T>() {
|
||||
val slots = IntArrayList()
|
||||
|
||||
override val size: Int
|
||||
get() = slots.size
|
||||
|
||||
override fun get(index: Int): T {
|
||||
return this@SlottedContainer.slots[slots.getInt(index)] as T
|
||||
}
|
||||
|
||||
override fun addItem(stack: ItemStack, simulate: Boolean, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): ItemStack {
|
||||
return this@SlottedContainer.addItem(stack, simulate, slots, onlyIntoExisting, popTime, ignoreFilters)
|
||||
}
|
||||
|
||||
override fun consumeItem(stack: ItemStack, simulate: Boolean, onlyIntoExisting: Boolean, popTime: Int?, ignoreFilters: Boolean): Boolean {
|
||||
return this@SlottedContainer.consumeItem(stack, simulate, slots, onlyIntoExisting, popTime, ignoreFilters)
|
||||
}
|
||||
|
||||
override fun fullyAddItem(
|
||||
stack: ItemStack,
|
||||
onlyIntoExisting: Boolean,
|
||||
popTime: Int?,
|
||||
ignoreFilters: Boolean
|
||||
): Boolean {
|
||||
return this@SlottedContainer.fullyAddItem(stack, slots, onlyIntoExisting, popTime, ignoreFilters)
|
||||
}
|
||||
|
||||
override fun balance() {
|
||||
return this@SlottedContainer.balance(slots)
|
||||
}
|
||||
}
|
||||
|
||||
class SingleTag<T : ContainerSlot>(val clazz: KClass<T>) {
|
||||
override fun toString(): String {
|
||||
return "SlottedContainer.SingleTag[${System.identityHashCode(this).toString(16)}@${clazz.qualifiedName}]"
|
||||
}
|
||||
}
|
||||
|
||||
class MultiTag<T : ContainerSlot>(val clazz: KClass<T>) {
|
||||
override fun toString(): String {
|
||||
return "SlottedContainer.MultiTag[${System.identityHashCode(this).toString(16)}@${clazz.qualifiedName}]"
|
||||
}
|
||||
}
|
||||
|
||||
private val sets = HashMap<MultiTag<*>, SlotGroup<*>>()
|
||||
private val singular = HashMap<SingleTag<*>, ContainerSlot>()
|
||||
private val slots: Array<ContainerSlot>
|
||||
|
||||
init {
|
||||
val itr = slots.iterator()
|
||||
this.slots = Array(slots.size) { itr.next().create(this, it) }
|
||||
this.slots = Array(slots.size) { index ->
|
||||
val (mark, provider) = itr.next()
|
||||
val slot = provider.create(this, index)
|
||||
mark?.map({ require(singular.put(it, slot) == null) { "Duplicate Slot tag: $it" } }, { sets.computeIfAbsent(it) { SlotGroup<ContainerSlot>() }.slots.add(index) })
|
||||
slot
|
||||
}
|
||||
}
|
||||
|
||||
operator fun <T : ContainerSlot> get(tag: MultiTag<T>): ISlotGroup<T> {
|
||||
return sets[tag] as ISlotGroup<T>? ?: throw NoSuchElementException("Container does not contain $tag")
|
||||
}
|
||||
|
||||
operator fun <T : ContainerSlot> get(tag: SingleTag<T>): T {
|
||||
return singular[tag] as T? ?: throw NoSuchElementException("Container does not contain $tag")
|
||||
}
|
||||
|
||||
override val hasFilterableSlots: Boolean = this.slots.any { it is IFilteredContainerSlot }
|
||||
@ -218,23 +305,44 @@ class SlottedContainer(
|
||||
notifyChanged()
|
||||
}
|
||||
|
||||
fun interface SlotProvider {
|
||||
fun create(container: SlottedContainer, index: Int): ContainerSlot
|
||||
fun interface SlotProvider<T : ContainerSlot> {
|
||||
fun create(container: SlottedContainer, index: Int): T
|
||||
}
|
||||
|
||||
data class MarkedSlotProvider<T : ContainerSlot>(val mark: Either<SingleTag<T>, MultiTag<T>>?, val provider: SlotProvider<T>)
|
||||
|
||||
class Builder {
|
||||
private val slots = ArrayList<SlotProvider>()
|
||||
private val slots = ArrayList<MarkedSlotProvider<*>>()
|
||||
private var stillValid = Predicate<Player> { true }
|
||||
private val globalChangeListeners = ArrayList<Runnable>()
|
||||
private val seenSingleTags = ObjectOpenHashSet<SingleTag<*>>()
|
||||
|
||||
fun add(slot: SlotProvider): Builder {
|
||||
slots.add(slot)
|
||||
fun add(slot: SlotProvider<*>): Builder {
|
||||
slots.add(MarkedSlotProvider(null, slot))
|
||||
return this
|
||||
}
|
||||
|
||||
fun add(amount: Int, provider: SlotProvider): Builder {
|
||||
fun <T : ContainerSlot> add(tag: SingleTag<T>, slot: SlotProvider<T>): Builder {
|
||||
require(seenSingleTags.add(tag)) { "Duplicate slot tag: $tag" }
|
||||
slots.add(MarkedSlotProvider(Either.left(tag), slot))
|
||||
return this
|
||||
}
|
||||
|
||||
fun <T : ContainerSlot> add(tag: MultiTag<T>, slot: SlotProvider<T>): Builder {
|
||||
slots.add(MarkedSlotProvider(Either.right(tag), slot))
|
||||
return this
|
||||
}
|
||||
|
||||
fun add(amount: Int, provider: SlotProvider<*>): Builder {
|
||||
for (i in 0 until amount)
|
||||
slots.add(provider)
|
||||
slots.add(MarkedSlotProvider(null, provider))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun <T : ContainerSlot> add(amount: Int, tag: MultiTag<T>, provider: SlotProvider<T>): Builder {
|
||||
for (i in 0 until amount)
|
||||
slots.add(MarkedSlotProvider(Either.right(tag), provider))
|
||||
|
||||
return this
|
||||
}
|
||||
@ -262,8 +370,37 @@ class SlottedContainer(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
|
||||
inline fun <reified T : ContainerSlot> tag(): SingleTag<T> {
|
||||
return SingleTag(T::class)
|
||||
}
|
||||
|
||||
inline fun <reified T : ContainerSlot> tagList(): MultiTag<T> {
|
||||
return MultiTag(T::class)
|
||||
}
|
||||
|
||||
fun simple(size: Int): SlottedContainer {
|
||||
return Builder().add(size, ::ContainerSlot).build()
|
||||
}
|
||||
|
||||
fun simple(size: Int, listener: Runnable): SlottedContainer {
|
||||
return Builder()
|
||||
.add(size, ::ContainerSlot)
|
||||
.onChanged(listener)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun filtered(size: Int): SlottedContainer {
|
||||
return Builder().add(size, ::FilteredContainerSlot).build()
|
||||
}
|
||||
|
||||
fun filtered(size: Int, listener: Runnable): SlottedContainer {
|
||||
return Builder()
|
||||
.add(size, ::FilteredContainerSlot)
|
||||
.onChanged(listener)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user