mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 23:32:20 +00:00
feat(cockpit): an application can add its own cockpit subjects; the Rail and Transit layers expose the read and hold APIs such a subject needs
GEV itself registers no new subject: with no provider, the Cockpit offers
aircraft, satellites and vessels as before, except that the most recently
selected of them now wins entry.
- services.cockpitSubjects: providers ({kind, layerId, entryFace, priority,
isEntryAllowed, read, hold, release, hud}) are checked once by the
coordinator; frames and HUD views on every update; a throwing provider
ends its view or keeps the last HUD.
- Entry: the most recently selected subject wins, across all kinds.
- Camera: a frame may turn the ground clamp off, anchor exactly on the
subject and update every frame.
- A generic HUD: kicker, title, cards, always-visible source rows, banner,
a veil with light streaks (off under reduced motion) and a bottom
progress line whose close ticks merge.
- Text comes from the provider, already in the page's language
(./i18n/locale: getLocale, onLocaleChange).
- Rail and Transit read and hold APIs (getSelectedTrain/Vehicle,
getCockpitSubject, setCockpitSubject, focusTrain/Vehicle); a held
train's marker, card and route line are hidden, and its feed keeps
polling while held.
- ./layers/rail/paths is exported.
This commit is contained in:
1 parent
10a788db78
commit
f75179eea0
51 files changed
+4059
-129
No files matched your search
@@ -1985,6 +1985,60 @@ the subject (tracking stopped, Satellites off) or tracking another target
|
||||
ends the view without refocusing. `src/ui/cockpitOrbitalView.test.mjs`
|
||||
covers entry, camera, zoom, look, HUD and exit.
|
||||
|
||||
### Application subjects
|
||||
|
||||
An application can add its own first-person subjects beside the aircraft,
|
||||
vessel and satellite: `services.cockpitSubjects` to `createApplicationControls`,
|
||||
a list of subject providers (`src/cockpitSubjectProviders.js`, checked once by
|
||||
the coordinator; a malformed one is left out with a warning). A provider names
|
||||
its layer, an entry face and labels in the page's language, and supplies four
|
||||
operations: `candidate()` (what entry would ride now), `hold(id)`,
|
||||
`read(nowMs, ctx)` (a camera frame each update) and `hud(frame, ctx)` (a HUD
|
||||
view model), with `release(id, {restore})` on exit. Entry needs the provider's
|
||||
layer on, no Context change in flight and the provider's own
|
||||
`isEntryAllowed(candidate)`; voice stays aircraft-only and is refused, with
|
||||
the reason, while a provider's view is in use.
|
||||
|
||||
Entry rides the most recently selected subject of all kinds: a tracked
|
||||
aircraft, the tracked satellite, the selected vessel or a provider's
|
||||
candidate, by when the Cockpit first saw it; subjects first seen together keep
|
||||
the fixed order (aircraft, satellite, vessel, then providers by priority). The
|
||||
newest decides alone: when its gate is shut there is no entry rather than an
|
||||
older subject's.
|
||||
|
||||
A frame places the eye `eye.upM` above `heightM` (the shared floor where the
|
||||
frame gives none), slews toward `headingDeg` at the provider's rate, and may
|
||||
turn off the floor clamps (`groundClamp: false`, for a subject inside a
|
||||
structure) or keep the anchor exactly on the subject (`anchor: 'exact'`, for a
|
||||
layer that already moves it smoothly); `cameraIntervalMs: 0` updates the
|
||||
camera every rendered frame. A frame that is null, malformed or for another
|
||||
subject ends the view (`restoreTracking: false`), as an aircraft tracked
|
||||
meanwhile and the provider's layer turning off do; the exit control asks the
|
||||
provider to restore its subject. The generic HUD shows the provider's kicker,
|
||||
title, meta line, speed with its unit and tag, readout cards, always-visible
|
||||
source rows, banner, route card and Live Signals rows, a veil that darkens the
|
||||
picture under the HUD (with passing light streaks, which stop under reduced
|
||||
motion), arrow-key look-around when the provider asks for it, and a progress
|
||||
line along the bottom edge (`src/cockpitProgress.js`: close ticks merge,
|
||||
labels never overlap). Core translates none of the provider's text: a host
|
||||
words it for the page's language (`@gods-eye-view/core/i18n/locale`:
|
||||
`getLocale`, `onLocaleChange`).
|
||||
|
||||
The Rail layer offers a read API for such a view: `getSelectedTrain()` and
|
||||
`getCockpitSubject()` (a snapshot of the train: where it is along its line,
|
||||
which way it runs (`pathBinding.js` learns it), its rail height, speed as
|
||||
reported or derived, position source, feed credit and stops),
|
||||
`setCockpitSubject(key)` (its marker and card hidden, the selection kept, its
|
||||
feed held, clicks and Escape left to the view) and `focusTrain(key)`; its pure
|
||||
path module is exported as `@gods-eye-view/core/layers/rail/paths`. Transit
|
||||
offers the same for a vehicle (`getSelectedVehicle`, `getCockpitSubject`,
|
||||
`setCockpitSubject`, `focusVehicle`): a held vehicle keeps playing when it is
|
||||
out of the camera's view, and its sprite, card, trail and detection box are
|
||||
hidden. `src/ui/cockpitSubjectView.test.mjs`,
|
||||
`src/cockpitSubjectProviders.test.mjs`, `src/cockpitProgress.test.mjs`,
|
||||
`src/layers/rail/cockpitSubject.test.mjs` and the Transit lifecycle tests
|
||||
cover them.
|
||||
|
||||
## Context coordination
|
||||
|
||||
Context controls own Contacts/Space Missions state, entry and exit transactions,
|
||||
|
||||
Reference in new issue
Block a user