feat: add entity handles and a bevy channel abstraction
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
32
src/core/bevy_channel.rs
Normal file
32
src/core/bevy_channel.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use tokio::sync::mpsc::{self, error::TryRecvError};
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct BevyChannelReader<T: Send + Sync + 'static>(mpsc::UnboundedReceiver<T>);
|
||||
pub struct BevyChannel<T: Send + Sync + 'static>(OnceLock<mpsc::UnboundedSender<T>>);
|
||||
impl<T: Send + Sync + 'static> BevyChannel<T> {
|
||||
pub const fn new() -> Self {
|
||||
Self(OnceLock::new())
|
||||
}
|
||||
pub fn init(&self, app: &mut App) {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
self.0.set(tx).unwrap();
|
||||
app.insert_resource(BevyChannelReader(rx));
|
||||
}
|
||||
pub fn send(&self, msg: T) -> Option<()> {
|
||||
self.0.get()?.send(msg).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send + Sync + 'static> BevyChannelReader<T> {
|
||||
pub fn read(&mut self) -> Option<T> {
|
||||
match self.0.try_recv() {
|
||||
Ok(v) => Some(v),
|
||||
Err(TryRecvError::Disconnected) => panic!("bevy channel should never disconnect"),
|
||||
Err(TryRecvError::Empty) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/core/color.rs
Normal file
12
src/core/color.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use stardust_xr::values::color::{AlphaColor, Rgb, color_space::LinearRgb};
|
||||
|
||||
pub trait ColorConvert {
|
||||
fn to_bevy(&self) -> bevy::color::Color;
|
||||
}
|
||||
// even tho its supposed to be linear the values have to be interpreted as Srgba to produce the
|
||||
// correct result because StereoKit used Srgba while it was assumed that is uses linear rgba
|
||||
impl ColorConvert for AlphaColor<f32, Rgb<f32, LinearRgb>> {
|
||||
fn to_bevy(&self) -> bevy::color::Color {
|
||||
bevy::color::Color::srgba(self.c.r, self.c.g, self.c.b, self.a)
|
||||
}
|
||||
}
|
||||
33
src/core/entity_handle.rs
Normal file
33
src/core/entity_handle.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use super::bevy_channel::{BevyChannel, BevyChannelReader};
|
||||
pub struct EntityHandlePlugin;
|
||||
|
||||
impl Plugin for EntityHandlePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
DESTROY.init(app);
|
||||
app.add_systems(PreUpdate, despawn);
|
||||
}
|
||||
}
|
||||
|
||||
fn despawn(mut cmds: Commands, mut reader: ResMut<BevyChannelReader<Entity>>) {
|
||||
while let Some(e) = reader.read() {
|
||||
cmds.entity(e).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
static DESTROY: BevyChannel<Entity> = BevyChannel::new();
|
||||
#[derive(Deref, DerefMut, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct EntityHandle(pub Entity);
|
||||
impl Drop for EntityHandle {
|
||||
fn drop(&mut self) {
|
||||
if DESTROY.send(self.0).is_none() {
|
||||
error!("Entity Destroy channel not open");
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<Entity> for EntityHandle {
|
||||
fn from(value: Entity) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,5 @@ pub mod resource;
|
||||
pub mod scenegraph;
|
||||
pub mod task;
|
||||
pub mod color;
|
||||
pub mod entity_handle;
|
||||
pub mod bevy_channel;
|
||||
|
||||
Reference in New Issue
Block a user