diff --git a/.gitignore b/.gitignore index 81cf465..6a9e7df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /.vscode +*.log diff --git a/Cargo.lock b/Cargo.lock index 1d1505c..3ed703d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" + [[package]] name = "arrayvec" version = "0.5.2" @@ -77,17 +83,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9ff149ed9780025acfdb36862d35b28856bb693ceb451259a7164442f22fdc3" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -170,6 +165,19 @@ dependencies = [ "libc", ] +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi 0.3.9", +] + [[package]] name = "cloudabi" version = "0.1.0" @@ -443,23 +451,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] -name = "either" -version = "1.6.1" +name = "dtoa" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" [[package]] -name = "env_logger" -version = "0.8.2" +name = "either" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "flate2" @@ -623,7 +624,7 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] @@ -798,9 +799,12 @@ dependencies = [ [[package]] name = "humantime" -version = "2.0.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] [[package]] name = "ident_case" @@ -835,6 +839,12 @@ dependencies = [ "libc", ] +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + [[package]] name = "jni-sys" version = "0.3.0" @@ -907,6 +917,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if 0.1.10", + "serde", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e1ad45e4584824d760c35d71868dd7e6e5acd8f5195a9573743b369fc86cd6" +dependencies = [ + "arc-swap", + "chrono", + "flate2 1.0.14", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "parking_lot", + "serde", + "serde-value", + "serde_derive", + "serde_json", + "serde_yaml", + "thread-id", + "typemap", + "winapi 0.3.9", ] [[package]] @@ -1105,6 +1147,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -1312,6 +1364,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.7" @@ -1436,6 +1494,12 @@ dependencies = [ "owned_ttf_parser 0.6.0", ] +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "same-file" version = "1.0.6" @@ -1463,6 +1527,50 @@ version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +[[package]] +name = "serde-value" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a65a7291a8a568adcae4c10a677ebcedbc6c9cec91c054dee2ce40b0e3290eb" +dependencies = [ + "ordered-float 1.1.0", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + [[package]] name = "shared_library" version = "0.1.9" @@ -1541,16 +1649,17 @@ dependencies = [ name = "space-crush" version = "0.1.0" dependencies = [ - "env_logger", "futures", "gl", "glc", "glutin", "glyph_brush", "log", + "log4rs", "num_cpus", "ordered-float 2.0.0", "rand", + "serde_yaml", "shred", "shrev", "specs", @@ -1599,15 +1708,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.22" @@ -1628,6 +1728,17 @@ dependencies = [ "syn", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall", + "winapi 0.3.9", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -1637,6 +1748,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + [[package]] name = "tokio" version = "0.3.4" @@ -1656,6 +1778,12 @@ dependencies = [ "serde", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" + [[package]] name = "ttf-parser" version = "0.6.2" @@ -1694,12 +1822,30 @@ dependencies = [ "nom 5.1.2", ] +[[package]] +name = "typemap" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" +dependencies = [ + "unsafe-any", +] + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "unsafe-any" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" +dependencies = [ + "traitobject", +] + [[package]] name = "version_check" version = "0.9.2" @@ -1743,6 +1889,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wayland-client" version = "0.28.2" @@ -1949,6 +2101,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" +[[package]] +name = "yaml-rust" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zip" version = "0.5.8" diff --git a/space-crush/Cargo.toml b/space-crush/Cargo.toml index 929af78..d004b8c 100644 --- a/space-crush/Cargo.toml +++ b/space-crush/Cargo.toml @@ -5,16 +5,17 @@ authors = ["Bergmann89 "] edition = "2018" [dependencies] -env_logger = "0.8" futures = "0.3" gl = { version = "0.1", features = [ "use_log_crate" ] } glc = "0.1" glutin = "0.25" glyph_brush = "0.7" log = { version = "0.4", features = [ "max_level_trace", "release_max_level_warn" ] } +log4rs = "0.13" num_cpus = "1.13" ordered-float = "2.0" rand = "0.7" +serde_yaml = "0.8" shred = "0.10" shrev = "1.1" specs = "0.16" diff --git a/space-crush/resources/log4rs.yml b/space-crush/resources/log4rs.yml new file mode 100644 index 0000000..9b45cce --- /dev/null +++ b/space-crush/resources/log4rs.yml @@ -0,0 +1,28 @@ +root: + level: debug + appenders: + - stdout + - file + +appenders: + stdout: + kind: console + encoder: + pattern: "[{d} {h({l:>5})}] {m}{n}" + + file: + kind: rolling_file + path: space-crush.log + append: true + encoder: + pattern: "{d} {h({l:<5})}{n} Module: {M}{n} File: {f}:{L}{n} Message: {m}{n}" + policy: + kind: compound + trigger: + kind: size + limit: 1 mb + roller: + kind: fixed_window + pattern: space-crush-{}.log + count: 5 + base: 1 diff --git a/space-crush/src/app/misc/text.rs b/space-crush/src/app/misc/text.rs index e9b8c82..8bc1a75 100644 --- a/space-crush/src/app/misc/text.rs +++ b/space-crush/src/app/misc/text.rs @@ -28,9 +28,9 @@ use log::warn; use ordered_float::OrderedFloat; use specs::World; -use crate::Error; +use crate::{misc::Vfs, Error}; -use super::super::{misc::WorldHelper, resources::Vfs}; +use super::super::misc::WorldHelper; /* TextManager */ diff --git a/space-crush/src/app/misc/world.rs b/space-crush/src/app/misc/world.rs index 96ad2fd..5d7f931 100644 --- a/space-crush/src/app/misc/world.rs +++ b/space-crush/src/app/misc/world.rs @@ -9,9 +9,7 @@ use shred::{Fetch, FetchMut, Resource}; use shrev::{Event, EventChannel, ReaderId}; use specs::World; -use crate::Error; - -use super::super::resources::Vfs; +use crate::{misc::Vfs, Error}; pub trait WorldHelper { fn resource(&self) -> Result, Error> diff --git a/space-crush/src/app/mod.rs b/space-crush/src/app/mod.rs index 9a7f2ea..364c0bd 100644 --- a/space-crush/src/app/mod.rs +++ b/space-crush/src/app/mod.rs @@ -9,7 +9,7 @@ use crate::Error; use misc::{Events, TextManager, Window}; use render::{Debug, Init, Test}; -use resources::{Camera, Geometry, State, Vfs}; +use resources::{Camera, Geometry, State}; use systems::StateUpdate; pub struct App<'a, 'b> { @@ -24,7 +24,6 @@ impl<'a, 'b> App<'a, 'b> { let events = Events::new(world); let window = Window::new(events.handle())?; - world.insert(Vfs::new()?); world.insert(Camera::new()?); world.insert(Geometry::new()?); world.insert(State::default()); diff --git a/space-crush/src/app/resources/mod.rs b/space-crush/src/app/resources/mod.rs index f4f762c..8c41549 100644 --- a/space-crush/src/app/resources/mod.rs +++ b/space-crush/src/app/resources/mod.rs @@ -1,9 +1,7 @@ mod camera; mod geometry; mod state; -mod vfs; -pub use self::vfs::Vfs; pub use camera::Camera; pub use geometry::Geometry; pub use state::State; diff --git a/space-crush/src/lib.rs b/space-crush/src/lib.rs index b468dc5..4e18ad9 100644 --- a/space-crush/src/lib.rs +++ b/space-crush/src/lib.rs @@ -1,7 +1,7 @@ -mod app; -mod error; -mod server; +pub mod app; +pub mod misc; +pub mod server; pub use app::App; -pub use error::Error; +pub use misc::{init_logger, Error}; pub use server::Server; diff --git a/space-crush/src/main.rs b/space-crush/src/main.rs index 28f3d72..3a0ba70 100644 --- a/space-crush/src/main.rs +++ b/space-crush/src/main.rs @@ -1,17 +1,16 @@ use log::{error, info}; use specs::{World, WorldExt}; -use space_crush::{App, Error, Server}; +use space_crush::{init_logger, misc::Vfs, App, Error, Server}; fn main() -> Result<(), Error> { - env_logger::builder() - .filter_level(log::LevelFilter::Trace) - .format_timestamp_nanos() - .init(); + let vfs = Vfs::new()?; + + init_logger(&vfs); info!("Application started"); - if let Err(err) = run() { + if let Err(err) = run(vfs) { error!("Error while executing application: {}", err); return Err(err); @@ -22,8 +21,10 @@ fn main() -> Result<(), Error> { Ok(()) } -fn run() -> Result<(), Error> { +fn run(vfs: Vfs) -> Result<(), Error> { let mut world = World::new(); + world.insert(vfs); + let mut server = Server::new(&mut world); let mut app = App::new(&mut world)?; diff --git a/space-crush/src/error.rs b/space-crush/src/misc/error.rs similarity index 90% rename from space-crush/src/error.rs rename to space-crush/src/misc/error.rs index 47d4597..6d7f498 100644 --- a/space-crush/src/error.rs +++ b/space-crush/src/misc/error.rs @@ -3,6 +3,7 @@ use std::io::Error as IoError; use glc::error::Error as GlcError; use glutin::{ContextError as GlutinContextError, CreationError as GlutinCreationError}; use glyph_brush::ab_glyph::InvalidFont; +use serde_yaml::Error as YmlError; use thiserror::Error; use vfs::VfsError; use vfs_zip::Error as VfsZipError; @@ -18,6 +19,9 @@ pub enum Error { #[error("VFS ZIP Error: {0}")] VfsZipError(VfsZipError), + #[error("YML Error: {0}")] + YmlError(YmlError), + #[error("GLC Error: {0}")] GlcError(GlcError), @@ -61,6 +65,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: YmlError) -> Self { + Self::YmlError(err) + } +} + impl From for Error { fn from(err: GlcError) -> Self { Self::GlcError(err) diff --git a/space-crush/src/misc/log.rs b/space-crush/src/misc/log.rs new file mode 100644 index 0000000..67d7c0d --- /dev/null +++ b/space-crush/src/misc/log.rs @@ -0,0 +1,98 @@ +use std::io::{stderr, Write}; + +use log::{warn, LevelFilter}; +use log4rs::{ + append::{ + console::ConsoleAppender, + rolling_file::{ + policy::compound::{ + roll::fixed_window::FixedWindowRoller, trigger::size::SizeTrigger, CompoundPolicy, + }, + RollingFileAppender, + }, + }, + config::{Appender, Config, Root}, + encode::pattern::PatternEncoder, + file::{Deserializers, RawConfig}, + init_config, +}; +use serde_yaml::from_str; + +use crate::{misc::Vfs, Error}; + +pub fn init(vfs: &Vfs) { + let (config, err) = match load_from_file(vfs) { + Ok(config) => (config, None), + Err(err) => (default_config(), Some(err)), + }; + + init_config(config).expect("Unable to initialize logger"); + + if let Some(err) = err { + warn!("Unable to load log config from file: {}", err); + } +} + +fn load_from_file(vfs: &Vfs) -> Result { + let mut config = String::default(); + vfs.join("resources/log4rs.yml")? + .open_file()? + .read_to_string(&mut config)?; + + let mut stderr = stderr(); + let config = from_str::(&config)?; + let deserializers = Deserializers::default(); + + let (appenders, errors) = config.appenders_lossy(&deserializers); + for error in &errors { + let _ = writeln!(stderr, "log: {}", error); + } + + let (config, errors) = Config::builder() + .appenders(appenders) + .loggers(config.loggers()) + .build_lossy(config.root()); + for error in &errors { + let _ = writeln!(stderr, "log: {}", error); + } + + Ok(config) +} + +#[allow(clippy::identity_op)] +fn default_config() -> Config { + let mut root = Root::builder(); + let mut config = Config::builder(); + + let encoder = PatternEncoder::new("[{d} {h({l:>5})}] {m}{n}"); + let stdout = ConsoleAppender::builder() + .encoder(Box::new(encoder)) + .build(); + root = root.appender("stdout"); + config = config.appender(Appender::builder().build("stdout", Box::new(stdout))); + + if let Ok(roller) = FixedWindowRoller::builder() + .base(1) + .build("space-crush-{}.log", 5) + { + let path = "space-crush.log"; + let trigger = SizeTrigger::new(1 * 1024 * 1024); + let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller)); + let encoder = PatternEncoder::new( + "{d} {h({l:<5})}{n} Module: {M}{n} File: {f}:{L}{n} Message: {m}{n}", + ); + + if let Ok(file) = RollingFileAppender::builder() + .append(true) + .encoder(Box::new(encoder)) + .build(path, Box::new(policy)) + { + root = root.appender("file"); + config = config.appender(Appender::builder().build("file", Box::new(file))); + } + } + + config + .build(root.build(LevelFilter::Info)) + .expect("Unable to create default log config") +} diff --git a/space-crush/src/misc/mod.rs b/space-crush/src/misc/mod.rs new file mode 100644 index 0000000..48aec74 --- /dev/null +++ b/space-crush/src/misc/mod.rs @@ -0,0 +1,7 @@ +mod error; +mod log; +mod vfs; + +pub use self::log::init as init_logger; +pub use self::vfs::Vfs; +pub use error::Error; diff --git a/space-crush/src/app/resources/vfs.rs b/space-crush/src/misc/vfs.rs similarity index 100% rename from space-crush/src/app/resources/vfs.rs rename to space-crush/src/misc/vfs.rs