Swift bindings to the Playdate C API
Wraps all ten subsystems of the Playdate SDK 3.1.1 C API (system, display, graphics, sprites, sound, file, JSON, Lua, scoreboards, network) in idiomatic Swift: namespaced APIs, wrapper types with ownership semantics, closures for callbacks, and typed throws. Written within the Embedded Swift subset so the same code can target the device. The SDK headers are resolved through a "playdate" pkg-config module (Scripts/install-pkgconfig.sh), so the package works as a normal SwiftPM dependency without unsafe build flags. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Support.swift
|
||||
// Internal helpers shared by the wrappers.
|
||||
//
|
||||
// C-string conversions are implemented manually (rather than with
|
||||
// `String(cString:)` / `withCString`) so the module stays within the
|
||||
// Embedded Swift subset used for device builds.
|
||||
//
|
||||
|
||||
internal import CPlaydate
|
||||
|
||||
extension String {
|
||||
/// Creates a string by copying a null-terminated UTF-8 C string.
|
||||
init(playdateCString pointer: UnsafePointer<CChar>) {
|
||||
var count = 0
|
||||
while pointer[count] != 0 { count += 1 }
|
||||
let bytes = UnsafeRawBufferPointer(start: pointer, count: count)
|
||||
self = String(decoding: bytes, as: UTF8.self)
|
||||
}
|
||||
|
||||
/// Creates a string from a nullable C string, or `nil` if the pointer is null.
|
||||
init?(playdateCString pointer: UnsafePointer<CChar>?) {
|
||||
guard let pointer else { return nil }
|
||||
self.init(playdateCString: pointer)
|
||||
}
|
||||
|
||||
/// Calls `body` with a temporary null-terminated UTF-8 copy of the string.
|
||||
func withPlaydateCString<Result>(_ body: (UnsafePointer<CChar>) -> Result) -> Result {
|
||||
var utf8 = ContiguousArray(self.utf8)
|
||||
utf8.append(0)
|
||||
return utf8.withUnsafeBufferPointer { buffer in
|
||||
buffer.withMemoryRebound(to: CChar.self) { rebound in
|
||||
body(rebound.baseAddress.unsafelyUnwrapped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies the string into a newly allocated null-terminated C string.
|
||||
/// The caller owns the memory and must free it with `deallocate()`.
|
||||
func copiedPlaydateCString() -> UnsafeMutablePointer<CChar> {
|
||||
let utf8 = ContiguousArray(self.utf8)
|
||||
let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: utf8.count + 1)
|
||||
for (index, byte) in utf8.enumerated() {
|
||||
buffer[index] = CChar(bitPattern: byte)
|
||||
}
|
||||
buffer[utf8.count] = 0
|
||||
return buffer
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user