Remove per-call overhead from API access and text conversion
Two hot-path optimizations for the device's Cortex-M7 (and debug simulator builds): - The ten sub-API pointers are cached once in Playdate.initialize(with:); wrapper accessors now return UnsafePointer and call sites read a single field through it, instead of unwrapping the optional API struct and copying a whole sub-API struct of function pointers on every call. Nested sub-APIs (sound classes, effects, video, tilemap, http/tcp) derive from the cached pointers with one field load. - String -> C conversions (withPlaydateCString, and a new withPlaydateUTF8 used by the text drawing/measuring APIs) use withUnsafeTemporaryAllocation instead of building a ContiguousArray, so logging and drawText in the update loop no longer heap-allocate per call. Verified within the Embedded Swift subset by the device cross-compile. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
internal import CPlaydate
|
||||
|
||||
private var jsonAPI: playdate_json { Playdate.api.json.pointee }
|
||||
private var jsonAPI: UnsafePointer<playdate_json> { Playdate.jsonAPI }
|
||||
|
||||
/// The JSON API: decoding to and encoding from a `Value` tree.
|
||||
public enum JSON {}
|
||||
@@ -112,7 +112,7 @@ extension JSON {
|
||||
var outval = json_value()
|
||||
let ok = jsonString.withPlaydateCString { cString in
|
||||
withExtendedLifetime(context) {
|
||||
jsonAPI.decodeString.unsafelyUnwrapped(&decoder, cString, &outval) != 0
|
||||
jsonAPI.pointee.decodeString.unsafelyUnwrapped(&decoder, cString, &outval) != 0
|
||||
}
|
||||
}
|
||||
guard ok else {
|
||||
@@ -141,7 +141,7 @@ extension JSON {
|
||||
var outval = json_value()
|
||||
let ok = withExtendedLifetime(context) {
|
||||
withExtendedLifetime(file) {
|
||||
jsonAPI.decode.unsafelyUnwrapped(&decoder, reader, &outval) != 0
|
||||
jsonAPI.pointee.decode.unsafelyUnwrapped(&decoder, reader, &outval) != 0
|
||||
}
|
||||
}
|
||||
guard ok else {
|
||||
@@ -172,7 +172,7 @@ extension JSON {
|
||||
private let output = Output()
|
||||
|
||||
public init(pretty: Bool = false) {
|
||||
jsonAPI.initEncoder.unsafelyUnwrapped(&encoder, { userdata, string, length in
|
||||
jsonAPI.pointee.initEncoder.unsafelyUnwrapped(&encoder, { userdata, string, length in
|
||||
guard let userdata, let string else { return }
|
||||
let output = Unmanaged<Output>.fromOpaque(userdata).takeUnretainedValue()
|
||||
let bytes = UnsafeRawBufferPointer(start: string, count: Int(length))
|
||||
|
||||
Reference in New Issue
Block a user