//! Scene graph and entity management.
//!
//! Stage 3 builds the world model every later system plugs into. Entities are
//! [`hecs`] handles living in a [`Scene`], which adds a parent/child
//! [`Transform`](crate::math::Transform) hierarchy on top of the bare ECS:
//!
//! - [`Scene`] — owns the entities and the hierarchy; spawn, despawn,
//!   reparent, query, and resolve world-space transforms
//! - [`Node`] — per-entity metadata (`name`, `enabled`)
//! - [`DespawnPolicy`] — whether despawning takes the subtree with it or
//!   detaches the children
//!
//! Local transforms are authored per entity; the scene resolves them against
//! the hierarchy on demand ([`Scene::world_transform`],
//! [`Scene::world_transforms`]). The node-baked hierarchy serializes to RON via
//! [`Scene::to_ron`] / [`Scene::from_ron`]; a registry-aware
//! [`SceneSnapshot`] (via [`Scene::snapshot`]) additionally captures every
//! reflected component, for play-mode restore and full scene files.
//!
//! `hecs` is re-exported as [`oxide_engine::hecs`](crate::hecs) so consumers
//! share one copy of [`Entity`](hecs::Entity) and the query API.

mod disabled;
mod graph;
mod node;
mod serialize;
mod snapshot;

pub use disabled::DisabledComponents;
pub use graph::{DespawnPolicy, Scene};
pub use node::Node;
pub use snapshot::SceneSnapshot;

// The handle type is part of the public scene API; re-export it here so callers
// can name it without reaching into the `hecs` re-export.
pub use hecs::Entity;

/// Errors produced by scene operations.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum SceneError {
    /// An operation referenced an entity that is not live in this scene.
    #[error("entity does not exist in this scene")]
    NoSuchEntity,

    /// A reparent would have made an entity its own ancestor.
    #[error("cannot parent an entity to itself or one of its descendants")]
    WouldCycle,

    /// Encoding the scene to RON failed.
    #[error("scene serialization failed: {0}")]
    Serialize(String),

    /// Decoding the scene from RON failed, or the data was inconsistent.
    #[error("scene deserialization failed: {0}")]
    Deserialize(String),
}
