This commit is contained in:
Thinkofdeath 2015-09-28 23:37:14 +01:00
parent db1c687c53
commit bdfc002e99
10 changed files with 206 additions and 30 deletions

50
src/console/mod.rs Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::marker::PhantomData;
pub struct CVar<T: Sized + 'static> {
pub name: &'static str,
pub ty: PhantomData<T>,
pub description: &'static str,
pub mutable: bool,
pub serializable: bool,
pub default: &'static Fn() -> T,
}
impl <T> CVar<T> {
}
impl Var for CVar<String> {}
pub trait Var {
}
pub struct Console {
vars: Vec<Box<Var>>,
}
impl Console {
pub fn new() -> Console {
Console {
vars: Vec::new(),
}
}
pub fn register<T>(&mut self, var: CVar<T>) where CVar<T> : Var {
self.vars.push(Box::new(var));
}
}

View File

@ -22,6 +22,8 @@ pub mod resources;
pub mod render;
pub mod ui;
pub mod screen;
#[macro_use]
pub mod console;
extern crate glfw;
extern crate image;
@ -35,9 +37,29 @@ extern crate rand;
extern crate rustc_serialize;
use std::sync::{Arc, RwLock};
use std::marker::PhantomData;
use glfw::{Action, Context, Key};
const CL_BRAND: console::CVar<String> = console::CVar {
ty: PhantomData,
name: "cl_brand",
description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \"Vanilla\"",
mutable: false,
serializable: false,
default: &|| "steven".to_owned(),
};
pub struct Game {
renderer: render::Renderer,
screen_sys: screen::ScreenSystem,
resource_manager: Arc<RwLock<resources::Manager>>,
console: console::Console,
}
fn main() {
let mut con = console::Console::new();
con.register(CL_BRAND);
let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
{ resource_manager.write().unwrap().tick(); }
@ -61,7 +83,7 @@ fn main() {
window.make_current();
glfw.set_swap_interval(1);
let mut renderer = render::Renderer::new(resource_manager.clone());
let renderer = render::Renderer::new(resource_manager.clone());
let mut ui_container = ui::Container::new();
let mut last_frame = time::now();
@ -70,51 +92,52 @@ fn main() {
let mut screen_sys = screen::ScreenSystem::new();
screen_sys.add_screen(Box::new(screen::Login::new()));
let mut game = Game {
renderer: renderer,
screen_sys: screen_sys,
resource_manager: resource_manager,
console: con,
};
while !window.should_close() {
{ resource_manager.write().unwrap().tick(); }
{ game.resource_manager.write().unwrap().tick(); }
let now = time::now();
let diff = now - last_frame;
last_frame = now;
let delta = (diff.num_nanoseconds().unwrap() as f64) / frame_time;
screen_sys.tick(delta, &mut renderer, &mut ui_container);
game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
let (width, height) = window.get_framebuffer_size();
ui_container.tick(&mut renderer, delta, width as f64, height as f64);
renderer.tick(delta, width as u32, height as u32);
ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
game.renderer.tick(delta, width as u32, height as u32);
window.swap_buffers();
glfw.poll_events();
for (_, event) in glfw::flush_messages(&events) {
handle_window_event(&mut window, &mut renderer, &mut screen_sys, &mut ui_container, event);
handle_window_event(&mut window, &mut game, &mut ui_container, event);
}
}
}
fn handle_window_event(
window: &mut glfw::Window,
renderer: &mut render::Renderer,
screen_sys: &mut screen::ScreenSystem,
ui_container: &mut ui::Container,
event: glfw::WindowEvent
) {
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::Escape, _, Action::Press, _) => {
window.set_should_close(true)
},
glfw::WindowEvent::Scroll(x, y) => {
screen_sys.on_scroll(x, y);
game.screen_sys.on_scroll(x, y);
},
glfw::WindowEvent::MouseButton(glfw::MouseButton::Button1, Action::Press, _) => {
glfw::WindowEvent::MouseButton(glfw::MouseButton::Button1, Action::Release, _) => {
let (width, height) = window.get_size();
let (xpos, ypos) = window.get_cursor_pos();
let (fw, fh) = window.get_framebuffer_size();
ui_container.click_at(screen_sys, renderer, xpos*((fw as f64)/(width as f64)), ypos*((fh as f64)/(height as f64)), fw as f64, fh as f64)
ui_container.click_at(game, xpos*((fw as f64)/(width as f64)), ypos*((fh as f64)/(height as f64)), fw as f64, fh as f64)
},
glfw::WindowEvent::CursorPos(xpos, ypos) => {
let (width, height) = window.get_size();
let (fw, fh) = window.get_framebuffer_size();
ui_container.hover_at(screen_sys, renderer, xpos*((fw as f64)/(width as f64)), ypos*((fh as f64)/(height as f64)), fw as f64, fh as f64)
ui_container.hover_at(game, xpos*((fw as f64)/(width as f64)), ypos*((fh as f64)/(height as f64)), fw as f64, fh as f64)
}
_ => {}
}

View File

@ -1,3 +1,19 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::rc::Rc;
use ui;
use render;
@ -31,7 +47,9 @@ impl super::Screen for Login {
let re = ui_container.add(login);
txt.set_parent(&re);
let tre = ui_container.add(txt);
super::button_action(ui_container, re.clone(), Some(tre.clone()), None);
super::button_action(ui_container, re.clone(), Some(tre.clone()), Some(Rc::new(|game, _| {
game.screen_sys.replace_screen(Box::new(super::ServerList::new(None)));
})));
elements.add(re);
elements.add(tre);

View File

@ -1,3 +1,16 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
mod server_list;
pub use self::server_list::*;
@ -59,6 +72,11 @@ impl ScreenSystem {
}
}
pub fn replace_screen(&mut self, screen: Box<Screen>) {
self.pop_screen();
self.add_screen(screen);
}
pub fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
for screen in &mut self.remove_queue {
if screen.active {
@ -153,8 +171,8 @@ pub fn button_action(ui_container: &mut ui::Container,
click: Option<ui::ClickFunc>
) {
let batch = ui_container.get_mut(&btn);
batch.add_hover_func(Rc::new(move |over, _, renderer, ui_container| {
let texture = render::Renderer::get_texture(renderer.get_textures_ref(), "gui/widgets").relative(
batch.add_hover_func(Rc::new(move |over, game, ui_container| {
let texture = render::Renderer::get_texture(game.renderer.get_textures_ref(), "gui/widgets").relative(
0.0, (if over { 86.0 } else { 66.0 }) / 256.0, 200.0 / 256.0, 20.0 / 256.0
);

View File

@ -1,3 +1,16 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fs;
use std::thread;
@ -143,12 +156,12 @@ impl ServerList {
let back = ui_container.get_mut(&server.back);
let back_ref = server.back.clone();
let address = address.clone();
back.add_hover_func(Rc::new(move |over, _, _, ui_container| {
back.add_hover_func(Rc::new(move |over, _, ui_container| {
let back = ui_container.get_mut(&back_ref);
back.set_a(if over { 200 } else { 100 });
}));
back.add_click_func(Rc::new(move |_, _, _| {
back.add_click_func(Rc::new(move |_, _| {
println!("Connecting to {}", address);
}));
}
@ -272,7 +285,7 @@ impl super::Screen for ServerList {
txt.set_parent(&re);
let tre = ui_container.add(txt);
let nr = self.needs_reload.clone();
super::button_action(ui_container, re.clone(), Some(tre.clone()), Some(Rc::new(move |_, _, _| {
super::button_action(ui_container, re.clone(), Some(tre.clone()), Some(Rc::new(move |_, _| {
*nr.borrow_mut() = true;
})));
elements.add(re);

View File

@ -1,3 +1,17 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[derive(Clone, Copy)]
pub struct BatchRef<T: UIElement> {
index: usize,

View File

@ -1,3 +1,16 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
ui_element!(Formatted {
val: format::Component,

View File

@ -1,3 +1,17 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
ui_element!(Image {
texture: render::Texture,
width: f64,

View File

@ -20,7 +20,6 @@ use std::rc::Rc;
use rand;
use render;
use format;
use screen;
const SCALED_WIDTH: f64 = 854.0;
const SCALED_HEIGHT: f64 = 480.0;
@ -33,8 +32,8 @@ pub enum Element {
None,
}
pub type ClickFunc = Rc<Fn(&mut screen::ScreenSystem, &mut render::Renderer, &mut Container)>;
pub type HoverFunc = Rc<Fn(bool, &mut screen::ScreenSystem, &mut render::Renderer, &mut Container)>;
pub type ClickFunc = Rc<Fn(&mut ::Game, &mut Container)>;
pub type HoverFunc = Rc<Fn(bool, &mut ::Game, &mut Container)>;
macro_rules! element_impl {
($($name:ident),+) => (
@ -372,7 +371,7 @@ impl Container {
map
}
pub fn click_at(&mut self, screen_sys: &mut screen::ScreenSystem, renderer: &mut render::Renderer, x: f64, y: f64, width: f64, height: f64) {
pub fn click_at(&mut self, game: &mut ::Game, x: f64, y: f64, width: f64, height: f64) {
let (sw, sh) = match self.mode {
Mode::Scaled => (SCALED_WIDTH / width, SCALED_HEIGHT / height),
Mode::Unscaled(scale) => (scale, scale),
@ -393,12 +392,12 @@ impl Container {
}
if let Some(click) = click {
for c in &click {
c(screen_sys, renderer, self);
c(game, self);
}
}
}
pub fn hover_at(&mut self, screen_sys: &mut screen::ScreenSystem, renderer: &mut render::Renderer, x: f64, y: f64, width: f64, height: f64) {
pub fn hover_at(&mut self, game: &mut ::Game, x: f64, y: f64, width: f64, height: f64) {
let (sw, sh) = match self.mode {
Mode::Scaled => (SCALED_WIDTH / width, SCALED_HEIGHT / height),
Mode::Unscaled(scale) => (scale, scale),
@ -421,7 +420,7 @@ impl Container {
};
if call {
for f in &hover.1 {
f(hover.2, screen_sys, renderer, self);
f(hover.2, game, self);
}
}
}

View File

@ -1,3 +1,17 @@
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
ui_element!(Text {
val: String,
width: f64,