package coffee.liz.abstractionengine.game import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import coffee.liz.ecs.System import coffee.liz.ecs.World import coffee.liz.ecs.animation.AnimationSystem import coffee.liz.ecs.animation.Animator import coffee.liz.ecs.animation.Position import coffee.liz.ecs.animation.SpriteSheet import kotlin.reflect.KClass /** * System that renders sprites to a DrawScope. * * This system queries all entities with Position, SpriteSheet, and Animator components, * then draws their current animation frame to the provided DrawScope. * * Depends on AnimationSystem to ensure animations are updated before rendering. */ class RenderSystem( private val imageCache: ImageCache ) : System { override val dependencies: Set> = setOf(AnimationSystem::class) /** * The update method is required by the System interface, but rendering * happens synchronously during Compose's draw phase via the render() method. */ override fun update(world: World, deltaTime: Float) { // Rendering happens in render() method, not here } /** * Renders all entities with sprites to the given DrawScope. * This should be called from a Compose Canvas during the draw phase. */ fun render(world: World, drawScope: DrawScope) { // Query all entities that can be rendered world.query(Position::class, SpriteSheet::class, Animator::class).forEach { entity -> val position = entity.get(Position::class) ?: return@forEach val spriteSheet = entity.get(SpriteSheet::class) ?: return@forEach val animator = entity.get(Animator::class) ?: return@forEach // Get the current frame name from the animator val frameName = animator.getCurrentFrameName() ?: return@forEach // Look up the frame rectangle in the sprite sheet val frameRect = spriteSheet.frames[frameName] ?: return@forEach // Get the image from cache val image = imageCache.getImage(spriteSheet.imagePath) ?: return@forEach // Draw the sprite with(drawScope) { drawImage( image = image, srcOffset = IntOffset(frameRect.x, frameRect.y), srcSize = IntSize(frameRect.width, frameRect.height), dstOffset = IntOffset(position.x.toInt(), position.y.toInt()), dstSize = IntSize(frameRect.width, frameRect.height) ) } } } }