Swift 6.4 migration and exhancements (#1)

This PR contains the work done to update the library and the attached example project to use the Swift 6.4 computer as a minimum supported version and also, to use the latest features introduced in it.

Reviewed-on: #1
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #1.
This commit is contained in:
2026-09-18 13:15:08 +00:00
committed by javier
parent d0a561b91f
commit c5037dd716
105 changed files with 1390 additions and 1397 deletions
@@ -1,10 +1,9 @@
/// The user's answer to a permission request (microphone, network).
/// Immediate result of a permission request (microphone, network). Wraps `enum accessReply`.
public enum AccessReply: UInt32, Sendable {
/// The user has not answered yet; the request's completion delivers
/// the answer later.
/// Not answered yet; the completion receives the answer.
case ask = 0
/// The user has already denied access; the completion is not called.
/// Already denied; the completion is not called.
case deny = 1
/// The user has already granted access; the completion is not called.
/// Already granted; the completion is not called.
case allow = 2
}
@@ -1,36 +1,31 @@
public import CPlaydate
/// A Swift view of `PDSystemEvent` with the key code folded into the
/// key events.
/// An event sent to the game's `eventHandler`. Wraps `PDSystemEvent`; key events carry
/// the event argument.
public enum SystemEvent {
/// Sent once at startup, before the first update.
/// Once after the game loads, before the first update.
case initialize
/// Sent when the Lua runtime is ready, for registering custom
/// functions and classes.
/// After `initialize` if no update callback is set, once Lua exists and before
/// `main.lua` runs; register Lua functions and classes here.
case initializeLua
/// The device was locked.
case lock
/// The device was unlocked.
case unlock
/// The game was paused (e.g. the system menu opened).
/// E.g. the system menu opened.
case pause
/// The game resumed after a pause.
case resume
/// The game is about to be terminated.
case terminate
/// A simulator key was pressed.
/// Simulator only.
case keyPressed(keyCode: UInt32)
/// A simulator key was released.
/// Simulator only.
case keyReleased(keyCode: UInt32)
/// The device is about to power down because the battery is low.
/// About to enter low-power sleep because the battery is low.
case lowPower
/// A Mirror session started.
/// Mirror connected.
case mirrorStarted
/// A Mirror session ended.
/// Mirror disconnected.
case mirrorEnded
/// Creates an event from the C event and its argument, or `nil` for
/// events unknown to this binding.
/// From the `eventHandler` arguments; `nil` for events this binding doesn't know.
public init?(event: PDSystemEvent, argument: UInt32) {
switch event {
case kEventInit: self = .initialize
+11 -23
View File
@@ -1,25 +1,17 @@
public import CPlaydate
/// The raw C API bootstrap.
///
/// The C API is delivered as a `PlaydateAPI` struct of function pointers
/// that the firmware hands to the game's `eventHandler` entry point. Call
/// `initialize(with:)` from that entry point before using any other API in
/// this module. Everything else (System, Graphics, Sprite, Sound, ...)
/// lives at the top level of the `PlaydateKit` module.
/// Raw C API bootstrap. The firmware passes the `PlaydateAPI` table to the game's
/// `eventHandler`; call `initialize(with:)` there before any other API in this module.
/// The wrappers (`System`, `Graphics`, `Sprite`, `Sound`, ...) are top-level.
public enum Playdate {
/// The raw C API. Populated by `initialize(with:)`.
///
/// Access is unsynchronized: the Playdate runtime is single-threaded and
/// the API pointer is written exactly once at startup.
/// Copy of the C API table; `nil` until `initialize(with:)`. Unsynchronized: the
/// runtime is single-threaded and this is written once at startup.
public internal(set) nonisolated(unsafe) static var api: PlaydateAPI!
/// The raw C API pointer handed to `initialize(with:)`, for calls that
/// need to pass the `PlaydateAPI*` back to C.
/// The pointer passed to `initialize(with:)`, for C calls that take it; `nil` until then.
public internal(set) nonisolated(unsafe) static var apiPointer: UnsafeMutablePointer<PlaydateAPI>!
// Sub-API pointers cached once at initialization, so wrapper calls are a
// single field load off a pointer instead of re-walking `api` per call.
// Cached so each wrapper call is one field load instead of re-walking `api`.
nonisolated(unsafe) static var systemAPI: UnsafePointer<playdate_sys>!
nonisolated(unsafe) static var displayAPI: UnsafePointer<playdate_display>!
nonisolated(unsafe) static var graphicsAPI: UnsafePointer<playdate_graphics>!
@@ -31,10 +23,8 @@ public enum Playdate {
nonisolated(unsafe) static var scoreboardsAPI: UnsafePointer<playdate_scoreboards>!
nonisolated(unsafe) static var networkAPI: UnsafePointer<playdate_network>!
// Second-level tables, cached for the same reason. Assigned with
// optional chaining because partial API tables (e.g. test mocks) may
// leave some of them null; using an absent table traps at the call
// site, as before.
// Optional chaining tolerates partial tables (e.g. test mocks) with a null parent;
// using a missing table traps at the call site.
nonisolated(unsafe) static var tilemapAPI: UnsafePointer<playdate_tilemap>!
nonisolated(unsafe) static var videoAPI: UnsafePointer<playdate_video>!
nonisolated(unsafe) static var videoStreamAPI: UnsafePointer<playdate_videostream>!
@@ -61,10 +51,8 @@ public enum Playdate {
nonisolated(unsafe) static var httpAPI: UnsafePointer<playdate_http>!
nonisolated(unsafe) static var tcpAPI: UnsafePointer<playdate_tcp>!
/// Stores the API pointer handed to the game's `eventHandler`.
///
/// Call this first, on the `.initialize` event, before using any other
/// wrapper in this module.
/// Stores the `eventHandler`'s `PlaydateAPI*` and caches its sub-tables. Call on the
/// `.initialize` event, before any other API in this module.
public static func initialize(with pointer: UnsafeMutableRawPointer) {
apiPointer = pointer.assumingMemoryBound(to: PlaydateAPI.self)
api = apiPointer.pointee
@@ -1,15 +1,13 @@
/// An error reported by the Playdate OS.
public struct PlaydateError: Swift.Error, Sendable {
/// The message reported by the OS, or a description of the failure.
/// The OS message, or a description of the failure.
public let message: String
/// Creates an error with the given message.
init(message: String) {
self.message = message
}
/// Creates an error by copying an OS-provided C string; a nil pointer
/// produces "unknown error".
/// Copies an OS C string; null yields "unknown error".
init(cString: UnsafePointer<CChar>?) {
self.init(message: String(playdateCString: cString) ?? "unknown error")
}