diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/Action.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/Action.kt index 085efc1d..8c2aab05 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/Action.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/Action.kt @@ -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() diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroup.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroup.kt index 7610f4aa..4f1309ea 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroup.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroup.kt @@ -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 @@ -17,23 +19,25 @@ class ActionEntry( val conditions: List?, val register: String?, val onFail: ActionGroup?, + val loop: Expression>?, ) @Serializable(with = ActionGroup.Serializer::class) class ActionGroup( val actions: List, -) { - 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 @@ -41,6 +45,17 @@ class ActionGroup( } } + 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, ActionGroup>( serialName = "geary:action_group", inner = ListSerializer( @@ -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() } ) ) ) @@ -60,12 +76,14 @@ class ActionGroup( var action: Action? = null var condition: List? = null var register: String? = null + var loop: Expression>? = 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) } @@ -75,7 +93,8 @@ class ActionGroup( action = action!!, conditions = condition, register = register, - onFail = onFail + onFail = onFail, + loop = loop ) } ActionGroup(actions) diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroupContext.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroupContext.kt index cee8faf2..5f070db4 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroupContext.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/ActionGroupContext.kt @@ -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 + } } diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/EntityObservers.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/EntityObservers.kt index 6bb5574b..d5d0d557 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/EntityObservers.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/EntityObservers.kt @@ -54,3 +54,7 @@ class ActionOnFail(val action: ActionGroup) { transform = ::ActionOnFail ) } + +@JvmInline +@Serializable +value class ActionLoop(val expression: String) diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/ParseEntityObservers.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/ParseEntityObservers.kt index d50082bc..67870bdf 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/ParseEntityObservers.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/ParseEntityObservers.kt @@ -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 diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/Passive.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/Passive.kt index 4535e0e5..2d9b80d7 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/Passive.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/event_binds/Passive.kt @@ -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 diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/EntityExpression.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/EntityExpression.kt index 7c05216b..961c0d98 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/EntityExpression.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/EntityExpression.kt @@ -10,9 +10,9 @@ import kotlin.jvm.JvmInline @Serializable value class EntityExpression( val expression: String, -) /*: Expression()*/ { - fun evaluate(context: ActionGroupContext): GearyEntity { +) : Expression { + override fun evaluate(context: ActionGroupContext): GearyEntity { return if (expression == "parent") context.entity.parent!! - else TODO() + else Expression.Evaluate(expression).evaluate(context) } } diff --git a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/Expression.kt b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/Expression.kt index 0fb32cc4..29b78c9c 100644 --- a/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/Expression.kt +++ b/addons/geary-actions/src/commonMain/kotlin/com/mineinabyss/geary/actions/expressions/Expression.kt @@ -59,3 +59,5 @@ sealed interface Expression { } } } + +fun expr(value: T) = Expression.Fixed(value)