pub struct Ctx<G>where
G: GameData,{Show 18 fields
pub game: G,
pub palette: Palette,
pub console: ConsoleSpec,
pub keymap: Keymap<<G as GameData>::Action>,
pub device: Device,
pub storage: ProfileStore,
pub debug_tools: bool,
pub debug_view: DebugView,
pub idle_motion: IdleMotion,
pub audio: AudioQueue<<G as GameData>::Voice>,
pub music_clock: Option<MusicClock>,
pub music_seed: u64,
pub clock_s: f64,
pub key_prompt: KeyPrompt,
pub crank_docked: bool,
pub platform: PlatformFacts,
pub system_keyboard: SystemKeyboard,
pub lang: LangCode,
/* private fields */
}Expand description
Resources shared by every screen: the engine’s, and the game’s in
game.
Fields§
§game: GThe game’s data and state, which its screens share.
palette: PaletteNamed colors, from the game’s palette and the color theme in the settings.
console: ConsoleSpecThe console the frame is drawn on: the game’s
(GameData::console) unless a front end sets its own before the
Game starts.
keymap: Keymap<<G as GameData>::Action>The active key bindings, for help text that names keys: the chosen
layout’s with the player’s changes, or the layout picker’s
(Keymap::layout_picker) until one is chosen. Change it with
use_layout,
choose_layout or
set_layout_bindings, never directly.
device: DeviceWhat the player pressed last, the keyboard or a controller, so help
text names keys or that pad’s buttons (help_keys). Game keeps
it up to date from the input, starting from the one set here when
it starts (the keyboard, unless a front end without one sets its
pad).
storage: ProfileStoreWhere saves and settings persist: a
MemoryStorage until the platform
swaps in its own with with_storage.
It reads and writes the keys of the profile in use: its settings,
key bindings and whatever the game keeps per player.
computer is the storage of what stays
with the computer.
debug_tools: boolWhether debug tools are offered: the Debug action
(GameHooks::debug) and whatever else
the game offers only to developers. On in debug builds and with the
debug-tools feature (DEBUG_TOOLS).
debug_view: DebugViewWhich channels of the debug view are on (none at first), and which
the running screens have offered (ADR-0085): read from the
computer’s storage by with_storage with
debug tools on. Turn one on with
set_debug_channel, which saves it; a
change made here directly isn’t saved.
idle_motion: IdleMotionWhether screens show their idle motion. Off here, so a screen left alone in a test looks the same a moment later; the platform turns it on.
audio: AudioQueue<<G as GameData>::Voice>Sounds and music screens ask for this frame, e.g.
ctx.audio.play_sound("click"). Game passes them to the
platform.
music_clock: Option<MusicClock>Where the music that is sounding is in its track, for a screen that
keeps time with it. None in silence: nothing asked for, the track
still loading, its file missing, or a track played once that has
ended. Of two tracks sounding (a crossfade) it is the newest:
the old one until the new one has loaded. The platform
reports it each frame through
Game::set_music_playing.
music_seed: u64Seeds random music picks (e.g. a track from a pool), kept apart
from any simulation’s randomness. A fixed DEFAULT_MUSIC_SEED
here, so tests are repeatable; the platform sets it from the clock
at startup so each launch picks differently.
clock_s: f64Seconds the game has been running: the sum of every frame’s time
(Game adds it).
key_prompt: KeyPromptWhether a screen waits for a key press before going on (and before
playing music). Off here; the platform sets
KeyPrompt::Waiting, and Game moves it on to
KeyPrompt::Pressed at the first key or button press.
crank_docked: boolWhether the device’s crank is folded away, as the platform said last: a screen whose required action is on the crank then gets a hint to unfold it.
platform: PlatformFactsWhere the game runs: the target’s id, whether the game may quit,
whether its window goes full screen and back, and the keyboard,
pointer and touch screen the device has. The desktop target’s
here (PlatformFacts::default); the platform hands over its own
before the Game starts (a front end without a
keyboard sets the device it has too). Screens
read it; a game’s rules never do.
system_keyboard: SystemKeyboardThe system’s own keyboard for a text box (a console’s, Steam’s on
the Steam Deck), if the platform has one: absent here, and the
platform’s App says so before every frame.
lang: LangCodeThe language screen text is shown in: the game’s source language
(Lang::source_lang) until the player picks another. The game’s
debug language (GameData::debug_lang) counts only with
debug_tools on; anywhere else it is the
source.
Implementations§
Source§impl<G> Ctx<G>where
G: GameData,
impl<G> Ctx<G>where
G: GameData,
Sourcepub fn new(game: G) -> Result<Ctx<G>, Vec<&'static str>>
pub fn new(game: G) -> Result<Ctx<G>, Vec<&'static str>>
The shared context over the game’s part. Fails with the names of
the colors the game’s palette lacks. Starts with a
MemoryStorage, the default
settings and no layout chosen (so the layout picker’s keys are
active).
Sourcepub fn widths(&self) -> &CellWidths
pub fn widths(&self) -> &CellWidths
Which characters take two cells of the console, for a screen that
measures text before it has the frame to draw it in
(text_width): the font atlas’s
in the language text is shown in (effective_lang), as that
language has them (Lang::widths: its wide set, and its
punctuation wide or not, a pack’s or the source’s). The frame’s
(GlyphBuffer::widths) follow
them at each drawing.
Sourcepub fn note_reload(&mut self, id: &str, reload: &Reload)
pub fn note_reload(&mut self, id: &str, reload: &Reload)
Takes how the asset id reloaded (Hot::refresh’s answer): a
failure’s errors show at the top of the frame, where the backend has
a debug overlay, until id’s next good reload. Called from
Module::reloaded.
Sourcepub fn reload_errors(&self) -> &[String]
pub fn reload_errors(&self) -> &[String]
The errors of the reloads that failed and haven’t reloaded since, each with its file and line, one a line.
Sourcepub fn module_state<T>(&self) -> Option<&T>where
T: Any,
pub fn module_state<T>(&self) -> Option<&T>where
T: Any,
The state of type T a module put here
(Install::state), or None if no
installed module did.
Sourcepub fn module_state_mut<T>(&mut self) -> Option<&mut T>where
T: Any,
pub fn module_state_mut<T>(&mut self) -> Option<&mut T>where
T: Any,
module_state, mutable.
Sourcepub fn text<'a>(&'a self, key: &'a str) -> &'a str
pub fn text<'a>(&'a self, key: &'a str) -> &'a str
The screen text for key in the player’s language, placeholders
and all: the first text along its fallback chain
(Lang::chain) made from today’s source text, else the source’s.
A key the source lacks is a bug in the screen: it panics in debug builds, and shows as the key itself in release builds.
Sourcepub fn text_with(&self, key: &str, args: &[(&str, &dyn Display)]) -> String
pub fn text_with(&self, key: &str, args: &[(&str, &dyn Display)]) -> String
text with its placeholders filled in: each {name}
that args names by its value, and each that names a key (an
action’s name, GameData::key_text) by the key the player has
for it (help_keys).
Sourcepub fn label(&self, label: &Label) -> String
pub fn label(&self, label: &Label) -> String
What label says to the player: a key’s text filled in by
text_with, or the text as it is. What a skin
calls on the labels of the view it paints.
Sourcepub fn text_with_keys(
&self,
key: &str,
keys: HelpKeys<'_, <G as GameData>::Action>,
args: &[(&str, &dyn Display)],
) -> String
pub fn text_with_keys( &self, key: &str, keys: HelpKeys<'_, <G as GameData>::Action>, args: &[(&str, &dyn Display)], ) -> String
text_with, naming the keys keys has rather
than the active ones: for a screen steered by the keys it was
opened with while the player changes them.
Sourcepub fn effective_lang(&self) -> &LangCode
pub fn effective_lang(&self) -> &LangCode
The language text is shown in: lang, but the
game’s source language for its debug language without
debug_tools.
Sourcepub fn help_keys(&self) -> HelpKeys<'_, <G as GameData>::Action>
pub fn help_keys(&self) -> HelpKeys<'_, <G as GameData>::Action>
What help text names keys from: the active bindings on the device the player pressed last, and the words of a key’s name in the player’s language.
Sourcepub fn pick_music(&mut self, pool: &str) -> Option<String>
pub fn pick_music(&mut self, pool: &str) -> Option<String>
A music cue picked at random from the audio manifest’s pool
(pick_from_pool): the n-th pick of this run uses
music_seed mixed with n, so a fight started
again may get another track. None if there is no such pool or it
is empty.
Sourcepub fn set_voice_manifest(&mut self, source: &str)
pub fn set_voice_manifest(&mut self, source: &str)
Takes the text of the voice manifest the platform read, and keeps
the clips that may be played (GameData::voices). A manifest the
game can’t use leaves no voices and a warning in the log
(log).
Sourcepub fn has_voice(&self, line: &LineId) -> bool
pub fn has_voice(&self, line: &LineId) -> bool
Whether line has a voice clip that would play now: voices are on
and the line has a clip that isn’t stale.
Sourcepub fn play_voice(&mut self, line: &LineId)
pub fn play_voice(&mut self, line: &LineId)
Says line: plays its voice clip (the one for
GameData::voice_variant, where the line has several), stopping
the voice that is playing. Does nothing when voices are off or the
line has no clip that may be played.
Sourcepub fn voice_playing(&self) -> Option<&LineId>
pub fn voice_playing(&self) -> Option<&LineId>
The line whose voice clip is sounding, or asked for and still
loading; None in silence. The platform reports it each frame
through Game::set_voice_playing,
before the screens run: a clip that ended, was stopped or replaced,
whose file failed or that loaded too late to be played is None. A
clip paused with the game still sounds.
A screen sees its own play_voice from the next
frame, once the platform has read the request: in the frame it asks,
and on a platform with no voices, this is still None. So a screen
that waits for a voice to end waits for its line to sound first,
and takes None after that as the end. A clip that never sounds
(its file missing or slow) gives up within half a second: a screen
that hasn’t seen its line by then may move on.
Sourcepub fn stop_voice(&mut self)
pub fn stop_voice(&mut self)
Stops the voice that is playing, if any.
Sourcepub fn preload_voices(&mut self, lines: &[LineId])
pub fn preload_voices(&mut self, lines: &[LineId])
Tells the platform the lines a scene is about to say, in script order, so it loads their clips a few ahead. Lines without a playable clip are left out; nothing is sent when voices are off or none has one.
Sourcepub fn has_voices(&self) -> bool
pub fn has_voices(&self) -> bool
Whether any line has a voice clip that may be played: the platform found the clips and the game can use them. Voices off in the settings doesn’t change it, so a game can ask whether to play them.
Sourcepub fn layout(&self) -> Option<Layout>
pub fn layout(&self) -> Option<Layout>
The layout in use, or None if the player hasn’t picked one yet.
Sourcepub fn use_layout(&mut self, layout: Layout)
pub fn use_layout(&mut self, layout: Layout)
Switches to layout’s bindings (the player’s own for that layout,
else its defaults) for this session, without saving the choice.
Sourcepub fn refresh_keymap(&mut self)
pub fn refresh_keymap(&mut self)
Rebuilds keymap from the layout in use (the
layout picker’s keys while there is none) and the player’s
bindings: also after the game changed its keymap file
(GameData::keymap_def), such as a console’s own buttons.
Sourcepub fn keymap_for(&self, layout: Layout) -> Keymap<<G as GameData>::Action>
pub fn keymap_for(&self, layout: Layout) -> Keymap<<G as GameData>::Action>
The keymap layout would have: the player’s bindings for it, else
its defaults (a layout picker draws every layout with this).
Sourcepub fn player_keys(&self) -> &PlayerKeys<<G as GameData>::Action>
pub fn player_keys(&self) -> &PlayerKeys<<G as GameData>::Action>
The player’s key bindings for every layout.
Sourcepub fn layout_bindings(
&self,
layout: Layout,
) -> LayoutBindings<<G as GameData>::Action>
pub fn layout_bindings( &self, layout: Layout, ) -> LayoutBindings<<G as GameData>::Action>
layout’s current bindings, for a key bindings screen to edit and
hand back to set_layout_bindings.
Sourcepub fn set_layout_bindings(
&mut self,
layout: Layout,
bindings: LayoutBindings<<G as GameData>::Action>,
) -> Result<(), StorageError>
pub fn set_layout_bindings( &mut self, layout: Layout, bindings: LayoutBindings<<G as GameData>::Action>, ) -> Result<(), StorageError>
Replaces layout’s bindings and saves every layout’s under
KEYBINDINGS_KEY. If layout is in use, its keys work from the
next key press (Game hands the new keymap to its input at once).
The change applies even if saving fails (it is then lost on quit).
Sourcepub fn pad_bindings(&self) -> PadBindings<<G as GameData>::Action>
pub fn pad_bindings(&self) -> PadBindings<<G as GameData>::Action>
The player’s controller buttons (the defaults until they change
them), for a key bindings screen to edit and hand back to
set_pad_bindings. The same in every
layout.
Sourcepub fn set_pad_bindings(
&mut self,
bindings: PadBindings<<G as GameData>::Action>,
) -> Result<(), StorageError>
pub fn set_pad_bindings( &mut self, bindings: PadBindings<<G as GameData>::Action>, ) -> Result<(), StorageError>
Replaces the controller buttons and saves them under
KEYBINDINGS_KEY. They work from the next press, whatever the
layout (and before one is chosen). The change applies even if
saving fails (it is then lost on quit).
Sourcepub fn take_log(&mut self) -> (Vec<LogLine>, u32)
pub fn take_log(&mut self) -> (Vec<LogLine>, u32)
Takes the lines waiting, oldest first, and how many were dropped
before they were taken: for the platform’s App.
Sourcepub fn span<R>(
&mut self,
name: &'static str,
f: impl FnOnce(&mut Ctx<G>) -> R,
) -> R
pub fn span<R>( &mut self, name: &'static str, f: impl FnOnce(&mut Ctx<G>) -> R, ) -> R
Runs f as a span called name and gives back what it returns. In
a frame the platform measures (debug builds, with
debug_tools on), the span’s start, length and
depth go into the frame’s record (crate::perf); past
MAX_SPANS in a frame it is only
counted. With no clock, or outside a measured frame, it calls f
and reads nothing. Nothing reads a span’s time to decide anything.
With memory scopes (set_memory_scopes)
what f allocates counts under a tag named name
(TagClass::Span).
Sourcepub fn set_memory_scopes(&mut self, scopes: Option<MemoryScopes>)
pub fn set_memory_scopes(&mut self, scopes: Option<MemoryScopes>)
Hands the context the backend’s memory tags, or takes them away
(None): for the platform’s App, which moves them here when the
game runs, and for tests. With them the frame’s update and draw
and each span count what they allocate under a tag of their own
(crate::perf::MemoryScopes).
Sourcepub fn memory_scopes(&self) -> Option<MemoryScopes>
pub fn memory_scopes(&self) -> Option<MemoryScopes>
The memory tags, if the context has them.
Sourcepub fn session_recording(&self) -> bool
pub fn session_recording(&self) -> bool
Whether the platform is recording this run as a session, or playing
one back, so ask_session_save means
something: not until it says.
Sourcepub fn set_session_recording(&mut self, on: bool)
pub fn set_session_recording(&mut self, on: bool)
Says whether the platform is recording this run, or playing a record:
for the platform’s App. The same in a session and its playback, so
it is no value a record must hold.
Sourcepub fn ask_session_save(&mut self)
pub fn ask_session_save(&mut self)
Asks the platform to save the session so far, after this frame.
Sourcepub fn take_session_save(&mut self) -> bool
pub fn take_session_save(&mut self) -> bool
Takes the request of ask_session_save: for
the platform’s App.
Sourcepub fn set_perf_clock(&mut self, clock: Option<PerfClock>)
pub fn set_perf_clock(&mut self, clock: Option<PerfClock>)
Hands the context a clock to measure frames with, or takes it away
(None): for the platform’s App, which moves the backend’s clock
here when the game runs, and for tests.
Sourcepub fn perf_clock(&self) -> Option<PerfClock>
pub fn perf_clock(&self) -> Option<PerfClock>
The clock frames are measured with, if the context has one: for the
platform’s App and tests (a fake clock’s reads).
Sourcepub fn perf_now(&mut self) -> Option<u64>
pub fn perf_now(&mut self) -> Option<u64>
Reads the clock, if the context has one, in microseconds: for the
platform’s App, which times its own parts of a frame with it, and
for tests.
Sourcepub fn begin_perf_frame(&mut self) -> Option<u64>
pub fn begin_perf_frame(&mut self) -> Option<u64>
Starts measuring a frame, if the context has a clock: reads the
frame’s start (and gives it) and forgets the last frame’s spans.
For the platform’s App, at the start of a frame it measures.
Sourcepub fn end_perf_frame(&mut self) -> Option<FrameRecord>
pub fn end_perf_frame(&mut self) -> Option<FrameRecord>
Ends the frame being measured, reading nothing: its update’s and
drawing’s times and its spans, in a record of frame 0 that App
finishes. None if no frame was being measured.
Sourcepub fn take_warnings(&mut self) -> Vec<String>
pub fn take_warnings(&mut self) -> Vec<String>
Takes every line waiting, and returns the text of the warnings and
errors among them (e.g. repaired key bindings): for a front end
without the platform’s App.
Sourcepub fn with_layout(self, layout: Layout) -> Ctx<G>
pub fn with_layout(self, layout: Layout) -> Ctx<G>
Builder form of use_layout.
Sourcepub fn choose_layout(&mut self, layout: Layout) -> Result<(), StorageError>
pub fn choose_layout(&mut self, layout: Layout) -> Result<(), StorageError>
The player picked layout: switches to it (its own keys if the
player changed them, else its defaults) and saves it in the
settings. The switch happens even if saving fails (the player is
then asked again next launch).
Sourcepub fn saved_layout(&self) -> Option<Layout>
pub fn saved_layout(&self) -> Option<Layout>
The layout saved by an earlier choose_layout:
the saved settings’, else the one under the game’s
old key. None if nothing is saved, or
if the saved value can’t be read or isn’t a layout the keymap file
lists (the player is simply asked again).
Sourcepub fn shown_layout(&self) -> Option<Layout>
pub fn shown_layout(&self) -> Option<Layout>
The layout a screen about the keys shows: the one in use, else the
keymap file’s first (before a layout is chosen). None only for a
keymap without layouts, which no loaded one is.
Sourcepub fn change_settings(
&mut self,
change: impl FnOnce(&mut Settings<<G as GameData>::Settings>),
) -> Result<(), StorageError>
pub fn change_settings( &mut self, change: impl FnOnce(&mut Settings<<G as GameData>::Settings>), ) -> Result<(), StorageError>
Lets change edit the settings and, if it changed anything, saves
them under SETTINGS_KEY. The change applies even if saving
fails (it is then lost on quit).
Sourcepub fn preview_settings(
&mut self,
change: impl FnOnce(&mut Settings<<G as GameData>::Settings>),
) -> bool
pub fn preview_settings( &mut self, change: impl FnOnce(&mut Settings<<G as GameData>::Settings>), ) -> bool
Lets change edit the settings without saving them: the change
applies at once (the look, the sound), and is saved only by
keep_settings or the next
change_settings. Returns whether it
changed anything. The layout changes only with the keys
(choose_layout).
Sourcepub fn keep_settings(&mut self) -> Result<(), StorageError>
pub fn keep_settings(&mut self) -> Result<(), StorageError>
Saves the settings if they differ from what storage holds (a
previewed change, preview_settings).
Sourcepub fn restore_settings(
&mut self,
to: &Settings<<G as GameData>::Settings>,
) -> Result<(), StorageError>
pub fn restore_settings( &mut self, to: &Settings<<G as GameData>::Settings>, ) -> Result<(), StorageError>
Puts the settings back to to (all but the layout, which only the
keys change), as a previewed change thrown away. It saves only if
storage holds something else, which is so only if another change
was saved meanwhile (a fullscreen shortcut, a layout picked).
Sourcepub fn request_frame_cap(&mut self, cap: FrameCap) -> CapRequest
pub fn request_frame_cap(&mut self, cap: FrameCap) -> CapRequest
Asks for cap as the frame cap: it becomes the setting and is
saved, as change_settings does, and takes
the next serial even if it is the cap already, so the request is
confirmed either way. The platform applies it from the next frame;
check where it is with frame_cap_status.
A save that fails is logged, and the cap applies all the same.
Sourcepub fn frame_cap_status(&self, request: CapRequest) -> CapStatus
pub fn frame_cap_status(&self, request: CapRequest) -> CapStatus
Where request is: CapStatus::Superseded once a later change of
the cap has taken the next serial; CapStatus::Applied, with the
report, once the platform has reported its serial
(Game::set_pacing); else
CapStatus::Pending.
Sourcepub fn frame_cap_serial(&self) -> u32
pub fn frame_cap_serial(&self) -> u32
The serial of the latest change of the frame cap: what the platform is handed with the cap, and reports once it has applied it. 0 until the cap changes.
Sourcepub fn pacing(&self) -> Option<Pacing>
pub fn pacing(&self) -> Option<Pacing>
The platform’s last report of its pacing (the cap it applied, the
frames a second it measured), for a screen that shows the frame
rate; None until the platform reports, and on a platform that
never does.
Sourcepub fn with_storage(self, storage: Box<dyn Storage>) -> Ctx<G>
pub fn with_storage(self, storage: Box<dyn Storage>) -> Ctx<G>
Replaces the storage backend (tests keep the
MemoryStorage; the platform
installs its own), loads the profiles from it (profiles::load:
the last one used, the first made on a first launch, a player’s
keys from before profiles moved into it) and that profile’s key
bindings and settings.
Sourcepub fn set_debug_channel(
&mut self,
id: &str,
on: bool,
) -> Result<(), StorageError>
pub fn set_debug_channel( &mut self, id: &str, on: bool, ) -> Result<(), StorageError>
Turns the debug view’s channel id on or off (ADR-0085) and, with
debug tools on, saves the channels on under DEBUG_VIEW_KEY in
the computer’s storage, for the next launch. The change applies
even if saving fails. With debug tools off nothing is saved (and
nothing is drawn).
Sourcepub fn switch_profile(&mut self, id: ProfileId) -> Result<(), ProfileError>
pub fn switch_profile(&mut self, id: ProfileId) -> Result<(), ProfileError>
Makes id the profile in use: its settings, key bindings and layout
replace these (None if it has none yet: the layout picker’s keys),
and whatever else it keeps is its own from the next read
(storage). It is the one the next launch opens
on. The switch happens even if the list can’t be saved (the next
launch then opens on the profile used before).
Sourcepub fn add_profile(&mut self, name: &str) -> Result<ProfileId, ProfileError>
pub fn add_profile(&mut self, name: &str) -> Result<ProfileId, ProfileError>
Adds a profile called name, starting from the default options and
keys, and returns its id; the one in use stays. Refused (and
nothing changes) for a name that’s empty, too long or taken, past
MAX_PROFILES, or if the list can’t be
saved.
Sourcepub fn rename_profile(
&mut self,
id: ProfileId,
name: &str,
) -> Result<(), ProfileError>
pub fn rename_profile( &mut self, id: ProfileId, name: &str, ) -> Result<(), ProfileError>
Renames the profile id. Refused (and nothing changes) as
add_profile is.
Sourcepub fn delete_profile(&mut self, id: ProfileId) -> Result<(), ProfileError>
pub fn delete_profile(&mut self, id: ProfileId) -> Result<(), ProfileError>
Deletes the profile id and every key it holds, and no other
profile’s. If it was in use, the first profile left is
(switch_profile). Refused (and nothing
changes) for the only profile, or if the list can’t be saved; once
the list is saved, an error deleting its keys is returned with the
profile gone (they are never read again).