SDL and Swift Concurrency not playing nicely

I'm attempting to make a cross-platform game engine in Swift that utilizes SDL under the hood. I'd like to use Swift's native concurrency tools for implementing frame timing (using Clock.sleep to wait if there's time leftover to get closer to a target FPS and overuse the CPU, for example). However, whenever I call any async function, the program immediately closes and the console shows the error No error handler for XPC error. Using SDL_Delay works, but as I understand it, that will stop any other process from using the thread. Maybe this is okay, but not being able to use Swift concurrency at all would be a bit of a bummer. Any ideas on what might be the issue here?

The project is available to peruse at GitHub - junebash/swift-lark: A game engine built with SDL and Swift..


Can you give an example of the usage or a link to how you are using it? I searched in that repo and it didn't show any hits for either Clock.sleep or SDK_Delay (but maybe GitHub was being weird for me.

Apologies, I've been playing with several different versions of things and only had one version in the Github repo. The place I was trying to implement async/await was in, as part of the main run loop. There have been a few different iterations, but the first iteration of the relevant code (which I'd still love if I could get working) ended up looking something like...

var currentState = gameState
var lastUpdate = // `updateClock: AnyClock<Duration>`
let timer = updateClock.timer(interval: .seconds(1.0 / 60.0)) // `AsyncTimerSequence<AnyClock<Duration>>`

for try await updateTime in timer {
  guard currentState.isRunning else { break }

  let deltaTime = lastUpdate.duration(to: updateTime)
  lastUpdate = updateTime

  currentState.update(deltaTime: deltaTime)
  try currentState.render()

Hi June,

I'm currently exploring SDL (through Swift), and I'm relying on the SDL_RENDERER_PRESENTVSYNC flag to make sure SDL doesn't overuse the CPU: SDL2/SDL_RendererFlags - SDL Wiki

Does that work for you?

That may very well work, but the possible CPU overuse isn't the greatest of my concerns; more than anything I'd like to know what's killing the process as soon as I interact with Swift concurrency.