Skip to content

Commit

Permalink
Added new class RecipeCache.kt
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiiragi283 committed Dec 16, 2024
1 parent 416f93b commit 7f86702
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
21 changes: 13 additions & 8 deletions src/main/kotlin/dev/robustum/core/extensions/CodecExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ import java.util.function.Function

// Codec //

/**
* 指定された[validator]で検証した[Codec]を返します。
* @param A 値のクラス
* @param validator 値を[DataResult]で評価する。
* @return [validator]で評価された[Codec]
*/
fun <A : Any> Codec<A>.validate(validator: (A) -> DataResult<A>): Codec<A> = flatXmap(validator, validator)

/**
* 指定された[getter]で遅延評価された[Codec]を返します。
* @param A 値のクラス
Expand All @@ -34,6 +26,19 @@ fun <A : Any> lazyCodec(getter: () -> Codec<A>): Codec<A> = object : Codec<A> {
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<A, T>> = getter().decode(ops, input)
}

fun <A : Any> alternativeCodec(first: Codec<A>, second: Codec<A>): Codec<A> = Codec.either(first, second).xmap(
{ either: Either<A, A> -> either.map(Function.identity(), Function.identity()) },
Either<A, A>::left,
)

/**
* 指定された[validator]で検証した[Codec]を返します。
* @param A 値のクラス
* @param validator 値を[DataResult]で評価する。
* @return [validator]で評価された[Codec]
*/
fun <A : Any> Codec<A>.validate(validator: (A) -> DataResult<A>): Codec<A> = flatXmap(validator, validator)

fun <A : Any, S : Any> Codec<A>.dispatch(type: Function<S, A>, codec: Function<A, MapCodec<S>>): Codec<S> = dispatch("type", type, codec)

fun <A : Any, S : Any> Codec<A>.dispatch(typeKey: String, type: Function<S, A>, codec: Function<A, MapCodec<S>>): Codec<S> =
Expand Down
53 changes: 53 additions & 0 deletions src/main/kotlin/dev/robustum/core/recipe/RecipeCache.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dev.robustum.core.recipe

import com.mojang.serialization.DataResult
import dev.robustum.core.extensions.filter
import dev.robustum.core.extensions.onErrored
import dev.robustum.core.extensions.onSucceeded
import dev.robustum.core.extensions.toDataResult
import net.minecraft.inventory.Inventory
import net.minecraft.recipe.Recipe
import net.minecraft.recipe.RecipeManager
import net.minecraft.recipe.RecipeType
import net.minecraft.util.Identifier
import net.minecraft.world.World
import java.util.*

/**
* 最後に一致した[Recipe]の[Identifier]を保持するクラスです。
* @param I [Inventory]のクラス
* @param R [Recipe]のクラス
* @param recipeType [Recipe]の種類
*/
class RecipeCache<I : Inventory, R : Recipe<I>>(private val recipeType: RecipeType<R>) {
/**
* 最後にキャッシュされた[Recipe]の[Identifier]です。
*
* 以前のキャッシュがない場合はnullを返します。
*/
private var id: Identifier? = null

/**
* 指定された[inventory]と[world]に一致する最初のレシピを返します。
* @return [id]がある場合は[RecipeManager.get]から,それ以外の場合は[RecipeManager.getFirstMatch]から取得
*/
@Suppress("UNCHECKED_CAST")
fun getFirstMatch(inventory: I, world: World): DataResult<R> = world.recipeManager
.let { recipeManager: RecipeManager ->
when (id) {
null -> recipeManager.getFirstMatch(recipeType, inventory, world)
else -> recipeManager.get(id).flatMap { Optional.ofNullable(it as? R) }
}
}.toDataResult("Failed to find matching recipe!")
.onSucceeded { this.id = it.id }
.onErrored { this.id = null }

/**
* 指定された[inventory]と[world]に一致するすべてのレシピを返します。
* @return [RecipeManager.getAllMatches]の戻り値が空の場合は[DataResult.error],それ以外は[DataResult.success]
*/
fun getAllMatches(inventory: I, world: World): DataResult<List<R>> = world.recipeManager
.getAllMatches(recipeType, inventory, world)
.let(DataResult<List<R>>::success)
.filter(List<R>::isNotEmpty, "Failed to find matching recipes!")
}

0 comments on commit 7f86702

Please sign in to comment.