From 12a88b07b92cfbe45bb50a94727a697884c98c54 Mon Sep 17 00:00:00 2001 From: Thinkofdeath Date: Tue, 29 Sep 2015 22:33:24 +0100 Subject: [PATCH] Base console implementation --- Cargo.lock | 1 + Cargo.toml | 1 + src/console/mod.rs | 157 ++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 26 ++++++-- src/ui/mod.rs | 1 + 5 files changed, 180 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c662aa2..c4c0bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,6 +7,7 @@ dependencies = [ "glfw 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9141397..dbc9146 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ image = "0.3.12" time = "0.1.32" rand = "0.3.11" rustc-serialize = "0.3" +log = "0.3.2" [dependencies.steven_gl] path = "./gl" diff --git a/src/console/mod.rs b/src/console/mod.rs index 3ec2281..6c7c9d7 100644 --- a/src/console/mod.rs +++ b/src/console/mod.rs @@ -15,6 +15,12 @@ use std::marker::PhantomData; use std::collections::HashMap; use std::any::Any; +use std::sync::{Arc, Mutex}; +use log; + +use ui; +use render; +use format::{Component, TextComponent, Color}; pub struct CVar { pub name: &'static str, @@ -34,14 +40,32 @@ pub trait Var { pub struct Console { vars: HashMap<&'static str, Box>, var_values: HashMap<&'static str, Box>, + + history: Vec, + + collection: ui::Collection, + active: bool, + position: f64, } impl Console { pub fn new() -> Console { - Console { + let mut con = Console { vars: HashMap::new(), var_values: HashMap::new(), + + history: Vec::with_capacity(200), + + collection: ui::Collection::new(), + active: false, + position: -220.0, + }; + for _ in 0 .. 200 { + con.history.push(Component::Text( + TextComponent::new("") + )); } + con } pub fn register(&mut self, var: CVar) where CVar : Var { @@ -60,4 +84,133 @@ impl Console { pub fn set(&mut self, var: CVar, val: T) where CVar : Var { self.var_values.insert(var.name, Box::new(val)); } -} \ No newline at end of file + + pub fn is_active(&self) -> bool { + self.active + } + + pub fn toggle(&mut self) { + self.active = !self.active; + } + + pub fn tick(&mut self, ui_container: &mut ui::Container, renderer: &mut render::Renderer, delta: f64, width: f64) { + // To make sure the console is always on top it constant removes and readds itself. + // Its hacky but the console should never appear for normal users so its not really + // a major issue. + self.collection.remove_all(ui_container); + if !self.active && self.position <= -220.0 { + return; + } + if self.active { + if self.position < 0.0 { + self.position += delta * 4.0; + } else { + self.position = 0.0; + } + } else { + if self.position > -220.0 { + self.position -= delta * 4.0; + } else { + self.position = -220.0; + } + } + let w = match ui_container.mode { + ui::Mode::Scaled => width, + ui::Mode::Unscaled(scale) => 854.0 / scale, + }; + + let mut background = ui::Image::new( + render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"), + 0.0, self.position, w, 220.0, + 0.0, 0.0, 1.0, 1.0, + 0, 0, 0 + ); + background.set_a(180); + let background = self.collection.add(ui_container.add(background)); + + let mut lines = Vec::new(); + let mut offset = 0.0; + for line in self.history.iter().rev() { + if offset >= 210.0 { + break; + } + let mut fmt = ui::Formatted::with_width_limit(renderer, line.clone(), 5.0, 5.0 + offset, w - 1.0); + fmt.set_parent(&background); + fmt.set_v_attach(ui::VAttach::Bottom); + offset += fmt.get_height(); + lines.push(ui_container.add(fmt)); + } + for fmt in lines { + self.collection.add(fmt); + } + } + + fn log(&mut self, record: &log::LogRecord) { + let mut file = record.location().file(); + if let Some(pos) = file.rfind("src/") { + file = &file[pos + 4..]; + } + println!("[{}:{}][{}] {}", file, record.location().line(), record.level(), record.args()); + self.history.remove(0); + let mut msg = TextComponent::new(""); + msg.modifier.extra = Some(vec![ + Component::Text(TextComponent::new("[")), + { + let mut msg = TextComponent::new(file); + msg.modifier.color = Some(Color::Green); + Component::Text(msg) + }, + Component::Text(TextComponent::new(":")), + { + let mut msg = TextComponent::new(&format!("{}", record.location().line())); + msg.modifier.color = Some(Color::Aqua); + Component::Text(msg) + }, + Component::Text(TextComponent::new("]")), + Component::Text(TextComponent::new("[")), + { + let mut msg = TextComponent::new(&format!("{}", record.level())); + msg.modifier.color = Some(match record.level() { + log::LogLevel::Debug => Color::Green, + log::LogLevel::Error => Color::Red, + log::LogLevel::Warn => Color::Yellow, + log::LogLevel::Info => Color::Aqua, + log::LogLevel::Trace => Color::Blue, + }); + Component::Text(msg) + }, + Component::Text(TextComponent::new("] ")), + Component::Text(TextComponent::new(&format!("{}", record.args()))) + ]); + self.history.push(Component::Text( + msg + )); + } +} + +pub struct ConsoleProxy { + console: Arc>, +} + +impl ConsoleProxy { + pub fn new(con: Arc>) -> ConsoleProxy { + ConsoleProxy { + console: con, + } + } +} + +impl log::Log for ConsoleProxy { + fn enabled(&self, metadata: &log::LogMetadata) -> bool { + metadata.level() <= log::LogLevel::Trace + } + + fn log(&self, record: &log::LogRecord) { + if self.enabled(record.metadata()) { + self.console.lock().unwrap().log(record); + } + } +} + +unsafe impl Send for ConsoleProxy {} +unsafe impl Sync for ConsoleProxy {} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d7e4421..5c691cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,8 +35,10 @@ extern crate hyper; extern crate flate2; extern crate rand; extern crate rustc_serialize; +#[macro_use] +extern crate log; -use std::sync::{Arc, RwLock}; +use std::sync::{Arc, RwLock, Mutex}; use std::marker::PhantomData; use glfw::{Action, Context, Key}; @@ -53,12 +55,19 @@ pub struct Game { renderer: render::Renderer, screen_sys: screen::ScreenSystem, resource_manager: Arc>, - console: console::Console, + console: Arc>, } fn main() { - let mut con = console::Console::new(); - con.register(CL_BRAND); + let con = Arc::new(Mutex::new(console::Console::new())); + con.lock().unwrap().register(CL_BRAND); + let proxy = console::ConsoleProxy::new(con.clone()); + log::set_logger(|max_log_level| { + max_log_level.set(log::LogLevelFilter::Trace); + Box::new(proxy) + }).unwrap(); + + info!("Starting steven"); let resource_manager = Arc::new(RwLock::new(resources::Manager::new())); { resource_manager.write().unwrap().tick(); } @@ -77,6 +86,7 @@ fn main() { gl::init(&mut window); window.set_key_polling(true); + window.set_char_polling(true); window.set_scroll_polling(true); window.set_mouse_button_polling(true); window.set_cursor_pos_polling(true); @@ -109,6 +119,7 @@ fn main() { game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container); let (width, height) = window.get_framebuffer_size(); + game.console.lock().unwrap().tick(&mut ui_container, &mut game.renderer, delta, width as f64); ui_container.tick(&mut game.renderer, delta, width as f64, height as f64); game.renderer.tick(delta, width as u32, height as u32); @@ -122,9 +133,16 @@ fn main() { fn handle_window_event(window: &mut glfw::Window, game: &mut Game, ui_container: &mut ui::Container, event: glfw::WindowEvent) { match event { + glfw::WindowEvent::Key(Key::GraveAccent, _, Action::Press, _) => { + game.console.lock().unwrap().toggle(); + } glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => { window.set_should_close(true) }, + + glfw::WindowEvent::Key(key, _, Action::Press, _) => { + println!("Key: {:?}", key); + }, glfw::WindowEvent::Scroll(x, y) => { game.screen_sys.on_scroll(x, y); }, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 27709a4..fd69708 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -248,6 +248,7 @@ impl Collection { for e in &self.elements { container.remove_raw(e); } + self.elements.clear(); } }