How can you mutate (or avoid the need to mutate) nested, constructed fields in Rust, without making everything mutable, when Cell can't be used? -
i'm pretty new rust , i've been following an arcade game tutorial has been great concepts goes through.
in part nine of tutorial, in main menu created, author suggests 'homework' reader of making labels on main menu ("new game", "quit") animate change in size when focused , unfocused, rather jump idle/focused size. have been having difficulty...
the basic layout of relevant parts of code before started implement change following:
// equivalent 'menu option' struct action { /// function executed if action chosen func: box<fn(&mut phi) -> viewaction>, label: &'static str, idle_sprite: sprite, // smaller (32) focus_sprite: sprite, // larger (38) // ... } impl action { fn new(phi: &mut phi, label: &'static str, func: box<fn(&mut phi) -> viewaction>) -> action { // ... } struct mainmenuview { actions: vec<action>, selected: i8, // ... } impl mainmenuview { pub fn new(phi: &mut phi) -> mainmenuview { // ... } } impl view mainmenuview { fn render(&mut self, phi: &mut phi, elapsed: f64) -> viewaction { // ... (i, action) in self.actions.iter().enumerate() { // ... } } } fn main() { ::phi::spawn("arcade shooter", |phi| { box::new(::views::main_menu::mainmenuview::new(phi)) }); }
my first thought animation make dynamically create sprite based on interpolated size between idle_size
and focus_size
using time elapsed since focus change using methods on action
focus , defocus change current_size
field used generate sprite sprite
field.
this required mutable binding of action
struct, took me little while work out there no let
binding anywhere, seemed possible changing constructor: action::new(...) -> &mut action
, , lots of explicitly marking lifetimes (which had own issues, getting long is). realised mainmenuview
have mutably bound well, @ point stopped path (i hadn't managed compile since starting it), seemed inelegant solution made mutable, surely defeating point of rust's immutability default...
i wondered whether create new mainmenuview
new action
new sprite
, work (changing view mainmenuview
), seems wasteful way change size of text , again pretty inelegant.
after that, remembered cell
, when trying make actions
mainmenuview
vec<cell<actions>>
, found cell
works copy
types. might have been ok (i don't have enough experience know), func
field of action
not implement copy
(and i'm not sure if can?) , action
cannot #[derive(copy)]
. dead end without restructuring large section of program not have func
in action
?
this end of main question - basically, do when have structs nested , want have deep field mutate, can't put cell
around (afaik)? , structural issue code such should avoiding issue in first place?
i realised solution vec<sprite>
in action
lot of sprites of different sizes transition eliminate need of aforementioned mutable. instinctively felt hacky, hardcoding shouldn't have be. see issues in implementation aligning frames (i'm new synchronising things frame timing well), , working maximum fps - although number of sprites dynamically created based on max fps when mainmenuview
constructed...
from tutorial, looks view::render
takes mainmenuview
mutable reference. mainmenuview
has ownership of action
values through vec
, means mutability transfers through them. means didn't have change in order mutable access action
values, except call iter_mut()
instead of iter()
in for
loop in implementation of view::render
mainmenuview
.
Comments
Post a Comment