waterui 0.3.0

A modern UI framework for Rust
import CWaterUI
import Foundation

final class WuiRedrawCallbackBox: @unchecked Sendable {
  private let wake: @MainActor @Sendable () -> Void

  init(wake: @escaping @MainActor @Sendable () -> Void) {
    self.wake = wake
  }

  func requestWake() {
    if Thread.isMainThread {
      MainActor.assumeIsolated {
        wake()
      }
    } else {
      DispatchQueue.main.async { [self] in
        wake()
      }
    }
  }
}

let wuiRedrawWakeCallback: @convention(c) (UnsafeMutableRawPointer?) -> Void = { context in
  guard let context else {
    fatalError("GPU redraw callback received a null context")
  }
  Unmanaged<WuiRedrawCallbackBox>
    .fromOpaque(context)
    .takeUnretainedValue()
    .requestWake()
}

let wuiRedrawDropCallback: @convention(c) (UnsafeMutableRawPointer?) -> Void = { context in
  guard let context else {
    fatalError("GPU redraw callback drop received a null context")
  }
  _ = Unmanaged<WuiRedrawCallbackBox>.fromOpaque(context).takeRetainedValue()
}

// Compiled out when the app disables WaterUI's `gpu` feature: the capture
// fence symbol this half binds does not exist in that build. The redraw box
// above stays — layout invalidation uses it with no GPU involved.
#if !WATERUI_NO_GPU
final class WuiGpuCaptureCompletionBox: @unchecked Sendable {
  private let completion: @MainActor @Sendable () -> Void

  init(completion: @escaping @MainActor @Sendable () -> Void) {
    self.completion = completion
  }

  func enqueueCompletion() {
    DispatchQueue.main.async { [completion] in
      completion()
    }
  }
}

let wuiGpuCaptureCompletionCallback: @convention(c) (UnsafeMutableRawPointer?) -> Void = {
  context in
  guard let context else {
    fatalError("GPU capture completion received a null context")
  }
  Unmanaged<WuiGpuCaptureCompletionBox>
    .fromOpaque(context)
    .takeUnretainedValue()
    .enqueueCompletion()
}

let wuiGpuCaptureCompletionDrop: @convention(c) (UnsafeMutableRawPointer?) -> Void = { context in
  guard let context else {
    fatalError("GPU capture completion drop received a null context")
  }
  _ = Unmanaged<WuiGpuCaptureCompletionBox>.fromOpaque(context).takeRetainedValue()
}

@MainActor
func observeGpuCaptureFence(
  _ fence: OpaquePointer,
  completion: @escaping @MainActor @Sendable () -> Void
) {
  let box = WuiGpuCaptureCompletionBox(completion: completion)
  waterui_gpu_capture_fence_on_complete(
    fence,
    Unmanaged.passRetained(box).toOpaque(),
    wuiGpuCaptureCompletionCallback,
    wuiGpuCaptureCompletionDrop
  )
}
#endif  // !WATERUI_NO_GPU