Skip to content

Conversation

@0ffz
Copy link
Contributor

@0ffz 0ffz commented Jan 6, 2026

This PR adds compose multiplatform dependencies and makes small updates to the core module to enable a future kool-compose-ui module to function correctly. I've left comments about some changes below where I'd like some feedback.

Main changes are:

  • Exposing mutable child/parents on UiNode and marking it as internal via an optIn annotation (see comments below)
  • Adding a global Snapshot write observer, necessary for mutableStates in compose to correctly trigger recomposition before a frame is drawn (see KoolContext)
  • Adding compose dependencies via version catalog

feat: Compose global snapshot handling in render loop
[versions]
agp = "8.12.3"
compose = "1.9.3"
compose-mini = "0.0.1"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the dependency I mentioned for some compose helpers, repo here: https://github.com/0ffz/compose-mini. I've tried to split things into modules where it makes sense and support all the current targets, the only thing it's necessary for in the core module is a cross platform nanoTime implementation which I've included in the runtime module, so I'd like to hear your preferences:

  • I can split just nanoTime into its own module under this repo or leave it as is (the runtime just contains some helpers for creating a composition)
  • I noticed Kool already has a SystemClock implementation though this doesn't expose nanoseconds. I could update its implementation, it's not too bad for jvm/web but there are a lot of native implementations if Kool ever adds those targets.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding it to Time should be fine. I think SystemClock actually isn't really needed anymore since Clock.System made it it to stdlib. So Time.kt could now look something like this:

val precisionTime: Double get() = nanoTime / 1_000_000_000.0

val nanoTime: Long get() {
    val now = Clock.System.now()
    return now.epochSeconds * 1_000_000_000L + now.nanosecondsOfSecond
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the implementation to use this and removed the dependency in core module 👍

* Any blocks waiting for a new frame will run immediately when the frame is emitted, then switch
* to their parent context to return the result.
*/
val frameClock = BroadcastFrameClock()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need UI surfaces to be able to access this in the compose module, not sure if keeping it in Time is the best since this may feel like a redundant way to listen to new frames (given we have a flow), I've tried to explain it in the KDoc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah seems a bit redundant indeed. I think I would prefer it to be in a more UI specific place and / or maybe have it renamed to something like composeFrameClock or so.

Another option might be to somehow merge it with frameFlow? Not sure if that's actually possible though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be doable with just the flow, but there's some extra work to make sure the collection gets dispatched in the right order (it might just mean calling KoolDispatchers.Frontend.executeDispatchedTasks() twice), as well as making sure the value is emitted in the right place.

I think to avoid changing too much I'll leave it with this and annotate it as internal for now.

@0ffz 0ffz marked this pull request as ready for review January 6, 2026 22:50
@fabmax fabmax merged commit b111688 into kool-engine:main Jan 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants