96 lines
1.7 KiB
Rust
96 lines
1.7 KiB
Rust
|
use anyhow::{bail, Result};
|
||
|
use cgmath::Point2;
|
||
|
use std::collections::HashMap;
|
||
|
|
||
|
use crate::physics::Pfloat;
|
||
|
|
||
|
/// Toml file syntax
|
||
|
pub(in crate::content) mod toml {
|
||
|
use super::Pfloat;
|
||
|
use serde::Deserialize;
|
||
|
use std::collections::HashMap;
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
pub struct SystemRoot {
|
||
|
pub system: System,
|
||
|
pub object: HashMap<String, Object>,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
pub struct System {
|
||
|
pub name: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
pub struct Object {
|
||
|
pub sprite: String,
|
||
|
pub center: Center,
|
||
|
|
||
|
#[serde(default)]
|
||
|
pub radius: Pfloat,
|
||
|
#[serde(default)]
|
||
|
pub angle: Pfloat,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
#[serde(untagged)]
|
||
|
pub enum Center {
|
||
|
Label(String),
|
||
|
Coords([Pfloat; 2]),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct System {
|
||
|
name: String,
|
||
|
objects: Vec<Object>,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
struct Object {
|
||
|
sprite: String,
|
||
|
center: Point2<Pfloat>,
|
||
|
radius: Pfloat,
|
||
|
angle: Pfloat,
|
||
|
}
|
||
|
|
||
|
fn resolve_center(
|
||
|
objects: &HashMap<String, toml::Object>,
|
||
|
obj: &toml::Object,
|
||
|
) -> Option<Point2<f32>> {
|
||
|
match &obj.center {
|
||
|
toml::Center::Label(s) => resolve_center(&objects, objects.get(s)?),
|
||
|
toml::Center::Coords(v) => Some(Point2::from(*v)),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl System {
|
||
|
pub fn parse(value: toml::SystemRoot) -> Result<Self> {
|
||
|
let mut objects = Vec::new();
|
||
|
|
||
|
for (_, obj) in &value.object {
|
||
|
let center = match resolve_center(&value.object, obj) {
|
||
|
Some(v) => v,
|
||
|
None => {
|
||
|
bail!(
|
||
|
"Failed to parse content file: could not resolve center label `{:?}`",
|
||
|
obj.center
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
objects.push(Object {
|
||
|
sprite: obj.sprite.clone(),
|
||
|
center,
|
||
|
radius: obj.radius,
|
||
|
angle: obj.angle,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return Ok(Self {
|
||
|
name: value.system.name.clone(),
|
||
|
objects,
|
||
|
});
|
||
|
}
|
||
|
}
|