Adjusted the naming of the library in the Package file.
CI / Build & test (macOS) (push) Has been cancelled
CI / Embedded Swift cross-compile (push) Has been cancelled
Documentation / deploy (push) Has been cancelled

This commit is contained in:
javier committed 2026-07-25 12:02:55 +02:00
1 parent f6645d2613
commit 2e7ee12ec1
37 files changed
+74 -56

No files matched your search

+2 -2
View File
@@ -52,10 +52,10 @@ jobs:
- name: Generate documentation
run: |
swift package --allow-writing-to-directory docs \
generate-documentation --target PlayDate \
generate-documentation --target PlaydateKit \
--disable-indexing \
--transform-for-static-hosting \
--hosting-base-path play-date \
--hosting-base-path playdate-kit \
--output-path docs
- uses: actions/upload-pages-artifact@v3
@@ -15,8 +15,8 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "pdex"
BuildableName = "pdex"
BlueprintIdentifier = "PlaydateKit"
BuildableName = "PlaydateKit"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
@@ -28,6 +28,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PlaydateKitTests"
BuildableName = "PlaydateKitTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -50,8 +61,8 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "pdex"
BuildableName = "pdex"
BlueprintIdentifier = "PlaydateKit"
BuildableName = "PlaydateKit"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
+3 -3
View File
@@ -2,12 +2,12 @@ REPO_ROOT := $(shell git rev-parse --show-toplevel)
PRODUCT := HelloPlaydate.pdx
include $(REPO_ROOT)/Examples/swift.mk
# MARK: - Build PlayDate Wrapper Swift Module
build/Modules/playdate_device.o: $(REPO_ROOT)/Sources/PlayDate/*.swift
# MARK: - Build PlaydateKit Wrapper Swift Module
build/Modules/playdate_device.o: $(REPO_ROOT)/Sources/PlaydateKit/*.swift
@mkdir -p build/Modules
$(SWIFT_EXEC) $(SWIFT_FLAGS) $(SWIFT_FLAGS_DEVICE) -c $^ -emit-module -o $@
build/Modules/playdate_simulator.o: $(REPO_ROOT)/Sources/PlayDate/*.swift
build/Modules/playdate_simulator.o: $(REPO_ROOT)/Sources/PlaydateKit/*.swift
@mkdir -p build/Modules
$(SWIFT_EXEC) $(SWIFT_FLAGS) $(SWIFT_FLAGS_SIMULATOR) -c $^ -emit-module -o $@
+8 -3
View File
@@ -13,15 +13,20 @@ let package = Package(
),
],
dependencies: [
.package(path: "../.."),
// The explicit name overrides the identity a path dependency
// otherwise derives from the checkout directory's name.
.package(
name: "playdate-kit",
path: "../.."
),
],
targets: [
.target(
name: "HelloPlaydate",
dependencies: [
.product(
name: "PlayDate",
package: "play-date"
name: "PlaydateKit",
package: "playdate-kit"
)
]
),
+1 -1
View File
@@ -1,6 +1,6 @@
# Hello Playdate
A minimal game built on the `play-date` bindings: a bouncing box, a crank-aimed needle, button handling, a system menu item, and an FPS counter.
A minimal game built on the `playdate-kit` bindings: a bouncing box, a crank-aimed needle, button handling, a system menu item, and an FPS counter.
## Build and run (Playdate Simulator)
@@ -1,12 +1,12 @@
//
// Game.swift
// A minimal Playdate game built on the play-date Swift bindings: a
// A minimal Playdate game built on the playdate-kit Swift bindings: a
// bouncing box, a crank-aimed needle, button logging, and a system menu
// item.
//
import CPlaydate
import PlayDate
import PlaydateKit
@_cdecl("eventHandler")
public func eventHandler(
+2 -2
View File
@@ -82,13 +82,13 @@ SWIFT_FLAGS_DEVICE := \
$(addprefix -Xcc , $(C_FLAGS_DEVICE)) \
-target armv7em-none-none-eabi \
-Xfrontend -experimental-platform-c-calling-convention=arm_aapcs_vfp \
-module-alias PlayDate=playdate_device \
-module-alias PlaydateKit=playdate_device \
C_FLAGS_SIMULATOR := \
SWIFT_FLAGS_SIMULATOR := \
$(addprefix -Xcc , $(C_FLAGS_SIMULATOR)) \
-module-alias PlayDate=playdate_simulator \
-module-alias PlaydateKit=playdate_simulator \
SIMCOMPILER += \
-nostdlib \
+4 -4
View File
@@ -1,4 +1,4 @@
# Development lifecycle front door for the play-date package. All logic
# Development lifecycle front door for the playdate-kit package. All logic
# lives in SwiftPM, Scripts/, and the example's own Makefile; the targets
# here only dispatch. Run `make` or `make help` for the list.
#
@@ -39,16 +39,16 @@ upgrade: ## Update the SwiftPM dependencies to their latest allowed versions
embedded: ## Compile-only device check (Embedded Swift, armv7em-none-none-eabi)
SWIFT_BIN="$(SWIFT_BIN)" Scripts/build-embedded.sh
consumer-test: ## Build and run a scratch package depending on play-date
consumer-test: ## Build and run a scratch package depending on playdate-kit
Scripts/consumer-test.sh
check: build test embedded consumer-test ## Everything CI runs: build, test, embedded, consumer-test
docs: ## Generate the DocC documentation archive
swift package generate-documentation --target PlayDate
swift package generate-documentation --target PlaydateKit
docs-preview: ## Preview the DocC documentation in a local web server
swift package --disable-sandbox preview-documentation --target PlayDate
swift package --disable-sandbox preview-documentation --target PlaydateKit
example: ## Build the HelloPlaydate example (device + simulator pdx)
$(MAKE) -C $(EXAMPLE_DIR)
+8 -8
View File
@@ -3,11 +3,11 @@
import PackageDescription
let package = Package(
name: "play-date",
name: "playdate-kit",
products: [
.library(
name: "PlayDate",
targets: ["PlayDate"]
name: "PlaydateKit",
targets: ["PlaydateKit"]
),
],
dependencies: [
@@ -26,17 +26,17 @@ let package = Package(
pkgConfig: "playdate"
),
.target(
name: "PlayDate",
name: "PlaydateKit",
dependencies: ["CPlaydate"],
path: "Sources/PlayDate",
path: "Sources/PlaydateKit",
swiftSettings: [
.enableUpcomingFeature("ApproachableConcurrency"),
],
),
.testTarget(
name: "PlayDateTests",
dependencies: ["PlayDate"],
path: "Tests/PlayDate",
name: "PlaydateKitTests",
dependencies: ["PlaydateKit"],
path: "Tests/PlaydateKit",
swiftSettings: [
.enableUpcomingFeature("ApproachableConcurrency"),
],
+14 -14
View File
@@ -1,6 +1,6 @@
# PlayDate
# PlaydateKit
[![CI](https://github.com/<you>/play-date/actions/workflows/ci.yml/badge.svg)](https://github.com/<you>/play-date/actions/workflows/ci.yml)
[![CI](https://github.com/<you>/playdate-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/<you>/playdate-kit/actions/workflows/ci.yml)
Swift bindings to the [Playdate](https://play.date) C API.
@@ -48,14 +48,14 @@ If Xcode had the package open before you ran the script, make it re-read the man
```swift
// Package.swift of your game
dependencies: [
.package(url: "https://github.com/<you>/play-date.git", from: "0.1.0"),
.package(url: "https://github.com/<you>/playdate-kit.git", from: "0.1.0"),
// …or, while developing locally:
// .package(path: "../play-date"),
// .package(path: "../playdate-kit"),
],
targets: [
.target(
name: "MyGame",
dependencies: [.product(name: "PlayDate", package: "play-date")]
dependencies: [.product(name: "PlaydateKit", package: "playdate-kit")]
),
]
```
@@ -66,7 +66,7 @@ A Playdate game has a single C entry point, `eventHandler`. Export it with `@_cd
```swift
import CPlaydate
import PlayDate
import PlaydateKit
@_cdecl("eventHandler")
func eventHandler(
@@ -289,7 +289,7 @@ try Lua.addFunction(double, name: "mylib.double")
## Conventions
- **Namespaces.** The subsystem namespaces (`System`, `Graphics`, `Sound`, …) live at the top level of the module; only the raw C API bootstrap stays under `Playdate` (`Playdate.initialize(with:)`, `Playdate.api`). On a name collision with another module, qualify with the module name: `PlayDate.System`.
- **Namespaces.** The subsystem namespaces (`System`, `Graphics`, `Sound`, …) live at the top level of the module; only the raw C API bootstrap stays under `Playdate` (`Playdate.initialize(with:)`, `Playdate.api`). On a name collision with another module, qualify with the module name: `PlaydateKit.System`.
- **Errors.** Fallible operations use typed throws — `throws(PlaydateError)` generally, `throws(Network.NetError)` for network I/O — so `catch` gives you a concrete type, and no `any Error` existentials are needed.
- **Ownership.** A wrapper that *creates* a C object frees it on `deinit`; keep the wrapper referenced for as long as you use it. Wrappers vending OS-owned objects (a `Bitmap` from a `BitmapTable`, a track from a `Sequence`, …) don't free them — keep the owner alive instead, as documented on each API. Resources a C object keeps referencing (a sprite's image, a synth's sample, modulators, menu-item option titles) are retained by the wrapper automatically.
- **Callbacks.** Where the C API provides a userdata slot, closures are supported everywhere and delivered back with the right wrapper. A few C callbacks have no userdata (serial messages, headphone changes, scoreboard
@@ -305,7 +305,7 @@ Shipping a `.pdx` needs the Playdate toolchain on top:
- **Simulator** builds compile your game as a host dylib placed in the pdx (`Examples/HelloPlaydate/build.sh` shows the SwiftPM-based flow).
- **Device** builds cross-compile with Embedded Swift for ARM Cortex-M7 (`-enable-experimental-feature Embedded`, triple `armv7em-none-none-eabi`, `-fshort-enums` to match the firmware ABI) and link through the SDK's own make infrastructure.
[`Examples/swift.mk`](Examples/swift.mk) packages the device pipeline: it locates the SDK and a Swift snapshot toolchain, compiles the `PlayDate` wrapper as a module-aliased Embedded Swift module, and hooks the game objects into the SDK's `common.mk`. A game needs only a short Makefile on top — [`Examples/HelloPlaydate/Makefile`](Examples/HelloPlaydate/Makefile) is the template, and `make` in that directory produces a `.pdx` containing both the device binary and the simulator dylib. Swift code is compiled `-Osize` by default (measured ~15% smaller than `-O` on the example); override with `make SWIFT_OPT=-O`. The setup follows Apple's [swift-playdate-examples](https://github.com/apple/swift-playdate-examples), adapted to this package.
[`Examples/swift.mk`](Examples/swift.mk) packages the device pipeline: it locates the SDK and a Swift snapshot toolchain, compiles the `PlaydateKit` wrapper as a module-aliased Embedded Swift module, and hooks the game objects into the SDK's `common.mk`. A game needs only a short Makefile on top — [`Examples/HelloPlaydate/Makefile`](Examples/HelloPlaydate/Makefile) is the template, and `make` in that directory produces a `.pdx` containing both the device binary and the simulator dylib. Swift code is compiled `-Osize` by default (measured ~15% smaller than `-O` on the example); override with `make SWIFT_OPT=-O`. The setup follows Apple's [swift-playdate-examples](https://github.com/apple/swift-playdate-examples), adapted to this package.
The wrappers are written within the Embedded Swift subset for exactly this reason: no Foundation, no reflection, no untyped throws. That claim is enforced, not aspirational: `Scripts/build-embedded.sh` cross-compiles the whole module for `armv7em-none-none-eabi` with Embedded Swift enabled and the device's `-fshort-enums` ABI, and CI runs it on every push. Running it locally needs the same snapshot toolchain and Arm GNU toolchain headers:
@@ -324,7 +324,7 @@ A root Makefile fronts the development lifecycle; a bare `make` (or `make help`)
| `make build` / `make test` | Build the bindings for the host / run the unit tests |
| `make outdated` / `make upgrade` | Show / apply updates to the SwiftPM dependencies |
| `make embedded` | Compile-only device check (Embedded Swift, `armv7em-none-none-eabi`) |
| `make consumer-test` | Build and run a scratch package depending on play-date |
| `make consumer-test` | Build and run a scratch package depending on playdate-kit |
| `make check` | Everything CI runs: build, test, embedded, consumer-test |
| `make docs` / `make docs-preview` | Generate / preview the DocC documentation |
| `make example` / `make example-run` | Build the HelloPlaydate example / open it in the Playdate Simulator |
@@ -352,7 +352,7 @@ Sideload the device build from the Playdate Simulator (Device ▸ Upload Game to
The API reference is a DocC catalog. Generate it locally with:
```sh
swift package generate-documentation --target PlayDate
swift package generate-documentation --target PlaydateKit
```
or browse it with Xcode's documentation viewer (Product ▸ Build Documentation). Pushes to `main` publish the rendered docs to GitHub Pages via `.github/workflows/docs.yml` (enable Pages ▸ Source: GitHub Actions in the repository settings once).
@@ -370,17 +370,17 @@ Scripts/
module at your SDK installation
build-embedded.sh Compile-only device check: Embedded Swift for
armv7em-none-none-eabi with the device ABI (CI)
consumer-test.sh Builds a scratch package depending on play-date
consumer-test.sh Builds a scratch package depending on playdate-kit
to prove settings propagate to consumers (CI)
Sources/
CPlaydate/ System library target: module map + umbrella header
importing pd_api.h from the SDK, plus inline shims for
the variadic log/error functions
PlayDate/ The Swift bindings, one file per subsystem
PlaydateKit/ The Swift bindings, one file per subsystem
(Sound and Graphics are split across several files),
plus the PlayDate.docc documentation catalog
plus the PlaydateKit.docc documentation catalog
Tests/
PlayDate/ Host-runnable tests for the pure value types
PlaydateKit/ Host-runnable tests for the pure value types
```
## License
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/sh
#
# Cross-compiles the PlayDate target for Playdate hardware (Embedded Swift,
# Cross-compiles the PlaydateKit target for Playdate hardware (Embedded Swift,
# ARM Cortex-M7) as a compile-only check that the bindings stay within the
# Embedded Swift subset. Linking is left to game projects.
#
@@ -46,7 +46,7 @@ echo "Using arm-none-eabi headers: $include_dir"
# bare-metal ELF objects.
exec "$swift_bin" build \
--build-system native \
--target PlayDate \
--target PlaydateKit \
--triple armv7em-none-none-eabi \
-Xswiftc -enable-experimental-feature -Xswiftc Embedded \
-Xswiftc -wmo \
+6 -4
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Verifies the package works as a SwiftPM dependency: generates a scratch
# executable package that depends on play-date, imports both modules, and
# executable package that depends on playdate-kit, imports both modules, and
# runs it. This guards the pkg-config setup — target settings that don't
# propagate to consumers (or manifest validation failures) surface here,
# not on this package's own build.
@@ -21,12 +21,14 @@ import PackageDescription
let package = Package(
name: "consumer",
dependencies: [
.package(path: "$package_dir"),
// The explicit name overrides the identity a path dependency
// otherwise derives from the checkout directory's name.
.package(name: "playdate-kit", path: "$package_dir"),
],
targets: [
.executableTarget(
name: "consumer",
dependencies: [.product(name: "PlayDate", package: "play-date")]
dependencies: [.product(name: "PlaydateKit", package: "playdate-kit")]
),
]
)
@@ -34,7 +36,7 @@ EOF
cat > "$scratch_dir/Sources/consumer/main.swift" <<'EOF'
import CPlaydate
import PlayDate
import PlaydateKit
// Touch a type from each module to prove both import and link.
let event = SystemEvent(event: kEventInit, argument: 0)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -11,7 +11,7 @@ install an update callback:
```swift
import CPlaydate
import PlayDate
import PlaydateKit
@_cdecl("eventHandler")
func eventHandler(
@@ -1,4 +1,4 @@
# ``PlayDate``
# ``PlaydateKit``
Swift bindings to the Playdate C API.
@@ -1,5 +1,5 @@
//
// PlayDate.swift
// PlaydateKit.swift
// Swift bindings to the Playdate C API.
//
// The C API is delivered as a `PlaydateAPI` struct of function pointers that
@@ -11,7 +11,7 @@
public import CPlaydate
/// The raw C API bootstrap. Everything else in this module (System,
/// Graphics, Sprite, Sound, ...) lives at the top level of the `PlayDate`
/// Graphics, Sprite, Sound, ...) lives at the top level of the `PlaydateKit`
/// module and requires `initialize(with:)` to have been called first.
public enum Playdate {
/// The raw C API. Populated by `initialize(with:)`.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -9,7 +9,7 @@
//
import CPlaydate
@testable import PlayDate
@testable import PlaydateKit
enum Mock {
// MARK: - Stable API allocations
@@ -1,5 +1,5 @@
import Testing
@testable import PlayDate
@testable import PlaydateKit
// Most of the binding requires a running Playdate (the API struct is handed
// to the game at launch), so these tests cover the pure value types and the
@@ -10,7 +10,7 @@
import CPlaydate
import Testing
@testable import PlayDate
@testable import PlaydateKit
@Suite(.serialized)
struct WrapperTests {