Skip to content

Commit

Permalink
Merge branch 'di-rewrite'
Browse files Browse the repository at this point in the history
# Conflicts:
#	addons/geary-serialization/src/jvmMain/kotlin/com/mineinabyss/geary/serialization/formats/YamlFormat.kt
  • Loading branch information
0ffz committed Oct 26, 2024
2 parents ef3ecae + 0a71387 commit 77159f0
Show file tree
Hide file tree
Showing 156 changed files with 2,083 additions and 1,598 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Read our [Quickstart guide](https://wiki.mineinabyss.com/geary/quickstart/) to s
data class Position(var x: Double, var y: Double)
data class Velocity(var x: Double, var y: Double)

fun GearyModule.updatePositionSystem() = system(query<Position, Velocity>())
fun Geary.updatePositionSystem() = system(query<Position, Velocity>())
.every(interval = 20.milliseconds)
.exec { (position, velocity) ->
// We can access our components like regular variables!
Expand Down
7 changes: 2 additions & 5 deletions addons/geary-actions/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,16 @@ kotlin {
dependencies {
implementation(project(":geary-core"))
implementation(project(":geary-serialization"))

implementation(libs.uuid)
implementation(idofrontLibs.idofront.di)
}
}
val commonTest by getting {
val jvmTest by getting {
dependencies {
implementation(project(":geary-test"))
implementation(kotlin("test"))
implementation(idofrontLibs.kotlinx.coroutines.test)
implementation(idofrontLibs.kotlinx.serialization.kaml)
implementation(idofrontLibs.kotest.assertions)
implementation(idofrontLibs.kotest.property)
implementation(idofrontLibs.idofront.di)
implementation(project(":geary-core"))
implementation(project(":geary-serialization"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ import com.mineinabyss.geary.actions.actions.EmitEventAction
import com.mineinabyss.geary.actions.actions.EnsureAction
import com.mineinabyss.geary.actions.event_binds.*
import com.mineinabyss.geary.actions.expressions.Expression
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.getWorld
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import com.mineinabyss.geary.serialization.serializers.SerializedComponents
import kotlinx.serialization.ContextualSerializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.modules.SerializersModule

class ActionEntry(
val action: Action,
Expand Down Expand Up @@ -64,14 +71,15 @@ class ActionGroup(
customKeys = mapOf(
"when" to { ActionWhen.serializer() },
"register" to { ActionRegister.serializer() },
"onFail" to { ActionOnFail.serializer() },
"onFail" to { ActionOnFail.Serializer() },
"loop" to { ActionLoop.serializer() }
)
)
)
),
inverseTransform = { TODO() },
transform = {
val world = serializersModule.getWorld()
val actions = it.mapNotNull { components ->
var action: Action? = null
var condition: List<EnsureAction>? = null
Expand All @@ -85,11 +93,11 @@ class ActionGroup(
comp is ActionRegister -> register = comp.register
comp is ActionOnFail -> onFail = comp.action
comp is ActionLoop -> loop =
Expression.parseExpression(comp.expression, serializersModule) as Expression<List<Any>>
Expression.parseExpression(world, comp.expression, serializersModule) as Expression<List<Any>>

comp is ActionEnvironment -> environment = comp.environment
action != null -> geary.logger.w { "Multiple actions defined in one block!" }
else -> action = EmitEventAction.wrapIfNotAction(comp)
action != null -> Geary.w { "Multiple actions defined in one block!" }
else -> action = EmitEventAction.wrapIfNotAction(world, comp)
}
}
if (action == null) return@mapNotNull null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ package com.mineinabyss.geary.actions

import com.mineinabyss.geary.actions.event_binds.bindEntityObservers
import com.mineinabyss.geary.actions.event_binds.parsePassive
import com.mineinabyss.geary.addons.dsl.GearyAddonWithDefault
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.addons.dsl.createAddon

class GearyActions {
companion object : GearyAddonWithDefault<GearyActions> {
override fun default() = GearyActions()

override fun GearyActions.install() {
geary.run {
bindEntityObservers()
parsePassive()
}
}
val GearyActions = createAddon("Geary Actions") {
onStart {
bindEntityObservers()
parsePassive()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.mineinabyss.geary.actions.Action
import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.datatypes.ComponentId
import com.mineinabyss.geary.helpers.componentId
import com.mineinabyss.geary.modules.Geary

class EmitEventAction(
val eventId: ComponentId,
Expand All @@ -14,8 +15,8 @@ class EmitEventAction(
}

companion object {
fun from(data: Any) = EmitEventAction(componentId(data::class), data)
fun from(world: Geary, data: Any) = EmitEventAction(world.componentId(data::class), data)

fun wrapIfNotAction(data: Any) = if (data is Action) data else from(data)
fun wrapIfNotAction(world: Geary, data: Any) = if (data is Action) data else from(world, data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ package com.mineinabyss.geary.actions.actions

import com.mineinabyss.geary.actions.*
import com.mineinabyss.geary.helpers.componentId
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.getWorld
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.PolymorphicListAsMapSerializer
import com.mineinabyss.geary.serialization.serializers.SerializedComponents
import kotlinx.serialization.ContextualSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

@Serializable(with = EnsureAction.Serializer::class)
class EnsureAction(
world: Geary,
val conditions: SerializedComponents,
) : Action {
@Transient
private val flat = conditions.map { componentId(it::class) to it }
private val flat = conditions.map { world.componentId(it::class) to it }

override fun ActionGroupContext.execute() {
flat.forEach { (id, data) ->
Expand All @@ -38,10 +42,10 @@ class EnsureAction(
return true
}

object Serializer : InnerSerializer<SerializedComponents, EnsureAction>(
class Serializer : InnerSerializer<SerializedComponents, EnsureAction>(
serialName = "geary:ensure",
inner = PolymorphicListAsMapSerializer.ofComponents(),
inverseTransform = { it.conditions },
transform = { EnsureAction(it) }
transform = { EnsureAction(serializersModule.getWorld(), it) }
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import com.mineinabyss.geary.actions.Action
import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.actions.expressions.Expression
import com.mineinabyss.geary.actions.expressions.InlineExpressionSerializer
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import kotlinx.serialization.Serializable

@Serializable(with = EvalAction.Serializer::class)
class EvalAction(
val expression: Expression<*>,
) : Action {
override fun ActionGroupContext.execute() =
expression.evaluate(this)

object Serializer : InnerSerializer<Expression<*>, EvalAction>(
class Serializer(
world: Geary,
) : InnerSerializer<Expression<*>, EvalAction>(
serialName = "geary:eval",
inner = InlineExpressionSerializer,
inner = InlineExpressionSerializer(world),
inverseTransform = { it.expression },
transform = { EvalAction(it) }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package com.mineinabyss.geary.actions.event_binds
import com.mineinabyss.geary.actions.ActionGroup
import com.mineinabyss.geary.actions.actions.EnsureAction
import com.mineinabyss.geary.actions.expressions.Expression
import com.mineinabyss.geary.datatypes.ComponentId
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.SerializableComponentId
import kotlinx.serialization.Contextual
import kotlinx.serialization.ContextualSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseContextualSerialization
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
Expand All @@ -20,8 +23,8 @@ class EntityObservers(
class Serializer : InnerSerializer<Map<SerializableComponentId, ActionGroup>, EntityObservers>(
serialName = "geary:observe",
inner = MapSerializer(
SerializableComponentId.serializer(),
ActionGroup.serializer()
ContextualSerializer(ComponentId::class),
ActionGroup.Serializer()
),
inverseTransform = { TODO() },
transform = {
Expand Down Expand Up @@ -67,7 +70,7 @@ value class ActionLoop(val expression: String)
class ActionEnvironment(val environment: Map<String, Expression<@Contextual Any>>) {
object Serializer : InnerSerializer<Map<String, Expression<@Contextual Any>>, ActionEnvironment>(
serialName = "geary:with",
inner = MapSerializer(String.serializer(), Expression.serializer(ContextualSerializer(Any::class))),
inner = MapSerializer(String.serializer(), Expression.Serializer(ContextualSerializer(Any::class))),
inverseTransform = ActionEnvironment::environment,
transform = { ActionEnvironment(it) }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ 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.modules.Geary
import com.mineinabyss.geary.modules.observe
import com.mineinabyss.geary.observers.entity.observe
import com.mineinabyss.geary.observers.events.OnSet
import com.mineinabyss.geary.systems.builders.observe
import com.mineinabyss.geary.systems.query.query

fun GearyModule.bindEntityObservers() = observe<OnSet>()
fun Geary.bindEntityObservers() = observe<OnSet>()
.involving(query<EntityObservers>())
.exec { (observers) ->
observers.observers.forEach { observer ->
val actionGroup = observer.actionGroup
entity.observe(observer.event.id).involving(EntityType(observer.involving.map { it.id })).exec {
entity.observe(observer.event).involving(EntityType(observer.involving)).exec {
val context = ActionGroupContext(entity)
actionGroup.execute(context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ 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
import com.mineinabyss.geary.modules.GearyModule
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.modules.observe
import com.mineinabyss.geary.observers.events.OnSet
import com.mineinabyss.geary.serialization.serializers.InnerSerializer
import com.mineinabyss.geary.serialization.serializers.SerializableComponentId
import com.mineinabyss.geary.systems.builders.observe
import com.mineinabyss.geary.systems.builders.system
import com.mineinabyss.geary.systems.query.query
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
Expand All @@ -37,15 +36,15 @@ class Passive(
)
}

fun GearyModule.parsePassive() = observe<OnSet>()
fun Geary.parsePassive() = observe<OnSet>()
.involving(query<Passive>())
.exec { (passive) ->
passive.systems.forEach { systemBind ->
val systemMatchingId = entity().id
entity.add(systemMatchingId)
system(query {
has(systemMatchingId)
has(systemBind.match.map { it.id })
has(systemBind.match)
}).every(systemBind.every).execOnAll {
entities().fastForEach { entity ->
runCatching {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.mineinabyss.geary.actions.expressions

import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.getWorld
import kotlinx.serialization.ContextualSerializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -31,23 +33,25 @@ sealed interface Expression<T> {
}

companion object {
fun parseExpression(string: String, module: SerializersModule): Expression<*> {
fun parseExpression(
world: Geary,string: String, module: SerializersModule): Expression<*> {
val (name, rem) = getFunctionName(string)
val reference = Variable<Any>(name)
if(rem == "") return reference
return foldFunctions(reference, rem, module)
return foldFunctions(world, reference, rem, module)
}

tailrec fun foldFunctions(
world: Geary,
reference: Expression<*>,
remainder: String,
module: SerializersModule,
): Expression<*> {
val (name, afterName) = getFunctionName(remainder)
val (yaml, afterYaml) = getYaml(afterName)
val functionExpr = FunctionExpression.parse(reference, name, yaml, module)
val functionExpr = FunctionExpression.parse(world, reference, name, yaml, module)
if (afterYaml == "") return functionExpr
return foldFunctions(functionExpr, afterYaml, module)
return foldFunctions(world, functionExpr, afterYaml, module)
}

fun getYaml(expr: String): Pair<String, String> {
Expand Down Expand Up @@ -76,6 +80,7 @@ sealed interface Expression<T> {
override val descriptor: SerialDescriptor = ContextualSerializer(Any::class).descriptor

override fun deserialize(decoder: Decoder): Expression<T> {
val world = decoder.serializersModule.getWorld()
// Try reading string value, if serial type isn't string, this fails
runCatching {
decoder.decodeStructure(String.serializer().descriptor) {
Expand All @@ -84,6 +89,7 @@ sealed interface Expression<T> {
}.onSuccess { string ->
if (string.startsWith("{{") && string.endsWith("}}"))
return parseExpression(
world,
string.removePrefix("{{").removeSuffix("}}").trim(),
decoder.serializersModule
) as Expression<T>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.mineinabyss.geary.actions.expressions

import com.mineinabyss.geary.actions.ActionGroupContext
import com.mineinabyss.geary.serialization.serializableComponents
import com.mineinabyss.geary.serialization.serializers.SerializableComponentId
import com.mineinabyss.geary.modules.Geary
import com.mineinabyss.geary.serialization.SerializableComponents
import com.mineinabyss.geary.serialization.serializers.ComponentIdSerializer
import kotlinx.serialization.modules.SerializersModule

interface FunctionExpression<I, O> {
companion object {
fun parse(
world: Geary,
ref: Expression<*>,
name: String,
yaml: String,
module: SerializersModule,
): FunctionExpressionWithInput<*, *> {
val compClass = SerializableComponentId.Serializer.getComponent(name, module)
val serializableComponents = world.getAddon(SerializableComponents)
val compClass = ComponentIdSerializer(serializableComponents.serializers, world).getComponent(name, module)
val serializer = serializableComponents.serializers.getSerializerFor(compClass)
?: error("No serializer found for component $name")
val expr =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.mineinabyss.geary.actions.expressions

import com.mineinabyss.geary.modules.Geary
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

object InlineExpressionSerializer : KSerializer<Expression<*>> {
class InlineExpressionSerializer(
val world: Geary,
) : KSerializer<Expression<*>> {
override val descriptor: SerialDescriptor = String.serializer().descriptor

override fun deserialize(decoder: Decoder): Expression<*> {
return Expression.parseExpression(
world,
decoder.decodeString(),
decoder.serializersModule
)
Expand All @@ -19,5 +23,4 @@ object InlineExpressionSerializer : KSerializer<Expression<*>> {
override fun serialize(encoder: Encoder, value: Expression<*>) {
TODO("Not yet implemented")
}

}
Loading

0 comments on commit 77159f0

Please sign in to comment.