pub struct Far<T, G>{ /* private fields */ }bank only.Expand description
A pointer to a T living in group G’s bank.
Far is itself a plain value (just an address plus the group brand), so
it is Copy and may be stored and passed around freely. What it points at,
however, is only addressable when G’s bank is mapped, so it cannot be
dereferenced without a Bank<G> token. T may be data (e.g. [u8; N]) or
a function pointer (fn(..) -> R).
Use local / there for data and
invoke for functions, or erase to drop the
static group for dynamic dispatch.
§Examples
// Generated by `#[bank] static TILES: [u8; 256] = ..;`
// const TILES: Far<[u8; 256], Sprites> = ..;
fn first_tile(anchor: Anchor, bank: &mut Bank<GroupZero>, tiles: &Far<[u8; 256], Sprites>) -> u8 {
tiles.there(anchor, bank, |t| t[0]) // switch into Sprites, read, switch back
}Implementations§
Source§impl<T, G> Far<T, G>
impl<T, G> Far<T, G>
Sourcepub fn local<'a>(&self, _here: &'a Bank<G>) -> &'a T
pub fn local<'a>(&self, _here: &'a Bank<G>) -> &'a T
Read the data in place, given a token already in its bank: no switch.
The same-bank read. here proves G is mapped, so the data is addressable;
the reference borrows here, and a switch needs the token &mut, so it
cannot be held across a switch away from the bank. (The cross-bank borrow is
there.) A token of the wrong group is a type error:
fn wrong(b: &Bank<G1>, far: &Far<u8, G2>) -> u8 {
*far.local(b) // ERROR: a G2 far needs a G2 token, not G1
}Source§impl<T> Far<T, GroupZero>where
T: ?Sized,
impl<T> Far<T, GroupZero>where
T: ?Sized,
Sourcepub const fn resident(data: &'static T) -> Far<T, GroupZero>
pub const fn resident(data: &'static T) -> Far<T, GroupZero>
A far pointer to bank 0 data, built safely.
Safe because GroupZero is always mapped: the pointer is always valid,
so there is no bank-mapping precondition to uphold. Use it to hand bank-0
data to code written in terms of Far / DynFar, e.g. a dispatch table
mixing data from several banks.
data must genuinely live in bank 0: an ordinary
static or const, not a #[bank] static. Plain statics always qualify
(the linker keeps them in bank 0); only data deliberately placed in a
switchable bank would not, and the safe API gives no &'static reference to
such data anyway.
§Examples
static PALETTE: [u8; 4] = [0, 1, 2, 3];
let far: Far<[u8; 4], GroupZero> = Far::resident(&PALETTE);