@@ -33,8 +33,8 @@ import kotlin.reflect.KClass
3333 * [StackSelection] is a class that holds a predicate for matching [ItemStack]s.
3434 */
3535class StackSelection {
36- var selector: (ItemStack ) -> Boolean = { true }
37- var comparator: Comparator <ItemStack >? = null
36+ var selector: (ItemStack ) -> Boolean = EVERYTHING
37+ var comparator: Comparator <ItemStack > = NO_COMPARE
3838 var count: Int = DEFAULT_AMOUNT
3939 var inShulkerBox: Boolean = false
4040
@@ -48,25 +48,54 @@ class StackSelection {
4848 val optimalStack: ItemStack ?
4949 get() = itemStack ? : item?.let { ItemStack (it, count) }
5050
51+ /* *
52+ * Filters the given [stacks], sorts them with the [comparator] and returns the first value
53+ */
54+ fun bestItemMatch (stacks : List <ItemStack >): ItemStack ? = stacks.minWithOrNull(comparator)
55+
5156 fun filterStack (stack : ItemStack ) =
5257 if (inShulkerBox) stack.shulkerBoxContents.any { selector(it) }
5358 else selector(stack)
5459
55- fun filterSlot (slot : Slot ) = filterStack(slot.stack)
60+ fun filterSlot (slot : Slot ): Boolean = filterStack(slot.stack)
5661
5762 fun filterStacks (stacks : List <ItemStack >): List <ItemStack > =
58- stacks.filter(::filterStack).let { filteredStacks ->
59- comparator?.run {
60- filteredStacks.sortedWith(this )
61- } ? : filteredStacks
62- }
63+ stacks.filter(::filterStack).sortedWith(comparator)
6364
6465 fun filterSlots (slots : List <Slot >): List <Slot > =
65- slots.filter(::filterSlot).let { filteredSlots ->
66- comparator?.run {
67- filteredSlots.sortedWith { slot, slot2 -> compare(slot.stack, slot2.stack) }
68- } ? : filteredSlots
69- }
66+ slots.filter(::filterSlot).sortedWith { slot, slot2 -> comparator.compare(slot.stack, slot2.stack) }
67+
68+ @StackSelectionDsl
69+ fun <R : Comparable <R >> sortBy (selector : (ItemStack ) -> R ? ): StackSelection = apply {
70+ comparator = compareBy(selector)
71+ }
72+
73+ @StackSelectionDsl
74+ fun <R : Comparable <R >> sortByDescending (selector : (ItemStack ) -> R ? ): StackSelection = apply {
75+ comparator = compareByDescending(selector)
76+ }
77+
78+ @StackSelectionDsl
79+ fun <R : Comparable <R >> thenBy (selector : (ItemStack ) -> R ? ): StackSelection = apply {
80+ check(comparator != NO_COMPARE ) { " No comparator specified" }
81+ comparator = comparator.thenBy(selector)
82+ }
83+
84+ @StackSelectionDsl
85+ fun <R : Comparable <R >> thenByDescending (selector : (ItemStack ) -> R ? ): StackSelection = apply {
86+ check(comparator != NO_COMPARE ) { " No comparator specified" }
87+ comparator = comparator.thenByDescending(selector)
88+ }
89+
90+ @StackSelectionDsl
91+ fun sortWith (custom : Comparator <ItemStack >): StackSelection = apply {
92+ comparator = custom
93+ }
94+
95+ @StackSelectionDsl
96+ fun reversed (): StackSelection = apply {
97+ comparator = comparator.reversed()
98+ }
7099
71100 /* *
72101 * returns a function that finds a shulker box to push matching items into.
@@ -235,14 +264,12 @@ class StackSelection {
235264 annotation class StackSelectionDsl
236265
237266 const val DEFAULT_AMOUNT = 1
238- val FULL_SHULKERS : (ItemStack ) -> Boolean = { stack ->
239- stack.shulkerBoxContents.none { it.isEmpty }
240- }
241- val EMPTY_SHULKERS : (ItemStack ) -> Boolean = { stack ->
242- stack.shulkerBoxContents.all { it.isEmpty }
243- }
267+
268+ val FULL_SHULKERS : (ItemStack ) -> Boolean = { stack -> stack.shulkerBoxContents.none { it.isEmpty } }
269+ val EMPTY_SHULKERS : (ItemStack ) -> Boolean = { stack -> stack.shulkerBoxContents.all { it.isEmpty } }
244270 val EVERYTHING : (ItemStack ) -> Boolean = { true }
245271 val NOTHING : (ItemStack ) -> Boolean = { false }
272+ val NO_COMPARE : Comparator <ItemStack > = Comparator { _, _ -> 0 }
246273
247274 @StackSelectionDsl
248275 fun Item.select () = selectStack { isItem(this @select) }
@@ -261,29 +288,12 @@ class StackSelection {
261288 @StackSelectionDsl
262289 fun ((ItemStack ) -> Boolean ).select() = selectStack { this @select }
263290
264- /* *
265- * Builds a [StackSelection] with the given parameters.
266- * @param count The count of items to be selected.
267- * @param block The predicate to be used to select the items.
268- * @return A [StackSelection] with the given parameters.
269- */
270- @StackSelectionDsl
271- fun selectStack (
272- count : Int = DEFAULT_AMOUNT ,
273- inShulkerBox : Boolean = false,
274- block : StackSelection .() -> (ItemStack ) -> Boolean ,
275- ) = StackSelection ().apply {
276- selector = block()
277- this .count = count
278- this .inShulkerBox = inShulkerBox
279- }
280-
281291 @StackSelectionDsl
282292 fun selectStack (
283293 count : Int = DEFAULT_AMOUNT ,
284294 inShulkerBox : Boolean = false,
285- sorter : Comparator <ItemStack >? = null ,
286- block : StackSelection .() -> (ItemStack ) -> Boolean ,
295+ sorter : Comparator <ItemStack > = NO_COMPARE ,
296+ block : StackSelection .() -> (ItemStack ) -> Boolean = { EVERYTHING } ,
287297 ) = StackSelection ().apply {
288298 selector = block()
289299 comparator = sorter
0 commit comments