Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ let package = Package(
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.0"),
.package(url: "https://github.com/cashapp/AccessibilitySnapshot", from: "0.12.0"),
.package(url: "https://github.com/SFSafeSymbols/SFSafeSymbols", from: "7.0.0"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.38.1"),
],
targets: [
.target(
Expand Down Expand Up @@ -224,6 +225,8 @@ let package = Package(
name: "ThrowCore",
dependencies: [
.target(name: "PeriscopeCore"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "ZIPFoundation", package: "ZIPFoundation"),
],
path: "Throw/ThrowCore/Sources",
resources: [
Expand Down
1 change: 1 addition & 0 deletions Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ let project = Project(
bundleIdSuffix: "throwcore",
productDependency: "ThrowCore",
sources: ["Throw/ThrowCore/Tests/**"],
extraPackageProducts: ["SwiftProtobuf"],
),
unitTests(
name: "ThrowUITests",
Expand Down
4 changes: 4 additions & 0 deletions Throw/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ WhereCore, RegionKit, or LifecycleKit into this feature.
`RunnableProjectionExperienceID` to playlist and runtime commands.
- Keep aircraft provider implementations in ThrowCore. ThrowUI uses the
provider-neutral operation service and domain results.
- Keep transit provider adapters in ThrowCore. Keep each city behind the typed
schedule and observation protocols. Never add agency checks to the renderer.
- Keep exactly one Transit runtime. It can poll only while Transit is active or
prewarming. Treat each realtime partition as an independent failure domain.
- Keep one experience coordinator for all scenes. Only the active and
prewarming experience runtimes may run at the same time.
- Exchange complete experience frames only while the projection is black.
Expand Down
37 changes: 28 additions & 9 deletions Throw/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ Preview runs the same projection renderer on the device.

## Projection Views

“View” is the user-facing name for a `ProjectionExperience`. Air & Space is the
first enabled View. It contains Geography, Flights, and the planned Stars and
Satellites layers. Transit is planned for nearby moving buses, trains, and
ferries. This change does not include a live transit provider.
“View” is the user-facing name for a `ProjectionExperience`. Air & Space contains
Geography, Flights, and the planned Stars and Satellites layers. Transit first
supports New York City subway trains.

One playlist controls every projector, full-screen output, and Preview. Each
View has a dwell duration. Automatic rotation starts only when two Views are
Expand All @@ -58,11 +57,31 @@ View visible until the new View has fresh data and a complete prepared frame.
Both values must belong to the same activation. The surface fades to black,
exchanges atomically, and fades back in. Two Views never share one frame.

Air & Space is the only configurable View in this release. Automatic rotation
therefore remains dormant. Transit stays in the display and preference formats
as a planned View. It has no runnable identity, so release code cannot add it to
the playlist or send it to the coordinator. A future runtime must add a new
runnable identity and update the exhaustive activation switch.
You can configure Air & Space and NYC Subway together. Then Throw can rotate
between the two Views. Each View keeps its own Map center, viewport, labels,
mark size, and context intensity.

## NYC Subway

The NYC Subway View uses the official supplemented GTFS schedule from the MTA.
It polls the eight official GTFS Realtime feed partitions every 30 seconds.
The schedule defines routes, stops, trip patterns, and route shapes. The
realtime feeds provide assigned train runs and predicted stop times.

The MTA feeds do not provide a continuous position for each train. Throw
estimates each train position along its scheduled shape. A train becomes more
certain after consecutive feed updates show its movement through stops.

Throw downloads the schedule during setup and stores it in the local cache.
It refreshes the schedule each hour while the View runs. A valid empty realtime
response completes activation. If one partition fails, the other partitions
continue to update. The failed partition keeps its last train positions for
90 seconds. Then it fades them for 30 seconds.

Transit data uses a provider-neutral schedule and observation boundary. An
additional city can supply its own GTFS adapters without changing the Transit
projection layers. The first release does not include San Francisco data,
buses, ferries, service alerts, or accessibility status.

## Aircraft sources

Expand Down
15 changes: 5 additions & 10 deletions Throw/TODOs.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,9 @@ owned by the root [`TODOs.md`](../TODOs.md).

## P1s (Should do)

- feat(Throw) [needs-design]: Implement the planned Transit View — the catalog
reserves Network and Vehicles layers
(`ThrowCore/Sources/ProjectionExperience.swift:67-74`), and Views presents
Transit as unavailable
(`ThrowUI/Sources/Settings/ProjectionViewsSettingsView.swift:38-42,95-102`).
Select a live provider, define GTFS or equivalent route geometry, and add
setup and credentials if required. Give its Map runtime independent polling.
Keep vehicles brighter than dim network and Geography context. (human
2026-08-26)

# Completed issues

- feat(Throw): Implement the first Transit View with the official NYC Subway
static and realtime MTA feeds. Keep the source seams independent of the city,
and keep route lines and train marks in the generic projection pipeline.
(completed 2026-08-27)
Loading
Loading