scene: make scenes own its own world, no references

This commit is contained in:
SeanOMik 2024-03-24 22:40:38 -04:00
parent 763d51ae36
commit 61efc358ce
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
2 changed files with 10 additions and 62 deletions

7
Cargo.lock generated
View File

@ -984,12 +984,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fps_counter"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aaba7ff514ee9d802b562927f80b1e94e93d8e74c31b134c9c3762dabf1a36b"
[[package]] [[package]]
name = "fsevent-sys" name = "fsevent-sys"
version = "4.1.0" version = "4.1.0"
@ -3104,7 +3098,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-std", "async-std",
"fps_counter",
"lyra-engine", "lyra-engine",
"tracing", "tracing",
] ]

View File

@ -1,4 +1,4 @@
use std::{collections::VecDeque, ops::{Deref, DerefMut}}; use std::collections::VecDeque;
use lyra_ecs::{query::Entities, relation::ChildOf, Bundle, Component, Entity, World}; use lyra_ecs::{query::Entities, relation::ChildOf, Bundle, Component, Entity, World};
@ -21,77 +21,31 @@ pub struct SceneNodeFlag;
#[derive(Component)] #[derive(Component)]
pub struct SceneNodeRoot; pub struct SceneNodeRoot;
enum MutCow<'a, T> {
Mut(&'a mut T),
Owned(T),
}
impl<'a, T> Deref for MutCow<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
MutCow::Mut(t) => t,
MutCow::Owned(t) => t,
}
}
}
impl<'a, T> DerefMut for MutCow<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
MutCow::Mut(t) => t,
MutCow::Owned(t) => t,
}
}
}
/// A SceneGraph is a Graph of nodes that represents the hierarchy of a scene. /// A SceneGraph is a Graph of nodes that represents the hierarchy of a scene.
/// ///
/// This SceneGraph is special in the sense that it is literally just an ECS world with methods /// This SceneGraph is special in the sense that it is literally just an ECS world with methods
/// implemented for it that make it easier to use for a SceneGraph. /// implemented for it that make it easier to use for a SceneGraph.
//#[derive(Default)] //#[derive(Default)]
pub struct SceneGraph<'a> { pub struct SceneGraph {
pub(crate) world: MutCow<'a, World>, pub(crate) world: World,
root_node: SceneNode, root_node: SceneNode,
} }
impl<'a> SceneGraph<'a> { impl SceneGraph {
/// Create a new SceneGraph with its own ECS World. /// Create a new SceneGraph with its own ECS World.
pub fn new() -> Self { pub fn new() -> Self {
let mut world = World::new(); let world = World::new();
let e = world.spawn((Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), SceneNodeRoot)); Self::from_world(world)
let root = SceneNode::new(None, e);
Self {
world: MutCow::Owned(world),
root_node: root
}
}
/// Retrieve a SceneGraph from an ECS World.
///
/// Returns `None` if the `root_entity` was not created from a `SceneGraph` that was later
/// inserted into another world with [`SceneGraph::into_world`].
pub fn from_world(world: &'a mut World, root_entity: Entity) -> Option<Self> {
if world.view_one::<(&SceneNodeRoot, &Transform)>(root_entity).get().is_none() {
None
} else {
Some(Self {
world: MutCow::Mut(world),
root_node: SceneNode::new(None, root_entity),
})
}
} }
/// Create a new SceneGraph inside an existing ECS World. /// Create a new SceneGraph inside an existing ECS World.
pub fn new_from_world(world: &'a mut World) -> Self { pub fn from_world(mut world: World) -> Self {
let root_en = world.spawn((Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), SceneNodeRoot)); let root_en = world.spawn((Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), SceneNodeRoot));
let root = SceneNode::new(None, root_en); let root = SceneNode::new(None, root_en);
Self { Self {
world: MutCow::Mut(world), world,
root_node: root, root_node: root,
} }
} }
@ -185,7 +139,8 @@ impl<'a> SceneGraph<'a> {
where where
F: FnMut(&SceneNode, Transform), F: FnMut(&SceneNode, Transform),
{ {
let v = self.world.view::<(Entities, &Transform)>() let v = self.world
.view::<(Entities, &Transform)>()
.relates_to::<ChildOf>(start.entity()); .relates_to::<ChildOf>(start.entity());
for ((e, _), _rel) in v.iter() { for ((e, _), _rel) in v.iter() {