Replies: 5 comments 1 reply
-
Not sure why my code didn't format correctly, I just click the "code" button, it creates the two ticks, then I paste my code between them, and the edit button doesn't seem to let me edit... Sorry. |
Beta Was this translation helpful? Give feedback.
-
i would also like to know how.
|
Beta Was this translation helpful? Give feedback.
-
Maybe let the struct borrow the query function parameter would make more sense? Or maybe I can just wipe all objects and recreate them every frame if it's not too expensive to do in the bevy ECS. But I would still like to figure out how to work with lifetimes in case it comes up somewhere else. Thanks for posting a reduced version of the question, that might help. |
Beta Was this translation helpful? Give feedback.
-
I might be wrong, but from fairly recent memory Query lifetimes are like this: Query<'w, 's, T, F> where:
So storing a Query (or QueryIter) in a struct, or passing it to a function, should look like: struct Thing<'w, 's> {
query: Query<'w, 's, (&'static TypeA, &'static TypeB), ()>
} I could be wrong about |
Beta Was this translation helpful? Give feedback.
-
I was having trouble getting that to work, but it occurred to me that I have to store the iterator, because the struct needs to remember where it is in the list between calls to draw (in my original code). |
Beta Was this translation helpful? Give feedback.
-
Hello, I am relatively new to rust, only written one program so far: https://retroprose.net/files/wasm-rust-render/
I feel like I have an handle on most of what rust has to offer, but can't seem to figure out more complex lifetime annotations. I'm just trying to borrow the query iterator in a struct that only has a lifetime until the end of the function, the same as the iterator itself. It seems like it would be legal since I did it with the other variables. I get a "borrowed value does not live long enough", is this even possible? What am I missing? Thanks.
`use bevy::{
prelude::*,
ecs::query::QueryIter,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
.insert_resource(Global::new())
.add_systems(Startup, setup)
.add_systems(Update, render)
.run();
}
// data structure to store global data
#[derive(Default, Resource)]
pub struct Global {
pub ascii_texture: Handle,
pub ascii_layout: Handle,
}
impl Global {
pub fn new() -> Self {
Default::default()
}
}
// the 'sprite batch' object that will display sprites with every call to draw
struct SpriteBatch<'a> {
commands: Commands<'a, 'a>,
// not sure how to specify this object type
//iter: &mut QueryIter<'a, 'a, (&'a mut Visibility, &'a mut Transform, &'a mut Sprite), ()>,
ascii_texture: Handle,
ascii_layout: Handle,
}
impl<'a> SpriteBatch<'a> {
// here iter is passed to this function, but I would rather have a reference in the struct
pub fn draw(&mut self, iter: &mut QueryIter<(&mut Visibility, &mut Transform, &mut Sprite), ()>, index: usize, p: Vec3) {
// here we set existing sprite data, and if we run out we just make more,
// essentially using the retained mode rendering as an immediate mode rendering
if let Some((mut visible, mut transform, mut sprite)) = iter.next() {
*visible = Visibility::Visible;
sprite.color = Color::rgba(1.0, 1.0, 1.0, 1.0);
sprite.texture_atlas = Some(TextureAtlas {
layout: self.ascii_layout.clone(),
index: index,
});
sprite.image = self.ascii_texture.clone();
transform.translation = Vec3::new(p.x, p.y, p.z);
transform.scale = Vec3::new(1.0, 1.0, 1.0);
} else {
// making more sprites to work with
self.commands.spawn((
Visibility::Visible,
Sprite::from_atlas_image(
self.ascii_texture.clone(),
TextureAtlas {
layout: self.ascii_layout.clone(),
index: index,
},
),
Transform {
translation: Vec3::new(p.x, p.y, p.z),
scale: Vec3::new(1.0, 1.0, 1.0),
..default()
}
));
}
}
}
// function that will take a series of draw calls to place sprites on the screen
fn render(
_time: Res,
mut commands: Commands,
mut global: ResMut,
mut query: Query<(&mut Visibility, &mut Transform, &mut Sprite)>,
) {
let mut iter = query.iter_mut();
}
// load textures and set up texture atlas
fn setup(
mut commands: Commands,
mut global: ResMut,
asset_server: Res,
mut texture_atlas_layouts: ResMut<Assets>,
) {
// a texture of ascii character bitmaps
// https://retroprose.net/files/test-cpp/assets/textures/tilemap.png
global.ascii_texture = asset_server.load("textures\tilemap.png");
let layout = TextureAtlasLayout::from_grid(UVec2::splat(8), 16, 256, None, None);
global.ascii_layout = texture_atlas_layouts.add(layout);
commands.spawn(Camera2d);
}`
Beta Was this translation helpful? Give feedback.
All reactions