Swift 6.4 migration and exhancements #1
@@ -48,14 +48,22 @@ extension Graphics {
|
|||||||
|
|
||||||
/// Fills the tilemap with `indexes`, `rowWidth` tiles per row. The
|
/// Fills the tilemap with `indexes`, `rowWidth` tiles per row. The
|
||||||
/// tilemap is resized to fit.
|
/// tilemap is resized to fit.
|
||||||
public func setTiles(_ indexes: [UInt16], rowWidth: Int) {
|
public func setTiles(_ indexes: Span<UInt16>, rowWidth: Int) {
|
||||||
var indexes = indexes
|
indexes.withUnsafeBufferPointer { buffer in
|
||||||
indexes.withUnsafeMutableBufferPointer { buffer in
|
// The C API takes a non-const pointer but only reads the
|
||||||
tilemapAPI.pointee.setTiles.unsafelyUnwrapped(pointer, buffer.baseAddress,
|
// indexes, copying them into the tilemap.
|
||||||
|
tilemapAPI.pointee.setTiles.unsafelyUnwrapped(
|
||||||
|
pointer, UnsafeMutablePointer(mutating: buffer.baseAddress),
|
||||||
Int32(buffer.count), Int32(rowWidth))
|
Int32(buffer.count), Int32(rowWidth))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fills the tilemap with `indexes`, `rowWidth` tiles per row. The
|
||||||
|
/// tilemap is resized to fit.
|
||||||
|
public func setTiles(_ indexes: [UInt16], rowWidth: Int) {
|
||||||
|
indexes.withUnsafeBufferPointer { setTiles($0.span, rowWidth: rowWidth) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the tile index at position (x, y).
|
/// Sets the tile index at position (x, y).
|
||||||
public func setTile(x: Int, y: Int, index: UInt16) {
|
public func setTile(x: Int, y: Int, index: UInt16) {
|
||||||
tilemapAPI.pointee.setTileAtPosition.unsafelyUnwrapped(pointer, Int32(x), Int32(y), index)
|
tilemapAPI.pointee.setTileAtPosition.unsafelyUnwrapped(pointer, Int32(x), Int32(y), index)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ enum Mock {
|
|||||||
nonisolated(unsafe) static let soundEffectAPI = UnsafeMutablePointer<playdate_sound_effect>.allocate(capacity: 1)
|
nonisolated(unsafe) static let soundEffectAPI = UnsafeMutablePointer<playdate_sound_effect>.allocate(capacity: 1)
|
||||||
nonisolated(unsafe) static let lfoAPI = UnsafeMutablePointer<playdate_sound_lfo>.allocate(capacity: 1)
|
nonisolated(unsafe) static let lfoAPI = UnsafeMutablePointer<playdate_sound_lfo>.allocate(capacity: 1)
|
||||||
nonisolated(unsafe) static let delayLineAPI = UnsafeMutablePointer<playdate_sound_effect_delayline>.allocate(capacity: 1)
|
nonisolated(unsafe) static let delayLineAPI = UnsafeMutablePointer<playdate_sound_effect_delayline>.allocate(capacity: 1)
|
||||||
|
nonisolated(unsafe) static let tilemapAPI = UnsafeMutablePointer<playdate_tilemap>.allocate(capacity: 1)
|
||||||
nonisolated(unsafe) static let fileAPI = UnsafeMutablePointer<playdate_file>.allocate(capacity: 1)
|
nonisolated(unsafe) static let fileAPI = UnsafeMutablePointer<playdate_file>.allocate(capacity: 1)
|
||||||
nonisolated(unsafe) static let jsonAPI = UnsafeMutablePointer<playdate_json>.allocate(capacity: 1)
|
nonisolated(unsafe) static let jsonAPI = UnsafeMutablePointer<playdate_json>.allocate(capacity: 1)
|
||||||
nonisolated(unsafe) static let apiStruct = UnsafeMutablePointer<PlaydateAPI>.allocate(capacity: 1)
|
nonisolated(unsafe) static let apiStruct = UnsafeMutablePointer<PlaydateAPI>.allocate(capacity: 1)
|
||||||
@@ -38,6 +39,9 @@ enum Mock {
|
|||||||
/// Caps the bytes a file read returns (0 = end of file, negative =
|
/// Caps the bytes a file read returns (0 = end of file, negative =
|
||||||
/// error); `nil` fills the whole request.
|
/// error); `nil` fills the whole request.
|
||||||
nonisolated(unsafe) static var fileReadLimit: Int32?
|
nonisolated(unsafe) static var fileReadLimit: Int32?
|
||||||
|
/// The index buffer and count last handed to `setTiles`.
|
||||||
|
nonisolated(unsafe) static var tilesPointer: UnsafeMutablePointer<UInt16>?
|
||||||
|
nonisolated(unsafe) static var tilesCount: Int32 = 0
|
||||||
/// Userdata stored per sprite / menu item, as the OS would keep it.
|
/// Userdata stored per sprite / menu item, as the OS would keep it.
|
||||||
nonisolated(unsafe) static var spriteUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
nonisolated(unsafe) static var spriteUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
||||||
nonisolated(unsafe) static var menuUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
nonisolated(unsafe) static var menuUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
||||||
@@ -87,6 +91,8 @@ enum Mock {
|
|||||||
buttonState = (0, 0, 0)
|
buttonState = (0, 0, 0)
|
||||||
patternBytes = []
|
patternBytes = []
|
||||||
fileReadLimit = nil
|
fileReadLimit = nil
|
||||||
|
tilesPointer = nil
|
||||||
|
tilesCount = 0
|
||||||
spriteUserdata = [:]
|
spriteUserdata = [:]
|
||||||
menuUserdata = [:]
|
menuUserdata = [:]
|
||||||
menuCallback = nil
|
menuCallback = nil
|
||||||
@@ -174,6 +180,19 @@ enum Mock {
|
|||||||
|
|
||||||
private static func installGraphics() {
|
private static func installGraphics() {
|
||||||
gfxAPI.initialize(to: playdate_graphics())
|
gfxAPI.initialize(to: playdate_graphics())
|
||||||
|
tilemapAPI.initialize(to: playdate_tilemap())
|
||||||
|
gfxAPI.pointee.tilemap = UnsafePointer(tilemapAPI)
|
||||||
|
|
||||||
|
tilemapAPI.pointee.newTilemap = {
|
||||||
|
Mock.record("newTilemap")
|
||||||
|
return Mock.fakePointer()
|
||||||
|
}
|
||||||
|
tilemapAPI.pointee.freeTilemap = { _ in Mock.record("freeTilemap") }
|
||||||
|
tilemapAPI.pointee.setTiles = { _, indexes, count, rowWidth in
|
||||||
|
Mock.record("setTiles(\(count),\(rowWidth))")
|
||||||
|
Mock.tilesPointer = indexes
|
||||||
|
Mock.tilesCount = count
|
||||||
|
}
|
||||||
|
|
||||||
gfxAPI.pointee.fillRect = { x, y, width, height, color in
|
gfxAPI.pointee.fillRect = { x, y, width, height, color in
|
||||||
if color > 3, let pattern = UnsafeRawPointer(bitPattern: color) {
|
if color > 3, let pattern = UnsafeRawPointer(bitPattern: color) {
|
||||||
|
|||||||
@@ -99,6 +99,16 @@ struct WrapperTests {
|
|||||||
#expect(visited == 1)
|
#expect(visited == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test func tileMapSetTilesPassesTheCallersStorageWithoutCopying() {
|
||||||
|
let tileMap = Graphics.TileMap()
|
||||||
|
let indexes: [UInt16] = [1, 2, 3, 4, 5, 6]
|
||||||
|
tileMap.setTiles(indexes, rowWidth: 3)
|
||||||
|
|
||||||
|
#expect(Mock.events.contains("setTiles(6,3)"))
|
||||||
|
let storage = indexes.withUnsafeBufferPointer { $0.baseAddress }
|
||||||
|
#expect(UnsafePointer(Mock.tilesPointer) == storage)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Sprite
|
// MARK: Sprite
|
||||||
|
|
||||||
@Test func spriteUserdataRecoversWrapperInCallbacks() {
|
@Test func spriteUserdataRecoversWrapperInCallbacks() {
|
||||||
|
|||||||
Reference in New Issue
Block a user