Skip to content

Commit

Permalink
Optimised trigger dispatching, reworked counters
Browse files Browse the repository at this point in the history
  • Loading branch information
WillFP committed Jul 13, 2023
1 parent 5f61c8b commit c7dc332
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 87 deletions.
11 changes: 8 additions & 3 deletions core/src/main/kotlin/com/willfp/libreforge/counters/Counter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.willfp.libreforge.counters
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.libreforge.ConfigurableElement
import com.willfp.libreforge.conditions.ConditionList
import com.willfp.libreforge.counters.bind.BoundCounters
import com.willfp.libreforge.effects.arguments.EffectArgumentList
import com.willfp.libreforge.filters.FilterList
import com.willfp.libreforge.triggers.PotentiallyTriggerable
import com.willfp.libreforge.triggers.Trigger
import java.util.Objects
import java.util.UUID
Expand All @@ -16,23 +18,26 @@ class Counter internal constructor(
override val config: Config,
val arguments: EffectArgumentList,
val multiplierExpression: String
) : ConfigurableElement {
) : ConfigurableElement, PotentiallyTriggerable {
override val uuid: UUID = UUID.randomUUID()

/**
* Bind this counter to an [accumulator].
*/
fun bind(accumulator: Accumulator) {
bindCounter(this, accumulator)
BoundCounters.bind(this, accumulator)
}

/**
* Unbind this counter from all accumulators.
*/
fun unbind() {
unbindCounter(this)
BoundCounters.unbind(this)
}

override fun canBeTriggeredBy(trigger: Trigger) =
this.trigger == trigger

override fun equals(other: Any?): Boolean {
if (other !is Counter) {
return false
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.willfp.libreforge.counters.bind

import com.willfp.eco.core.placeholder.context.placeholderContext
import com.willfp.eco.util.evaluateExpression
import com.willfp.libreforge.counters.Accumulator
import com.willfp.libreforge.counters.Counter
import com.willfp.libreforge.triggers.DispatchedTrigger

/*
The current binding system feels a bit messy, so it's all marked as internal since
I'll probably change it later, and I don't want someone to hook into a system
that may break between updates.
*/

internal data class BoundCounter(
val counter: Counter,
val accumulator: Accumulator
) {
fun accept(trigger: DispatchedTrigger) {
val data = trigger.data

val player = trigger.player
val value = data.value

if (!counter.canBeTriggeredBy(trigger.trigger)) {
return
}

if (!counter.conditions.areMet(player, data.holder)) {
return
}

if (!counter.filters.isMet(data)) {
return
}

val config = counter.config

// Inject placeholders, totally not stolen from ElementLike
listOf(counter.filters, counter.conditions)
.flatten()
.map { it.config }
.plusElement(config)
.forEach { it.addInjectablePlaceholder(trigger.placeholders) }

val (argumentsMet, met, notMet) = counter.arguments.checkMet(counter, trigger)

if (!argumentsMet) {
notMet.forEach { it.ifNotMet(counter, trigger) }
return
}

val multiplier = evaluateExpression(
counter.multiplierExpression,
placeholderContext(
player = player,
injectable = config
)
)

met.forEach { it.ifMet(counter, trigger) }

accumulator.accept(player, value * multiplier)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.willfp.libreforge.counters.bind

import com.willfp.eco.core.map.listMap
import com.willfp.libreforge.counters.Accumulator
import com.willfp.libreforge.counters.Counter

internal object BoundCounters {
private val bindings = listMap<Counter, BoundCounter>()

fun bind(counter: Counter, accumulator: Accumulator) {
bindings[counter] += BoundCounter(counter, accumulator)
}

fun unbind(counter: Counter) {
bindings.remove(counter)
}

fun values(): List<Counter> =
bindings.keys.toList()

val Counter.bindings: List<BoundCounter>
get() = BoundCounters.bindings[this].toList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.willfp.libreforge.effects.arguments.EffectArgumentList
import com.willfp.libreforge.filters.FilterList
import com.willfp.libreforge.mutators.MutatorList
import com.willfp.libreforge.triggers.DispatchedTrigger
import com.willfp.libreforge.triggers.PotentiallyTriggerable
import com.willfp.libreforge.triggers.Trigger
import org.bukkit.entity.Player
import java.util.Objects
Expand All @@ -26,7 +27,7 @@ class EffectBlock internal constructor(
override val mutators: MutatorList,
override val filters: FilterList,
override val isElementOwnChain: Boolean
) : ElementLike() {
) : ElementLike(), PotentiallyTriggerable {
override val supportsDelay = effects.all { it.supportsDelay }

val weight = effects.weight
Expand All @@ -51,7 +52,7 @@ class EffectBlock internal constructor(
}
}

fun canBeTriggeredBy(trigger: Trigger) =
override fun canBeTriggeredBy(trigger: Trigger) =
trigger in triggers

override fun doTrigger(trigger: DispatchedTrigger) =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.willfp.libreforge.triggers

interface PotentiallyTriggerable {
/**
* Check if this can be triggered by some [trigger].
*/
fun canBeTriggeredBy(trigger: Trigger): Boolean
}
18 changes: 16 additions & 2 deletions core/src/main/kotlin/com/willfp/libreforge/triggers/Trigger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.willfp.libreforge.triggers

import com.willfp.eco.core.registry.KRegistrable
import com.willfp.libreforge.ProvidedHolder
import com.willfp.libreforge.counters.bind.BoundCounters
import com.willfp.libreforge.counters.bind.BoundCounters.bindings
import com.willfp.libreforge.generatePlaceholders
import com.willfp.libreforge.getProvidedActiveEffects
import com.willfp.libreforge.plugin
Expand Down Expand Up @@ -42,16 +44,23 @@ abstract class Trigger(
) {
val dispatch = plugin.dispatchedTriggerFactory.create(player, this, data) ?: return

val effects = forceHolders?.getProvidedActiveEffects(player) ?: player.providedActiveEffects

// Prevent dispatching useless triggers
val potentialDestinations = effects.flatMap { it.effects } + BoundCounters.values()
if (potentialDestinations.none { it.canBeTriggeredBy(this) }) {
return
}

dispatch.generatePlaceholders(data)

val dispatchEvent = TriggerDispatchEvent(player, dispatch)
Bukkit.getPluginManager().callEvent(dispatchEvent)

if (dispatchEvent.isCancelled) {
return
}

val effects = forceHolders?.getProvidedActiveEffects(player) ?: player.providedActiveEffects

for ((holder, blocks) in effects) {
// Avoid generating placeholders for nothing
if (blocks.none { it.canBeTriggeredBy(this) }) {
Expand All @@ -69,6 +78,11 @@ abstract class Trigger(
block.tryTrigger(dispatchWithHolder)
}
}

// Probably a better way to work with counters, but this works for now.
for (counter in BoundCounters.values()) {
counter.bindings.forEach { it.accept(dispatch) }
}
}

final override fun onRegister() {
Expand Down

0 comments on commit c7dc332

Please sign in to comment.