All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.stress.ProcessorsExample.kt Maven / Gradle / Ivy

There is a newer version: 2021.0.3-RELEASE
Show newest version
import kotlinx.coroutines.*
import org.hexworks.amethyst.api.Context
import org.hexworks.cobalt.core.api.UUID
import kotlin.coroutines.CoroutineContext
import kotlin.reflect.KClass

interface Attribute {
    val name: String
}

interface EntityType : Attribute

data class Category(val value: String) : Attribute {
    override val name = "category"
}

data class DependsOn(val processors: List) : Attribute {
    override val name = "depends on"
}

data class ProcessorContext(
        val currentTime: Long,
        val entities: Sequence>>
) : Context

object Processor : EntityType {
    override val name = "Processor"
}

typealias ProcessorEntity = Entity

@Suppress("UNCHECKED_CAST")
class Engine(
        override val coroutineContext: CoroutineContext = Dispatchers.Default
) : CoroutineScope {

    private val entities = mutableMapOf, MutableList>>>()

    fun > addEntity(entity: Entity) {
        entities.getOrPut(entity.contextClass) { mutableListOf() }.add(entity as Entity>)
    }

    fun > removeEntity(entity: Entity) {
        // ...
    }

    fun update(currentTimeMs: Long): Job {
        return launch {
            entities[ProcessorContext::class]?.map {
                async {
                    it.update(ProcessorContext(
                            currentTime = System.currentTimeMillis(),
                            entities = entities.values.asSequence().flatMap { it.asSequence() }
                    ))
                }
            }?.awaitAll()
        }
    }
}

fun Engine.addProcessor(processor: Entity) {
    addEntity(processor)
}

interface Behavior> {

    suspend fun update(entity: Entity, context: C): Boolean

}

class Entity>(
        val type: T,
        val contextClass: KClass,
        val attributes: Set,
        val behaviors: Set>
) {

    val id: UUID = UUID.randomUUID()

    suspend fun update(context: C): Boolean {
        return behaviors.fold(false) { acc, next -> acc || next.update(this, context) }
    }
}

fun processor(attributes: Set, fn: suspend (ProcessorContext) -> Boolean) = Entity(
        type = Processor,
        contextClass = ProcessorContext::class,
        attributes = attributes,
        behaviors = setOf(object : Behavior {
            override suspend fun update(
                    entity: Entity,
                    context: ProcessorContext
            ): Boolean {
                return fn(context)
            }
        })
)

data class LastUpdate(var lastUpdate: Long = System.currentTimeMillis()) : Attribute {
    override val name = "last update"
}

object FloraContext : Context
object FaunaContext : Context
object CombatContext : Context

fun main() {

    val engine = Engine()

    val floraProcessor = processor(
            attributes = setOf(LastUpdate(), Category("flora"))
    ) { (currentTime, entities) ->
        // we get the last update from this entity and calculate whether we want to update now
        entities.filter {
            it.contextClass == FloraContext::class
        }.forEach {
            it.update(FloraContext as Context)
        }
        true
    }
    val faunaProcessor = processor(
            attributes = setOf(LastUpdate(), Category("fauna"), DependsOn(listOf(floraProcessor)))
    ) { (currentTime, entities) ->
        // same as above, but different filtering
        true
    }
    val combatProcessor = processor(
            attributes = setOf(LastUpdate(), Category("combat"), DependsOn(listOf(floraProcessor, faunaProcessor)))
    ) { (currentTime, entities) ->
        // same as above, but different filtering
        true
    }

    engine.addProcessor(floraProcessor)
    engine.addProcessor(faunaProcessor)
    engine.addProcessor(combatProcessor)

    // add the rest of the entities

}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy