use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::ecs::render_layer::components::RenderLayer;
use crate::ecs::sprite::components::Sprite;
use crate::ecs::sprite_animator::components::SpriteAnimator;
use crate::ecs::sprite_particles::components::SpriteParticleEmitter;
use crate::ecs::tilemap::components::Tilemap;
use crate::ecs::tween::components::Tween;
use crate::ecs::visibility::components::Visibility;
pub const SCENE_2D_FORMAT_VERSION: u32 = 1;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Scene2D {
pub format_version: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub entities: Vec<SceneEntity2D>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub metadata: HashMap<String, serde_json::Value>,
}
impl Scene2D {
pub fn new(name: Option<&str>) -> Self {
Self {
format_version: SCENE_2D_FORMAT_VERSION,
name: name.map(|name| name.to_string()),
entities: Vec::new(),
metadata: HashMap::new(),
}
}
pub fn add_entity(&mut self, entity: SceneEntity2D) -> u32 {
let id = entity.id;
self.entities.push(entity);
id
}
pub fn find_entity(&self, id: u32) -> Option<&SceneEntity2D> {
self.entities.iter().find(|entity| entity.id == id)
}
pub fn find_entity_mut(&mut self, id: u32) -> Option<&mut SceneEntity2D> {
self.entities.iter_mut().find(|entity| entity.id == id)
}
pub fn root_entities(&self) -> impl Iterator<Item = &SceneEntity2D> {
self.entities
.iter()
.filter(|entity| entity.parent_id.is_none())
}
pub fn children_of(&self, parent_id: u32) -> impl Iterator<Item = &SceneEntity2D> {
self.entities
.iter()
.filter(move |entity| entity.parent_id == Some(parent_id))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneEntity2D {
pub id: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent_id: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sprite: Option<Sprite>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tilemap: Option<Tilemap>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sprite_animator: Option<SpriteAnimator>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tween: Option<Tween>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sprite_particle_emitter: Option<SpriteParticleEmitter>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub visibility: Option<Visibility>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub render_layer: Option<RenderLayer>,
}
impl SceneEntity2D {
pub fn new(id: u32) -> Self {
Self {
id,
parent_id: None,
name: None,
sprite: None,
tilemap: None,
sprite_animator: None,
tween: None,
sprite_particle_emitter: None,
visibility: None,
render_layer: None,
}
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn with_parent(mut self, parent_id: u32) -> Self {
self.parent_id = Some(parent_id);
self
}
pub fn with_sprite(mut self, sprite: Sprite) -> Self {
self.sprite = Some(sprite);
self
}
pub fn with_tilemap(mut self, tilemap: Tilemap) -> Self {
self.tilemap = Some(tilemap);
self
}
pub fn with_sprite_animator(mut self, sprite_animator: SpriteAnimator) -> Self {
self.sprite_animator = Some(sprite_animator);
self
}
pub fn with_tween(mut self, tween: Tween) -> Self {
self.tween = Some(tween);
self
}
pub fn with_sprite_particle_emitter(mut self, emitter: SpriteParticleEmitter) -> Self {
self.sprite_particle_emitter = Some(emitter);
self
}
pub fn with_visibility(mut self, visibility: Visibility) -> Self {
self.visibility = Some(visibility);
self
}
pub fn with_render_layer(mut self, render_layer: RenderLayer) -> Self {
self.render_layer = Some(render_layer);
self
}
}