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",
]
[[package]]
name = "fps_counter"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aaba7ff514ee9d802b562927f80b1e94e93d8e74c31b134c9c3762dabf1a36b"
[[package]]
name = "fsevent-sys"
version = "4.1.0"
@ -3104,7 +3098,6 @@ version = "0.1.0"
dependencies = [
"anyhow",
"async-std",
"fps_counter",
"lyra-engine",
"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};
@ -21,77 +21,31 @@ pub struct SceneNodeFlag;
#[derive(Component)]
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.
///
/// 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.
//#[derive(Default)]
pub struct SceneGraph<'a> {
pub(crate) world: MutCow<'a, World>,
pub struct SceneGraph {
pub(crate) world: World,
root_node: SceneNode,
}
impl<'a> SceneGraph<'a> {
impl SceneGraph {
/// Create a new SceneGraph with its own ECS World.
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));
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),
})
}
Self::from_world(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 = SceneNode::new(None, root_en);
Self {
world: MutCow::Mut(world),
world,
root_node: root,
}
}
@ -185,7 +139,8 @@ impl<'a> SceneGraph<'a> {
where
F: FnMut(&SceneNode, Transform),
{
let v = self.world.view::<(Entities, &Transform)>()
let v = self.world
.view::<(Entities, &Transform)>()
.relates_to::<ChildOf>(start.entity());
for ((e, _), _rel) in v.iter() {