Skip to content

Commit

Permalink
feat(actions): Loop support
Browse files Browse the repository at this point in the history
  • Loading branch information
0ffz committed Jul 31, 2024
1 parent 4d8c730 commit 3ad7521
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.mineinabyss.geary.actions

import kotlin.jvm.JvmName

interface Action {
fun ActionGroupContext.execute(): Any?

}

fun Action.execute(context: ActionGroupContext) = context.execute()
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.mineinabyss.geary.actions

import com.mineinabyss.geary.actions.actions.EmitEventAction
import com.mineinabyss.geary.actions.actions.EnsureAction
import com.mineinabyss.geary.actions.event_binds.ActionLoop
import com.mineinabyss.geary.actions.event_binds.ActionOnFail
import com.mineinabyss.geary.actions.event_binds.ActionRegister
import com.mineinabyss.geary.actions.event_binds.ActionWhen
import com.mineinabyss.geary.actions.expressions.Expression
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
Expand All @@ -17,30 +19,43 @@ class ActionEntry(
val conditions: List<EnsureAction>?,
val register: String?,
val onFail: ActionGroup?,
val loop: Expression<List<Any>>?,
)

@Serializable(with = ActionGroup.Serializer::class)
class ActionGroup(
val actions: List<ActionEntry>,
) {
fun execute(context: ActionGroupContext) {
): Action {
override fun ActionGroupContext.execute() {
val context = this
actions.forEach { entry ->
try {
entry.conditions?.forEach { condition ->
with(condition) { context.execute() }
}

val returned = with(entry.action) { context.execute() }

if (entry.register != null)
context.register(entry.register, returned)
if (entry.loop != null) {
entry.loop.evaluate(context).forEach { loopEntry ->
val subcontext = context.copy()
subcontext.register("item", loopEntry)
executeEntry(subcontext, entry)
}
} else
executeEntry(context, entry)
} catch (e: ActionsCancelledException) {
entry.onFail?.execute(context)
return
}
}
}

private fun executeEntry(context: ActionGroupContext, entry: ActionEntry) {
entry.conditions?.forEach { condition ->
with(condition) { context.execute() }
}

val returned = with(entry.action) { context.execute() }

if (entry.register != null)
context.register(entry.register, returned)
}

class Serializer : InnerSerializer<List<SerializedComponents>, ActionGroup>(
serialName = "geary:action_group",
inner = ListSerializer(
Expand All @@ -49,7 +64,8 @@ class ActionGroup(
customKeys = mapOf(
"when" to { ActionWhen.serializer() },
"register" to { ActionRegister.serializer() },
"onFail" to { ActionOnFail.serializer() }
"onFail" to { ActionOnFail.serializer() },
"loop" to { ActionLoop.serializer() }
)
)
)
Expand All @@ -60,12 +76,14 @@ class ActionGroup(
var action: Action? = null
var condition: List<EnsureAction>? = null
var register: String? = null
var loop: Expression<List<Any>>? = null
var onFail: ActionGroup? = null
components.forEach { comp ->
when {
comp is ActionWhen -> condition = comp.conditions
comp is ActionRegister -> register = comp.register
comp is ActionOnFail -> onFail = comp.action
comp is ActionLoop -> loop = Expression.Evaluate(comp.expression)
action != null -> geary.logger.w { "Multiple actions defined in one block!" }
else -> action = EmitEventAction.wrapIfNotAction(comp)
}
Expand All @@ -75,7 +93,8 @@ class ActionGroup(
action = action!!,
conditions = condition,
register = register,
onFail = onFail
onFail = onFail,
loop = loop
)
}
ActionGroup(actions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ class ActionGroupContext(
fun register(name: String, value: Any?) {
environment[name] = value
}

fun copy(): ActionGroupContext {
val newContext = ActionGroupContext(entity)
newContext.environment.putAll(environment)
return newContext
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ class ActionOnFail(val action: ActionGroup) {
transform = ::ActionOnFail
)
}

@JvmInline
@Serializable
value class ActionLoop(val expression: String)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mineinabyss.geary.actions.event_binds

import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.actions.execute
import com.mineinabyss.geary.datatypes.EntityType
import com.mineinabyss.geary.modules.GearyModule
import com.mineinabyss.geary.observers.entity.observe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.mineinabyss.geary.actions.event_binds;

import com.mineinabyss.geary.actions.ActionGroup
import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.actions.execute
import com.mineinabyss.geary.actions.serializers.DurationSerializer
import com.mineinabyss.geary.helpers.entity
import com.mineinabyss.geary.helpers.fastForEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import kotlin.jvm.JvmInline
@Serializable
value class EntityExpression(
val expression: String,
) /*: Expression<GearyEntity>()*/ {
fun evaluate(context: ActionGroupContext): GearyEntity {
) : Expression<GearyEntity> {
override fun evaluate(context: ActionGroupContext): GearyEntity {
return if (expression == "parent") context.entity.parent!!
else TODO()
else Expression.Evaluate<GearyEntity>(expression).evaluate(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ sealed interface Expression<T> {
}
}
}

fun <T> expr(value: T) = Expression.Fixed(value)

0 comments on commit 3ad7521

Please sign in to comment.