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

commonMain.de.fabmax.kool.editor.api.CachedComponents.kt Maven / Gradle / Ivy

package de.fabmax.kool.editor.api

import de.fabmax.kool.editor.components.GameEntityComponent
import de.fabmax.kool.editor.components.project
import de.fabmax.kool.editor.components.scene
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.cast

class CachedEntityComponents(val gameEntity: GameEntity, val componentClass: KClass) {
    private var modCnt = 0
    private val cache = mutableListOf()

    operator fun getValue(thisRef: Any?, property: KProperty<*>): List = getComponents()

    fun getComponents(): List {
        return if (gameEntity.componentModCnt == modCnt) cache else {
            modCnt = gameEntity.componentModCnt
            cache.clear()
            gameEntity.components
                .filter { componentClass.isInstance(it) }
                .map { componentClass.cast(it) }
                .also { cache.addAll(it) }
        }
    }
}

class CachedSceneComponents(val scene: EditorScene, val componentClass: KClass) {
    private var modCnt = 0
    private val cache = mutableListOf()

    operator fun getValue(thisRef: Any?, property: KProperty<*>): List = getComponents()

    fun getComponents(): List {
        return if (scene.componentModCnt == modCnt) cache else {
            modCnt = scene.componentModCnt
            cache.clear()
            scene.sceneEntities.values
                .flatMap { it.components.filter { c -> componentClass.isInstance(c) } }
                .map { componentClass.cast(it) }
                .also { cache.addAll(it) }
        }
    }
}

class CachedProjectComponents(val project: EditorProject, val componentClass: KClass) {
    private var modCnts = intArrayOf()
    private val cache = mutableListOf()

    operator fun getValue(thisRef: Any?, property: KProperty<*>): List = getComponents()

    fun getComponents(): List {
        val scenes = project.createdScenes.values.toList() + project.materialScene
        if (modCnts.size != scenes.size) {
            modCnts = IntArray(scenes.size)
        }

        var isDirty = false
        for (i in modCnts.indices) {
            if (modCnts[i] != scenes[i].componentModCnt) {
                isDirty = true
            }
            modCnts[i] = scenes[i].componentModCnt
        }

        if (isDirty) {
            cache.clear()
            scenes.forEach { scene ->
                scene.sceneEntities.values
                    .flatMap { it.components.filter { c -> componentClass.isInstance(c) } }
                    .map { componentClass.cast(it) }
                    .also { cache.addAll(it) }
            }
        }
        return cache
    }
}

inline fun  GameEntity.cachedEntityComponents(): CachedEntityComponents {
    return CachedEntityComponents(this, T::class)
}

inline fun  GameEntityComponent.cachedEntityComponents(): CachedEntityComponents {
    return CachedEntityComponents(gameEntity, T::class)
}

inline fun  GameEntity.cachedSceneComponents(): CachedSceneComponents {
    return CachedSceneComponents(scene, T::class)
}

inline fun  GameEntityComponent.cachedSceneComponents(): CachedSceneComponents {
    return CachedSceneComponents(scene, T::class)
}

inline fun  GameEntity.cachedProjectComponents(): CachedProjectComponents {
    return CachedProjectComponents(project, T::class)
}

inline fun  GameEntityComponent.cachedProjectComponents(): CachedProjectComponents {
    return CachedProjectComponents(project, T::class)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy