Added basic system file
parent
26a7693a72
commit
5279eeb7d4
|
@ -543,6 +543,7 @@ dependencies = [
|
|||
"rand",
|
||||
"serde",
|
||||
"toml",
|
||||
"walkdir",
|
||||
"wgpu",
|
||||
"winit",
|
||||
]
|
||||
|
@ -1382,6 +1383,15 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
|
@ -1675,6 +1685,16 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
|
|
@ -40,3 +40,4 @@ pollster = "0.3"
|
|||
anyhow = "1.0"
|
||||
cgmath = "0.18.0"
|
||||
rand = "0.8.5"
|
||||
walkdir = "2.4.0"
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# content type: system
|
||||
[system]
|
||||
name = "12 Autumn above"
|
||||
|
||||
[object.star]
|
||||
sprite = "star::a0"
|
||||
center = [0.0, 0.0]
|
||||
|
||||
[object.earth]
|
||||
sprite = "planet::earth"
|
||||
center = "star"
|
||||
radius = 200
|
||||
angle = 14
|
|
@ -0,0 +1,32 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use super::{syntax, ContentType};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Content {
|
||||
systems: Vec<syntax::System>,
|
||||
}
|
||||
|
||||
impl Content {
|
||||
pub fn new(cv: Vec<ContentType>) -> Result<Self> {
|
||||
let mut content = Self {
|
||||
systems: Vec::new(),
|
||||
};
|
||||
|
||||
// TODO: locate bad files
|
||||
|
||||
// These methods check intra-file consistency
|
||||
for c in cv {
|
||||
match c {
|
||||
ContentType::System(v) => content.add_system(v)?,
|
||||
};
|
||||
}
|
||||
|
||||
return Ok(content);
|
||||
}
|
||||
|
||||
fn add_system(&mut self, toml: syntax::system::toml::SystemRoot) -> Result<()> {
|
||||
self.systems.push(syntax::System::parse(toml)?);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
use anyhow::Result;
|
||||
use std::{fs::File, io::Read, path::Path};
|
||||
|
||||
use super::syntax;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ContentType {
|
||||
System(syntax::system::toml::SystemRoot),
|
||||
}
|
||||
|
||||
// TODO: check content without loading game
|
||||
impl ContentType {
|
||||
pub fn try_parse(file_string: &str) -> Result<Option<Self>> {
|
||||
// TODO: More advanced parsing, read the whole top comment
|
||||
let (first, _) = file_string.split_once("\n").unwrap();
|
||||
let type_spec = first[1..].trim(); // Remove hash
|
||||
|
||||
return Ok(match type_spec {
|
||||
"content type: system" => Some(Self::System(toml::from_str(&file_string)?)),
|
||||
_ => None,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn from_path(path: &Path) -> Result<Option<Self>> {
|
||||
let mut file_string = String::new();
|
||||
let _ = File::open(path)?.read_to_string(&mut file_string);
|
||||
let file_string = file_string.trim();
|
||||
return Self::try_parse(&file_string);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
mod content;
|
||||
mod contenttype;
|
||||
mod syntax;
|
||||
|
||||
pub use content::Content;
|
||||
pub use contenttype::ContentType;
|
|
@ -0,0 +1,3 @@
|
|||
#![allow(dead_code)]
|
||||
pub mod system;
|
||||
pub use system::System;
|
|
@ -0,0 +1,95 @@
|
|||
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,
|
||||
});
|
||||
}
|
||||
}
|
21
src/main.rs
21
src/main.rs
|
@ -1,3 +1,4 @@
|
|||
mod content;
|
||||
mod doodad;
|
||||
mod inputstatus;
|
||||
mod physics;
|
||||
|
@ -7,6 +8,8 @@ mod system;
|
|||
|
||||
use anyhow::Result;
|
||||
use cgmath::{Deg, Point2};
|
||||
use std::time::Instant;
|
||||
use walkdir::WalkDir;
|
||||
use winit::{
|
||||
event::{
|
||||
ElementState, Event, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase,
|
||||
|
@ -160,8 +163,6 @@ impl Game {
|
|||
}
|
||||
}
|
||||
|
||||
use std::time::Instant;
|
||||
|
||||
pub async fn run() -> Result<()> {
|
||||
let event_loop = EventLoop::new();
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
|
@ -230,6 +231,20 @@ pub async fn run() -> Result<()> {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
pollster::block_on(run())?;
|
||||
let mut raw_content = Vec::new();
|
||||
for e in WalkDir::new("content").into_iter().filter_map(|e| e.ok()) {
|
||||
if e.metadata().unwrap().is_file() {
|
||||
let c = crate::content::ContentType::from_path(e.path())?;
|
||||
match c {
|
||||
Some(c) => raw_content.push(c),
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let a = crate::content::Content::new(raw_content)?;
|
||||
println!("{:?}", a);
|
||||
|
||||
//pollster::block_on(run())?;
|
||||
return Ok(());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue