use crate::*;
#[cfg(feature = "bevy")]
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy", derive(Bundle))]
pub struct LevelProperties {
pub name: NameInSite,
pub elevation: LevelElevation,
#[serde(default, skip_serializing_if = "is_default")]
pub global_floor_visibility: GlobalFloorVisibility,
#[serde(default, skip_serializing_if = "is_default")]
pub global_drawing_visibility: GlobalDrawingVisibility,
}
impl Default for LevelProperties {
fn default() -> Self {
Self {
name: NameInSite("<Unnamed>".to_owned()),
elevation: LevelElevation(0.0),
global_floor_visibility: Default::default(),
global_drawing_visibility: Default::default(),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(transparent)]
#[cfg_attr(feature = "bevy", derive(Component, Deref, DerefMut))]
pub struct LevelElevation(pub f32);
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Level {
pub properties: LevelProperties,
pub anchors: BTreeMap<u32, Anchor>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub doors: BTreeMap<u32, Door<u32>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub drawings: BTreeMap<u32, Drawing>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub floors: BTreeMap<u32, Floor<u32>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub lights: BTreeMap<u32, Light>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub physical_cameras: BTreeMap<u32, PhysicalCamera>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub walls: BTreeMap<u32, Wall<u32>>,
#[serde(default, skip_serializing_if = "RankingsInLevel::is_empty")]
pub rankings: RankingsInLevel,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub user_camera_poses: BTreeMap<u32, UserCameraPose>,
}
impl Level {
pub fn new(properties: LevelProperties, rankings: RankingsInLevel) -> Level {
Level {
properties,
rankings,
anchors: Default::default(),
doors: Default::default(),
drawings: Default::default(),
floors: Default::default(),
lights: Default::default(),
physical_cameras: Default::default(),
walls: Default::default(),
user_camera_poses: Default::default(),
}
}
}
#[derive(Default, Serialize, Deserialize, Debug, Clone)]
pub struct RankingsInLevel {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub floors: Vec<u32>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub drawings: Vec<u32>,
}
impl RankingsInLevel {
pub fn is_empty(&self) -> bool {
self.floors.is_empty() && self.drawings.is_empty()
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[serde(transparent)]
#[cfg_attr(feature = "bevy", derive(Component, Reflect))]
pub struct OnLevel<T: RefTrait>(pub Option<T>);
impl<T: RefTrait> Default for OnLevel<T> {
fn default() -> Self {
OnLevel(None)
}
}
impl<T: RefTrait> OnLevel<T> {
pub fn convert<U: RefTrait>(&self, id_map: &HashMap<T, U>) -> Result<OnLevel<U>, T> {
if let Some(x) = self.0 {
Ok(OnLevel(Some(id_map.get(&x).ok_or(x)?.clone())))
} else {
Ok(OnLevel(None))
}
}
}