DefaultBattleMutationInterceptorChain.kt

package io.github.lishangbu.avalon.game.battle.engine.core.runtime.flow

import io.github.lishangbu.avalon.game.battle.engine.core.mutation.BattleMutation

/**
 * 默认 battle mutation 拦截链实现。
 *
 * @property interceptors 按顺序执行的 mutation 拦截器集合。
 */
class DefaultBattleMutationInterceptorChain(
    interceptors: List<BattleMutationInterceptor>,
) : BattleMutationInterceptorChain {
    private val interceptors: List<BattleMutationInterceptor> = interceptors.sortedBy(BattleMutationInterceptor::order)

    /**
     * 过滤一组待提交的 mutation。
     */
    override fun filter(
        snapshot: BattleRuntimeSnapshot,
        selfId: String?,
        targetId: String?,
        sourceId: String?,
        mutations: List<BattleMutation>,
        attachedEffectProcessor: BattleAttachedEffectProcessor,
    ): MutationFilteringResult {
        var currentSnapshot = snapshot
        val allowedMutations = mutableListOf<BattleMutation>()

        mutations.forEach { originalMutation ->
            var mutationSnapshot = currentSnapshot
            var currentMutation: BattleMutation? = originalMutation
            var allowed = true

            interceptors.forEach { interceptor ->
                val mutation = currentMutation
                if (!allowed || mutation == null || !interceptor.supports(mutation)) {
                    return@forEach
                }
                val result =
                    interceptor.intercept(
                        context =
                            BattleMutationInterceptionContext(
                                snapshot = mutationSnapshot,
                                selfId = selfId,
                                targetId = targetId,
                                sourceId = sourceId,
                                mutation = mutation,
                            ),
                        attachedEffectProcessor = attachedEffectProcessor,
                    )
                mutationSnapshot = result.snapshot
                currentMutation = result.mutation
                if (!result.allowed || result.mutation == null) {
                    allowed = false
                }
            }

            currentSnapshot = mutationSnapshot
            if (allowed && currentMutation != null) {
                allowedMutations += currentMutation
            }
        }

        return MutationFilteringResult(
            snapshot = currentSnapshot,
            mutations = allowedMutations,
        )
    }
}