diff options
author | Matthew Michelotti <michelotti.matthew@gmail.com> | 2017-12-29 14:06:40 -0600 |
---|---|---|
committer | Matthew Michelotti <michelotti.matthew@gmail.com> | 2017-12-29 14:06:40 -0600 |
commit | 690dcb0c461a71e8f87e5059de776c0dbdae0650 (patch) | |
tree | 87cb774a49863c0df62372858343714e673832bd | |
parent | 8b3b87130f254e2ede6ddbe69338d6ed9cc237d6 (diff) |
refactoring, preparing to add wasm backend
-rw-r--r-- | gate/src/input.rs | 95 | ||||
-rw-r--r-- | gate/src/lib.rs | 53 | ||||
-rw-r--r-- | gate/src/renderer/mod.rs | 4 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/mod.rs (renamed from gate/src/renderer/core_renderer/mod.rs) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/shader_util.rs (renamed from gate/src/renderer/core_renderer/shader_util.rs) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/sprite.frag (renamed from gate/src/renderer/core_renderer/sprite.frag) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/sprite.vert (renamed from gate/src/renderer/core_renderer/sprite.vert) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/sprite_program.rs (renamed from gate/src/renderer/core_renderer/sprite_program.rs) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/tiled.frag (renamed from gate/src/renderer/core_renderer/tiled.frag) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/tiled.vert (renamed from gate/src/renderer/core_renderer/tiled.vert) | 0 | ||||
-rw-r--r-- | gate/src/renderer/sdl_core_renderer/tiled_program.rs (renamed from gate/src/renderer/core_renderer/tiled_program.rs) | 0 | ||||
-rw-r--r-- | gate/src/sdl_core/app_clock.rs (renamed from gate/src/app_clock.rs) | 0 | ||||
-rw-r--r-- | gate/src/sdl_core/core_audio.rs (renamed from gate/src/audio.rs) | 29 | ||||
-rw-r--r-- | gate/src/sdl_core/event_handler.rs | 109 | ||||
-rw-r--r-- | gate/src/sdl_core/mod.rs (renamed from gate/src/core.rs) | 35 |
15 files changed, 180 insertions, 145 deletions
diff --git a/gate/src/input.rs b/gate/src/input.rs index 20f6cdb..81250b8 100644 --- a/gate/src/input.rs +++ b/gate/src/input.rs @@ -14,16 +14,6 @@ //! Structs related to user input. -use std::collections::HashSet; - -use sdl2::EventPump; -use sdl2::event::Event; -use sdl2::keyboard::Keycode as SdlKeyCode; - -use ::App; -use audio::Audio; -use asset_id::AppAssetId; - /// Events related to a keyboard key. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum KeyEvent { @@ -42,88 +32,3 @@ pub enum KeyCode { Return, Space, } - -pub(crate) struct EventHandler { - pump: EventPump, - held_keys: HashSet<KeyCode>, -} - -impl EventHandler { - pub fn new(pump: EventPump) -> EventHandler { - EventHandler { pump, held_keys: HashSet::new() } - } - - pub fn process_events<AS: AppAssetId, AP: App<AS>>(&mut self, app: &mut AP, audio: &mut Audio<AS>) -> bool { - for event in self.pump.poll_iter() { - match event { - Event::Quit { .. } => return false, - Event::KeyDown { keycode: Some(keycode), .. } => { - if let Some(keycode) = sdl_to_gate_key(keycode) { - if self.held_keys.insert(keycode) { - let continuing = app.input(KeyEvent::Pressed, keycode, audio); - if !continuing { return false } - } - } - }, - Event::KeyUp { keycode: Some(keycode), .. } => { - if let Some(keycode) = sdl_to_gate_key(keycode) { - if self.held_keys.remove(&keycode) { - let continuing = app.input(KeyEvent::Released, keycode, audio); - if !continuing { return false } - } - } - }, - _ => {}, - } - } - true - } -} - -fn sdl_to_gate_key(sdl: SdlKeyCode) -> Option<KeyCode> { - match sdl { - SdlKeyCode::A => Some(KeyCode::A), - SdlKeyCode::B => Some(KeyCode::B), - SdlKeyCode::C => Some(KeyCode::C), - SdlKeyCode::D => Some(KeyCode::D), - SdlKeyCode::E => Some(KeyCode::E), - SdlKeyCode::F => Some(KeyCode::F), - SdlKeyCode::G => Some(KeyCode::G), - SdlKeyCode::H => Some(KeyCode::H), - SdlKeyCode::I => Some(KeyCode::I), - SdlKeyCode::J => Some(KeyCode::J), - SdlKeyCode::K => Some(KeyCode::K), - SdlKeyCode::L => Some(KeyCode::L), - SdlKeyCode::M => Some(KeyCode::M), - SdlKeyCode::N => Some(KeyCode::N), - SdlKeyCode::O => Some(KeyCode::O), - SdlKeyCode::P => Some(KeyCode::P), - SdlKeyCode::Q => Some(KeyCode::Q), - SdlKeyCode::R => Some(KeyCode::R), - SdlKeyCode::S => Some(KeyCode::S), - SdlKeyCode::T => Some(KeyCode::T), - SdlKeyCode::U => Some(KeyCode::U), - SdlKeyCode::V => Some(KeyCode::V), - SdlKeyCode::W => Some(KeyCode::W), - SdlKeyCode::X => Some(KeyCode::X), - SdlKeyCode::Y => Some(KeyCode::Y), - SdlKeyCode::Z => Some(KeyCode::Z), - SdlKeyCode::Num0 => Some(KeyCode::Num0), - SdlKeyCode::Num1 => Some(KeyCode::Num1), - SdlKeyCode::Num2 => Some(KeyCode::Num2), - SdlKeyCode::Num3 => Some(KeyCode::Num3), - SdlKeyCode::Num4 => Some(KeyCode::Num4), - SdlKeyCode::Num5 => Some(KeyCode::Num5), - SdlKeyCode::Num6 => Some(KeyCode::Num6), - SdlKeyCode::Num7 => Some(KeyCode::Num7), - SdlKeyCode::Num8 => Some(KeyCode::Num8), - SdlKeyCode::Num9 => Some(KeyCode::Num9), - SdlKeyCode::Right => Some(KeyCode::Right), - SdlKeyCode::Left => Some(KeyCode::Left), - SdlKeyCode::Down => Some(KeyCode::Down), - SdlKeyCode::Up => Some(KeyCode::Up), - SdlKeyCode::Return => Some(KeyCode::Return), - SdlKeyCode::Space => Some(KeyCode::Space), - _ => None, - } -} diff --git a/gate/src/lib.rs b/gate/src/lib.rs index a1524c7..08fb848 100644 --- a/gate/src/lib.rs +++ b/gate/src/lib.rs @@ -122,10 +122,53 @@ extern crate byteorder; pub mod asset_id; pub mod renderer; pub mod app_info; -mod app_clock; -mod audio; -mod core; pub mod input; -pub use audio::Audio; -pub use core::{App, run}; +mod sdl_core; +use ::sdl_core as core; + +use std::marker::PhantomData; + +use core::CoreAudio; +use ::asset_id::{AppAssetId, IdU16}; +use ::input::{KeyEvent, KeyCode}; +use ::renderer::Renderer; +use ::app_info::AppInfo; + +/// Trait that a user can implement to specify application behavior, passed into `gate::run(...)`. +pub trait App<A: AppAssetId> { + /// Invoked when the application is first started, default behavior is a no-op. + fn start(&mut self, _audio: &mut Audio<A>) {} + + /// Advances the app state by a given amount of `seconds` (usually a fraction of a second). + fn advance(&mut self, seconds: f64, audio: &mut Audio<A>) -> bool; + + /// Invoked when user input is received (currently only keyboard presses/releases). + fn input(&mut self, event: KeyEvent, key: KeyCode, audio: &mut Audio<A>) -> bool; + + /// Render the app in its current state. + fn render(&mut self, renderer: &mut Renderer<A>); +} + +/// Invoke this in a `main` method to run the `App`. +/// +/// Will panic if this method is called more than once. +/// The `AppInfo` is used to specify intiailization parameters for the application. +pub fn run<AS: AppAssetId, AP: App<AS>>(info: AppInfo, app: AP) { core::run(info, app); } + + +/// Struct for audio playback. +pub struct Audio<A: AppAssetId> { core: CoreAudio, phantom: PhantomData<A> } + +impl<A: AppAssetId> Audio<A> { + pub(crate) fn new(core: CoreAudio) -> Audio<A> { Audio { core, phantom: PhantomData } } + + /// Plays the given sound effect once. + pub fn play_sound(&mut self, sound: A::Sound) { self.core.play_sound(sound.id_u16()); } + + /// Continually loops the given music, replacing the currently playing music, if any. + pub fn loop_music(&mut self, music: A::Music) { self.core.loop_music(music.id_u16()); } + + /// Stops the currently playing music, if any. + pub fn stop_music(&mut self) { self.core.stop_music(); } +} diff --git a/gate/src/renderer/mod.rs b/gate/src/renderer/mod.rs index ba8b5f9..b15e98d 100644 --- a/gate/src/renderer/mod.rs +++ b/gate/src/renderer/mod.rs @@ -20,9 +20,11 @@ mod geom; pub(crate) mod atlas; pub(crate) mod render_buffer; -pub(crate) mod core_renderer; mod renderer; mod vbo_packer; +pub(crate) mod sdl_core_renderer; +pub(crate) use self::sdl_core_renderer as core_renderer; + pub use self::renderer::*; pub use self::geom::Affine; diff --git a/gate/src/renderer/core_renderer/mod.rs b/gate/src/renderer/sdl_core_renderer/mod.rs index 2b0da0b..2b0da0b 100644 --- a/gate/src/renderer/core_renderer/mod.rs +++ b/gate/src/renderer/sdl_core_renderer/mod.rs diff --git a/gate/src/renderer/core_renderer/shader_util.rs b/gate/src/renderer/sdl_core_renderer/shader_util.rs index d20c168..d20c168 100644 --- a/gate/src/renderer/core_renderer/shader_util.rs +++ b/gate/src/renderer/sdl_core_renderer/shader_util.rs diff --git a/gate/src/renderer/core_renderer/sprite.frag b/gate/src/renderer/sdl_core_renderer/sprite.frag index 14477f4..14477f4 100644 --- a/gate/src/renderer/core_renderer/sprite.frag +++ b/gate/src/renderer/sdl_core_renderer/sprite.frag diff --git a/gate/src/renderer/core_renderer/sprite.vert b/gate/src/renderer/sdl_core_renderer/sprite.vert index c601eb6..c601eb6 100644 --- a/gate/src/renderer/core_renderer/sprite.vert +++ b/gate/src/renderer/sdl_core_renderer/sprite.vert diff --git a/gate/src/renderer/core_renderer/sprite_program.rs b/gate/src/renderer/sdl_core_renderer/sprite_program.rs index 968b5df..968b5df 100644 --- a/gate/src/renderer/core_renderer/sprite_program.rs +++ b/gate/src/renderer/sdl_core_renderer/sprite_program.rs diff --git a/gate/src/renderer/core_renderer/tiled.frag b/gate/src/renderer/sdl_core_renderer/tiled.frag index dd47fd0..dd47fd0 100644 --- a/gate/src/renderer/core_renderer/tiled.frag +++ b/gate/src/renderer/sdl_core_renderer/tiled.frag diff --git a/gate/src/renderer/core_renderer/tiled.vert b/gate/src/renderer/sdl_core_renderer/tiled.vert index 5a01436..5a01436 100644 --- a/gate/src/renderer/core_renderer/tiled.vert +++ b/gate/src/renderer/sdl_core_renderer/tiled.vert diff --git a/gate/src/renderer/core_renderer/tiled_program.rs b/gate/src/renderer/sdl_core_renderer/tiled_program.rs index 980a8c8..980a8c8 100644 --- a/gate/src/renderer/core_renderer/tiled_program.rs +++ b/gate/src/renderer/sdl_core_renderer/tiled_program.rs diff --git a/gate/src/app_clock.rs b/gate/src/sdl_core/app_clock.rs index 936405b..936405b 100644 --- a/gate/src/app_clock.rs +++ b/gate/src/sdl_core/app_clock.rs diff --git a/gate/src/audio.rs b/gate/src/sdl_core/core_audio.rs index 4182826..b7b7d5f 100644 --- a/gate/src/audio.rs +++ b/gate/src/sdl_core/core_audio.rs @@ -13,43 +13,32 @@ // limitations under the License. use std::path::PathBuf; -use std::marker::PhantomData; use sdl2::mixer::{self, Music}; -use asset_id::{AppAssetId, IdU16}; +pub struct CoreAudio { music: Option<Music<'static>>, sounds: Vec<mixer::Chunk> } -/// Struct for audio playback. -pub struct Audio<A: AppAssetId> { - music: Option<Music<'static>>, - sounds: Vec<mixer::Chunk>, - phantom: PhantomData<A>, -} - -impl<A: AppAssetId> Audio<A> { - pub(crate) fn new() -> Audio<A> { - let sounds: Vec<_> = (0..(A::Sound::count())) +impl CoreAudio { + pub(crate) fn new(sound_count: u16) -> CoreAudio { + let sounds: Vec<_> = (0..sound_count) .map(|id| PathBuf::from(format!("assets/sound{}.ogg", id))) .map(|p| mixer::Chunk::from_file(p).unwrap()) .collect(); - Audio { sounds, music: None, phantom: PhantomData } + CoreAudio { sounds, music: None } } - /// Plays the given sound effect once. - pub fn play_sound(&mut self, sound: A::Sound) { - mixer::Channel::all().play(&self.sounds[sound.id_u16() as usize], 0).unwrap(); + pub fn play_sound(&mut self, sound: u16) { + mixer::Channel::all().play(&self.sounds[sound as usize], 0).unwrap(); } - /// Continually loops the given music, replacing the currently playing music, if any. - pub fn loop_music(&mut self, music: A::Music) { - let music = &format!("assets/music{}.ogg", music.id_u16()); + pub fn loop_music(&mut self, music: u16) { + let music = &format!("assets/music{}.ogg", music); self.stop_music(); let music = mixer::Music::from_file(music).unwrap(); music.play(1_000_000).unwrap(); self.music = Some(music); } - /// Stops the currently playing music, if any. pub fn stop_music(&mut self) { if let Some(_) = self.music.take() { Music::halt(); diff --git a/gate/src/sdl_core/event_handler.rs b/gate/src/sdl_core/event_handler.rs new file mode 100644 index 0000000..6b21db5 --- /dev/null +++ b/gate/src/sdl_core/event_handler.rs @@ -0,0 +1,109 @@ +// Copyright 2017 Matthew D. Michelotti +// +// 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::collections::HashSet; + +use sdl2::EventPump; +use sdl2::event::Event; +use sdl2::keyboard::Keycode as SdlKeyCode; + +use ::App; +use ::Audio; +use ::asset_id::AppAssetId; +use ::input::{KeyEvent, KeyCode}; + +pub struct EventHandler { + pump: EventPump, + held_keys: HashSet<KeyCode>, +} + +impl EventHandler { + pub fn new(pump: EventPump) -> EventHandler { + EventHandler { pump, held_keys: HashSet::new() } + } + + pub fn process_events<AS: AppAssetId, AP: App<AS>>(&mut self, app: &mut AP, audio: &mut Audio<AS>) -> bool { + for event in self.pump.poll_iter() { + match event { + Event::Quit { .. } => return false, + Event::KeyDown { keycode: Some(keycode), .. } => { + if let Some(keycode) = sdl_to_gate_key(keycode) { + if self.held_keys.insert(keycode) { + let continuing = app.input(KeyEvent::Pressed, keycode, audio); + if !continuing { return false } + } + } + }, + Event::KeyUp { keycode: Some(keycode), .. } => { + if let Some(keycode) = sdl_to_gate_key(keycode) { + if self.held_keys.remove(&keycode) { + let continuing = app.input(KeyEvent::Released, keycode, audio); + if !continuing { return false } + } + } + }, + _ => {}, + } + } + true + } +} + +fn sdl_to_gate_key(sdl: SdlKeyCode) -> Option<KeyCode> { + match sdl { + SdlKeyCode::A => Some(KeyCode::A), + SdlKeyCode::B => Some(KeyCode::B), + SdlKeyCode::C => Some(KeyCode::C), + SdlKeyCode::D => Some(KeyCode::D), + SdlKeyCode::E => Some(KeyCode::E), + SdlKeyCode::F => Some(KeyCode::F), + SdlKeyCode::G => Some(KeyCode::G), + SdlKeyCode::H => Some(KeyCode::H), + SdlKeyCode::I => Some(KeyCode::I), + SdlKeyCode::J => Some(KeyCode::J), + SdlKeyCode::K => Some(KeyCode::K), + SdlKeyCode::L => Some(KeyCode::L), + SdlKeyCode::M => Some(KeyCode::M), + SdlKeyCode::N => Some(KeyCode::N), + SdlKeyCode::O => Some(KeyCode::O), + SdlKeyCode::P => Some(KeyCode::P), + SdlKeyCode::Q => Some(KeyCode::Q), + SdlKeyCode::R => Some(KeyCode::R), + SdlKeyCode::S => Some(KeyCode::S), + SdlKeyCode::T => Some(KeyCode::T), + SdlKeyCode::U => Some(KeyCode::U), + SdlKeyCode::V => Some(KeyCode::V), + SdlKeyCode::W => Some(KeyCode::W), + SdlKeyCode::X => Some(KeyCode::X), + SdlKeyCode::Y => Some(KeyCode::Y), + SdlKeyCode::Z => Some(KeyCode::Z), + SdlKeyCode::Num0 => Some(KeyCode::Num0), + SdlKeyCode::Num1 => Some(KeyCode::Num1), + SdlKeyCode::Num2 => Some(KeyCode::Num2), + SdlKeyCode::Num3 => Some(KeyCode::Num3), + SdlKeyCode::Num4 => Some(KeyCode::Num4), + SdlKeyCode::Num5 => Some(KeyCode::Num5), + SdlKeyCode::Num6 => Some(KeyCode::Num6), + SdlKeyCode::Num7 => Some(KeyCode::Num7), + SdlKeyCode::Num8 => Some(KeyCode::Num8), + SdlKeyCode::Num9 => Some(KeyCode::Num9), + SdlKeyCode::Right => Some(KeyCode::Right), + SdlKeyCode::Left => Some(KeyCode::Left), + SdlKeyCode::Down => Some(KeyCode::Down), + SdlKeyCode::Up => Some(KeyCode::Up), + SdlKeyCode::Return => Some(KeyCode::Return), + SdlKeyCode::Space => Some(KeyCode::Space), + _ => None, + } +} diff --git a/gate/src/core.rs b/gate/src/sdl_core/mod.rs index af65f2a..2f078d6 100644 --- a/gate/src/core.rs +++ b/gate/src/sdl_core/mod.rs @@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod app_clock; +mod core_audio; +mod event_handler; + +pub use self::core_audio::CoreAudio; + use std::sync::atomic::{AtomicBool, Ordering}; use std::ffi::CStr; use std::path::Path; @@ -28,30 +34,15 @@ use sdl2::render::{Renderer as SdlRenderer}; use gl; use gl::types::*; -use audio::Audio; +use ::{Audio, App}; use app_info::AppInfo; use renderer::Renderer; use renderer::core_renderer::CoreRenderer; use renderer::render_buffer::RenderBuffer; use renderer::atlas::Atlas; -use input::{KeyEvent, KeyCode, EventHandler}; -use asset_id::AppAssetId; -use app_clock::AppClock; - -/// Trait that a user can implement to specify application behavior, passed into `gate::run(...)`. -pub trait App<A: AppAssetId> { - /// Invoked when the application is first started, default behavior is a no-op. - fn start(&mut self, _audio: &mut Audio<A>) {} - - /// Advances the app state by a given amount of `seconds` (usually a fraction of a second). - fn advance(&mut self, seconds: f64, audio: &mut Audio<A>) -> bool; - - /// Invoked when user input is received (currently only keyboard presses/releases). - fn input(&mut self, event: KeyEvent, key: KeyCode, audio: &mut Audio<A>) -> bool; - - /// Render the app in its current state. - fn render(&mut self, renderer: &mut Renderer<A>); -} +use ::asset_id::{AppAssetId, IdU16}; +use self::app_clock::AppClock; +use self::event_handler::EventHandler; lazy_static! { static ref APP_CREATED: AtomicBool = AtomicBool::new(false); @@ -62,10 +53,6 @@ fn mark_app_created_flag() { assert!(!previously_created, "Cannot construct more than one App."); } -/// Invoke this in a `main` method to run the `App`. -/// -/// Will panic if this method is called more than once. -/// The `AppInfo` is used to specify intiailization parameters for the application. pub fn run<AS: AppAssetId, AP: App<AS>>(info: AppInfo, mut app: AP) { mark_app_created_flag(); @@ -94,7 +81,7 @@ pub fn run<AS: AppAssetId, AP: App<AS>>(info: AppInfo, mut app: AP) { gl_error_check(); - let mut audio = Audio::new(); + let mut audio = Audio::new(CoreAudio::new(AS::Sound::count())); if info.print_gl_info { print_gl_info(); } |