From 3bf0c5c48e13ca3daf7bf3db49c34ff43e55950b Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Tue, 22 Mar 2022 10:14:08 -0400 Subject: [PATCH] Basic rendering code in progress --- game/desktop_wrapper/src/main.rs | 3 ++ game/game_logic/src/lib.rs | 3 +- .../src/rendering/core_renderer_sm.rs | 16 ++++++++ game/game_logic/src/rendering/event_loop.rs | 40 +++++++++++++++++-- game/game_logic/src/rendering/mod.rs | 4 +- .../src/rendering/screens/loading_screen.rs | 26 ++++++++++++ game/game_logic/src/rendering/screens/mod.rs | 2 + .../rendering/screens/sm_failure_screen.rs | 27 +++++++++++++ 8 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 game/game_logic/src/rendering/core_renderer_sm.rs create mode 100644 game/game_logic/src/rendering/screens/loading_screen.rs create mode 100644 game/game_logic/src/rendering/screens/mod.rs create mode 100644 game/game_logic/src/rendering/screens/sm_failure_screen.rs diff --git a/game/desktop_wrapper/src/main.rs b/game/desktop_wrapper/src/main.rs index 7120a73a..c57b96de 100644 --- a/game/desktop_wrapper/src/main.rs +++ b/game/desktop_wrapper/src/main.rs @@ -32,4 +32,7 @@ async fn main() { log::info!("Starting game"); game_logic::entrypoint(args.force_recreate_savefiles).await; log::info!("Goodbye!"); + + // Exit the program + std::process::exit(0); } diff --git a/game/game_logic/src/lib.rs b/game/game_logic/src/lib.rs index 9fb34ff3..8fd77621 100644 --- a/game/game_logic/src/lib.rs +++ b/game/game_logic/src/lib.rs @@ -43,7 +43,7 @@ pub async fn entrypoint(force_recreate_savefiles: bool) { .await .expect("Failed to connect to Discord RPC"); let event_loop_discord_tx = discord.get_channel(); - let _discord_task_handle = discord.begin_thread_non_blocking(); + let discord_task_handle = discord.begin_thread_non_blocking(); // Set a base activity to show in Discord { @@ -77,4 +77,5 @@ pub async fn entrypoint(force_recreate_savefiles: bool) { save_state .save() .expect("Could not save game save state to disk."); + discord_task_handle.abort(); } diff --git a/game/game_logic/src/rendering/core_renderer_sm.rs b/game/game_logic/src/rendering/core_renderer_sm.rs new file mode 100644 index 00000000..d430ad6d --- /dev/null +++ b/game/game_logic/src/rendering/core_renderer_sm.rs @@ -0,0 +1,16 @@ +//! This module contains state machine definitions for the backend rendering system. + +sad_machine::state_machine! { + RenderBackendStates { + InitialStates { + Preload + } + FinishPreload { + Preload => Loading + } + FinishLoading { + // TODO: Make this hand off to the main render code + Loading => SmFailed + } + } +} diff --git a/game/game_logic/src/rendering/event_loop.rs b/game/game_logic/src/rendering/event_loop.rs index e6919ac9..c754bb84 100644 --- a/game/game_logic/src/rendering/event_loop.rs +++ b/game/game_logic/src/rendering/event_loop.rs @@ -1,12 +1,28 @@ -use raylib::RaylibBuilder; +//! The Event Loop module +//! +//! ## Overview +//! +//! This is the code that handles beginning each frame and ending it. Do not try to add your own game logic in here. +//! The event loop function has its own statemachine (`core_renderer_sm.rs`) that handles the current action. +//! +//! You can think of this as a bit of bootstrap code for the game. All that happens directly here is rendering of the loading screen and a bit of error handling. use crate::discord::DiscordChannel; +use crate::rendering::core_renderer_sm::{PreloadState, RenderBackendStates}; +use crate::rendering::screens::sm_failure_screen; +use raylib::RaylibBuilder; /// Will begin rendering graphics. Returns when the window closes -pub fn handle_graphics_blocking(config: ConfigBuilder, target_frames_per_second: u32, discord_signaling: DiscordChannel) -where +pub fn handle_graphics_blocking( + config: ConfigBuilder, + target_frames_per_second: u32, + discord_signaling: DiscordChannel, +) where ConfigBuilder: FnOnce(&mut RaylibBuilder), { + // Set up the backend rendering state machine + let mut backend_sm = RenderBackendStates::preload(); + // Let the caller configure Raylib's internal window stuff let (mut raylib_handle, raylib_thread) = { log::trace!("Configuring Raylib"); @@ -19,9 +35,27 @@ where raylib_handle.set_exit_key(None); raylib_handle.set_target_fps(target_frames_per_second); + // Set up the internal screens + let mut loading_screen = crate::rendering::screens::loading_screen::LoadingScreen::new(); + let mut sm_failure_screen = sm_failure_screen::SmFailureScreen::new(); + // Run the event loop log::trace!("Running event loop"); while !raylib_handle.window_should_close() { + // Handle state machine updates + match backend_sm { + RenderBackendStates::Preload(m @ PreloadState::FromInit) => { + backend_sm = m.finish_preload(); + } + RenderBackendStates::Loading(ref m) => { + if loading_screen.render(&mut raylib_handle, &raylib_thread, &discord_signaling) { + backend_sm = m.finish_loading(); + } + } + RenderBackendStates::SmFailed(ref m) => { + sm_failure_screen.render(&mut raylib_handle, &raylib_thread, &discord_signaling); + } + }; // Tell the profiler that we ended the frame profiling::finish_frame!(); diff --git a/game/game_logic/src/rendering/mod.rs b/game/game_logic/src/rendering/mod.rs index 883289b4..3d37aae0 100644 --- a/game/game_logic/src/rendering/mod.rs +++ b/game/game_logic/src/rendering/mod.rs @@ -1,4 +1,6 @@ //! This module contains lower level rendering logic. pub mod event_loop; -pub mod utilities; \ No newline at end of file +pub mod utilities; +pub mod screens; +mod core_renderer_sm; \ No newline at end of file diff --git a/game/game_logic/src/rendering/screens/loading_screen.rs b/game/game_logic/src/rendering/screens/loading_screen.rs new file mode 100644 index 00000000..d3eea8f1 --- /dev/null +++ b/game/game_logic/src/rendering/screens/loading_screen.rs @@ -0,0 +1,26 @@ +use raylib::prelude::*; + +use crate::discord::DiscordChannel; + +#[derive(Debug)] +pub struct LoadingScreen {} + +impl LoadingScreen { + /// Construct a new `LoadingScreen` + pub fn new() -> Self { + Self {} + } + + pub fn render( + &mut self, + raylib: &mut RaylibHandle, + rl_thread: &RaylibThread, + discord: &DiscordChannel, + ) -> bool { + let mut d = raylib.begin_drawing(&rl_thread); + + d.clear_background(raylib::color::Color::WHITE); + + true + } +} diff --git a/game/game_logic/src/rendering/screens/mod.rs b/game/game_logic/src/rendering/screens/mod.rs new file mode 100644 index 00000000..28f4670c --- /dev/null +++ b/game/game_logic/src/rendering/screens/mod.rs @@ -0,0 +1,2 @@ +pub mod loading_screen; +pub mod sm_failure_screen; \ No newline at end of file diff --git a/game/game_logic/src/rendering/screens/sm_failure_screen.rs b/game/game_logic/src/rendering/screens/sm_failure_screen.rs new file mode 100644 index 00000000..e0475d56 --- /dev/null +++ b/game/game_logic/src/rendering/screens/sm_failure_screen.rs @@ -0,0 +1,27 @@ +use raylib::prelude::*; + +use crate::discord::DiscordChannel; + +#[derive(Debug)] +pub struct SmFailureScreen {} + +impl SmFailureScreen { + /// Construct a new `SmFailureScreen` + pub fn new() -> Self { + Self {} + } + + pub fn render( + &mut self, + raylib: &mut RaylibHandle, + rl_thread: &RaylibThread, + discord: &DiscordChannel, + ) -> bool { + let mut d = raylib.begin_drawing(&rl_thread); + + d.clear_background(raylib::color::Color::RED); + d.draw_text("Backend Rendering Broke.\nYou should not be seeing this!", 10, 10, 40, raylib::color::Color::WHITE); + + false + } +}