I think you might be missing the job of PlayHead. It doesn’t just run internally, it’s not a timer. From the docs:
Converts a monotonically increasing reference range in to a timeline range.
This can then get converted to a real-time range using the playback sample rate.
This also handles looping and scrubbing and keeps track of when the play position
was last set.
Maybe look at tracktion::engine::EditPlaybackContext::NodePlaybackContext for how we use it there?