1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
//! Adds utility queries
//!
//! These are common queries and resources grouped up, so everything
//! done here can be replicated with a normal query. You may not
//! need or want to use them but for quick prototyping they are useful to
//! have and not pollute your systems with many and/or complex types.
//!
//! [PixelBuffers] is a [WorldQuery] intented for more than one pixel buffer.
//!
//! [QueryPixelBuffer] is a [SystemParam] that groups the [PixelBuffers] query and
//! the [image](Image) [assets](Assets) resource. It has some convenience methods
//! when working with a single pixel buffer.
//!
//! # Examples
//!
//! For many pixel buffers
//! ```
//! # use bevy::prelude::*;
//! # use bevy_pixel_buffer::prelude::*;
//! fn example_system(mut images: ResMut<Assets<Image>>, pixel_buffers: Query<PixelBuffers>) {
//! for item in pixel_buffers.iter() {
//! images.frame(item).per_pixel(|_, _| Pixel::random())
//! }
//! }
//! # bevy::ecs::system::assert_is_system(example_system);
//! ```
//! Is equivalent to
//! ```
//! # use bevy::prelude::*;
//! # use bevy_pixel_buffer::prelude::*;
//! fn example_system(pixel_buffers: QueryPixelBuffer) {
//! let (query, mut images) = pixel_buffers.split();
//! for item in query.iter() {
//! images.frame(item).per_pixel(|_, _| Pixel::random())
//! }
//! }
//! # bevy::ecs::system::assert_is_system(example_system);
//! ```
//! ---
//! For a single pixel buffer
//!
//! ```
//! # use bevy::prelude::*;
//! # use bevy_pixel_buffer::prelude::*;
//! fn example_system(mut pb: QueryPixelBuffer) {
//! pb.frame().per_pixel(|_, _| Pixel::random());
//! }
//! # bevy::ecs::system::assert_is_system(example_system);
//! ```
use std::ops::{Deref, DerefMut};
use bevy::{ecs::system::SystemParam, prelude::*};
use crate::{
frame::{AsImageHandle, Frame, GetFrame},
pixel_buffer::PixelBuffer,
};
// #[derive(WorldQuery)] generates structs without documentation, put them inside
// here to allow that
mod queries {
use bevy::ecs::query::QueryData;
use super::*;
// cannot use #[cfg(feature = "egui")] inside the derive
#[cfg(not(feature = "egui"))]
/// Query to get the pixel buffers
///
/// See [module documentation](crate::query).
#[derive(QueryData)]
#[query_data(mutable, derive(Debug))]
pub struct PixelBuffers {
/// [Entity] of the pixel buffer
pub entity: Entity,
/// [PixelBuffer] component
pub pixel_buffer: &'static mut PixelBuffer,
/// Image handle
pub image_handle: &'static Handle<Image>,
}
#[cfg(feature = "egui")]
/// Query to get the pixel buffers.
///
/// See [module documentation](crate::query).
#[derive(QueryData)]
#[query_data(mutable, derive(Debug))]
pub struct PixelBuffers {
/// [Entity] of the pixel buffer
pub entity: Entity,
/// [PixelBuffer] component
pub pixel_buffer: &'static mut PixelBuffer,
/// Image handle
pub image_handle: &'static Handle<Image>,
/// [EguiTexture](crate::egui::EguiTexture) component.
///
/// Only available with the `egui` feature.
///
/// If the [PixelBufferEguiPlugin](crate::egui::PixelBufferEguiPlugin) is added
/// it will always be [Some].
pub egui_texture: Option<&'static crate::egui::EguiTexture>,
}
}
pub use queries::*;
impl AsImageHandle for crate::query::PixelBuffersReadOnlyItem<'_> {
fn as_image_handle(&self) -> &Handle<Image> {
self.image_handle
}
}
impl AsImageHandle for crate::query::PixelBuffersItem<'_> {
fn as_image_handle(&self) -> &Handle<Image> {
self.image_handle
}
}
/// System parameter to use in systems
#[derive(SystemParam)]
pub struct QueryPixelBuffer<'w, 's> {
pub(crate) query: Query<'w, 's, PixelBuffers>,
pub(crate) images: ResMut<'w, Assets<Image>>,
}
impl<'w, 's> Deref for QueryPixelBuffer<'w, 's> {
type Target = Query<'w, 's, PixelBuffers>;
fn deref(&self) -> &Self::Target {
&self.query
}
}
impl<'w, 's> DerefMut for QueryPixelBuffer<'w, 's> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.query
}
}
// Zheoni: Help, I can't make a way to iterate over Frame s... lifetimes
// and so many other problems :(
impl<'w, 's> QueryPixelBuffer<'w, 's> {
/// Get the image assets resource.
pub fn images(&mut self) -> &mut Assets<Image> {
&mut self.images
}
/// Gets the query and images resource
pub fn split(self) -> (Query<'w, 's, PixelBuffers>, ResMut<'w, Assets<Image>>) {
(self.query, self.images)
}
}
impl<'w, 's> GetFrame for QueryPixelBuffer<'w, 's> {
fn frame(&mut self) -> Frame<'_> {
let image_handle = self.query.single().image_handle;
Frame::extract(&mut self.images, image_handle)
}
}