From 32aa330b33026252839bf6900da54c11dc32ac2b Mon Sep 17 00:00:00 2001 From: Avery Date: Thu, 17 Apr 2025 12:42:53 +0200 Subject: [PATCH] Add doc comments to various things Doc comments were added to: - States and their components, expaining their meaning - Traits - Functions transitioning game state --- src/game/mod.rs | 3 +++ src/input/mod.rs | 11 ++++++---- src/main.rs | 16 +++++++++++++++ src/render/cube.rs | 2 ++ src/render/in_world.rs | 4 ++++ src/render/loading_world.rs | 40 ++++++++++++++++++++++++++++++++++--- src/render/mod.rs | 8 ++++---- 7 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/game/mod.rs b/src/game/mod.rs index f284bc3..de1f55d 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -24,6 +24,9 @@ pub struct Camera { } impl Game { + /// The main gameloop, this will exit the program is the game is requested to close, + /// or return to the [`RenderAvailable`] state if the world is closed and we want to + /// return to a menu. pub fn main_loop(mut self) -> Game { println!("Starting main loop"); let mut event_pump = self diff --git a/src/input/mod.rs b/src/input/mod.rs index 6abb388..cf7c778 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -5,15 +5,18 @@ use sdl2::{ mouse::MouseState, }; -// More methods to be added for other forms of input +/// The generic interface for input handling, this is supposed to be implemented for +/// the game in a specific state, see [`ingame_input`] for an example. +/// More methods to be added for other forms of input pub trait InputHandler { - // Handle keys which are meant to be held down and repeated every frame, ex movement keys + /// Handle keys which are meant to be held down and repeated every frame, ex movement keys fn handle_cont_key(&mut self, keycode: Keycode) {} - // Handle single keypresses or keys held down after the repear delay + /// Handle single key presses or keys held down after the repear delay fn handle_keydown(&mut self, keycode: Keycode, modifier: Mod, repeat: bool) {} + /// Handle single key releases fn handle_keyup(&mut self, keycode: Keycode, modifier: Mod, repeat: bool) {} - // Handle mouse movements + /// Handle mouse movements fn handle_mouse_motion(&mut self, state: MouseState, abs: (i32, i32), rel: (i32, i32)) {} } diff --git a/src/main.rs b/src/main.rs index a6e0f90..15a7ac4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,8 @@ pub struct Unstarted; impl GameState for Unstarted {} +/// The render context, this is what is used in most of the rendering, +/// contains everything we create in and need after [`RenderAvailable`] pub struct RenderCtx { entry: Entry, instance: Instance, @@ -38,12 +40,17 @@ pub struct RenderCtx { host_invis_idx: u32, } +/// Our window, holds the width and height, since we track those independent of Sdl and +/// the window Sdl gave us, since if we lose that, everything explodes pub struct Window { width: u32, height: u32, _sdl: SdlWindow, } +/// The render avalable state, this is the bare minimun state that is not +/// [`Unstarted`], from here we can transition into [`LoadingWorld`] or in +/// the future Menus and such pub struct RenderAvailable { sdl_context: Sdl, window: Window, @@ -52,6 +59,9 @@ pub struct RenderAvailable { impl GameState for RenderAvailable {} +/// The state in which we can load a world, this means loading the actual +/// world data, as well as adding components to be rendered, or potentially +/// loading mods. pub struct LoadingWorld { sdl_context: Sdl, window: Window, @@ -68,6 +78,8 @@ pub struct LoadingWorld { impl GameState for LoadingWorld {} +/// We are now in a running world and can render this world and do +/// things like movenent or (in the future) physics pub struct InWorld { sdl_context: Sdl, window: Window, @@ -114,9 +126,13 @@ fn main() { .unwrap(); let game = Game::new().init_render(sdl_context, window); + + // Hardcoded loading of a world, skybox + 1 cube let mut game = game.start_load_world(); let cube = game.create_cube(); game.add_component(cube); let game = game.start_world(); + + // Run the actual game let game = game.main_loop(); } diff --git a/src/render/cube.rs b/src/render/cube.rs index 563577a..7aab60b 100644 --- a/src/render/cube.rs +++ b/src/render/cube.rs @@ -267,6 +267,8 @@ impl RenderCtx { } impl Game { + /// Create a cube to be rendered in world, this can then be + /// added using [`Game::add_component`] pub fn create_cube(&self) -> Cube { let Self { state: LoadingWorld { ctx, pass, .. }, diff --git a/src/render/in_world.rs b/src/render/in_world.rs index ef08b88..586c965 100644 --- a/src/render/in_world.rs +++ b/src/render/in_world.rs @@ -12,6 +12,7 @@ use super::{ }; impl Game { + /// Rebuild the swapchain in response to a resize of the window pub fn window_resize(&mut self, size: (u32, u32)) { let Self { state: @@ -71,6 +72,7 @@ impl Game { ); } + /// Render a single frame pub fn render_frame(&self) { let Self { state: @@ -259,6 +261,8 @@ impl Game { ); }); + // FIXME: We currently get away with hardcoding these number + // because all we draw are cubes, but not for long I suspect dev.cmd_draw(*cmd_buf, 36, 1, 0, 0); } diff --git a/src/render/loading_world.rs b/src/render/loading_world.rs index 5ae25eb..2dcc893 100644 --- a/src/render/loading_world.rs +++ b/src/render/loading_world.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, iter}; use ash::{ khr::{surface, swapchain}, - vk::{self, DescriptorSet}, + vk::{self}, }; use crate::{ @@ -19,11 +19,22 @@ use super::{ /// Anything can be rendered in world pub trait WorldComponent { + /// Return the types and number of descriptors this component wants to use fn descriptors(&self) -> HashMap; + /// Return the layout of the descriptor set this component wants to used, + /// the used descriptors should match [`WorldComponent::descriptors`] fn desc_layout(&self, ctx: &RenderCtx) -> vk::DescriptorSetLayout; - /// Skybox is passed in for reflections + /// Write to this components descriptor set, the passed descriptor set + /// is layed out like was requested in [`WorldComponent::desc_layout`] + /// + /// Skybox is currently passed in for reflections + /// + /// Note: + /// This api might be changed to having this functions return the + /// [`vk::WriteDescriptorSet`]s it wants, so that the render context + /// does not have to be passed in fn write_desc_set( &self, ctx: &RenderCtx, @@ -31,8 +42,16 @@ pub trait WorldComponent { skybox: (vk::ImageView, vk::Sampler), ); + /// Return the pipeline and pipeline layout this component wants to use, + /// this function is called every frame, so the component should not + /// contruct the pipeline in this function, but merely return an earlier + /// contructed pipeline fn pipeline(&self) -> (vk::Pipeline, vk::PipelineLayout); + /// Return the constants that must be pushed to the shader, + /// camera, screen resolution and base color are provided + /// as they are relevant for most shaders. + /// Return in `(stage, offset, data)` fn push_constants( &self, camera: &Camera, @@ -41,12 +60,19 @@ pub trait WorldComponent { ) -> Vec<(vk::ShaderStageFlags, u32, Vec)>; } +/// A [`WorldComponent`] and its associated [`vk::DescriptorSet`] pub struct Component { pub inner: Box, - pub desc_set: DescriptorSet, + pub desc_set: vk::DescriptorSet, } impl Game { + /// Start the loading of a world + /// + /// FIXME: This should not remain in [`crate::render`], + /// the function here should be replaced with one for render + /// specifically and this should be moved to [`crate::game`] + /// and call the render specific function from there pub fn start_load_world(self) -> Game { let Self { state: @@ -118,6 +144,8 @@ impl Game { } impl Game { + /// Add a component to be rendered to the world, see [`crate::render::cube`] + /// for an example for such a component pub fn add_component(&mut self, component: C) { let Self { state: @@ -136,6 +164,12 @@ impl Game { components.push(Box::new(component)); } + /// Finish loading of a world, it is now ready for play + /// + /// FIXME: This should not remain in [`crate::render`], + /// the function here should be replaced with one for render + /// specifically and this should be moved to [`crate::game`] + /// and call the render specific function from there pub fn start_world(self) -> Game { println!("Starting world"); let Self { diff --git a/src/render/mod.rs b/src/render/mod.rs index 838f979..4e3f76f 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -33,7 +33,7 @@ pub enum MemType { } impl RenderCtx { - pub fn mem_alloc(&self, typ: MemType, size: u64) -> vk::DeviceMemory { + fn mem_alloc(&self, typ: MemType, size: u64) -> vk::DeviceMemory { let mem_info = vk::MemoryAllocateInfo::default() .allocation_size(size) .memory_type_index(match typ { @@ -46,7 +46,7 @@ impl RenderCtx { mem } - pub fn alloc_buf( + fn alloc_buf( &self, mem: vk::DeviceMemory, size: vk::DeviceSize, @@ -70,7 +70,7 @@ impl RenderCtx { } } - pub fn buf_to_ptr(&self, mem: vk::DeviceMemory, buf: vk::Buffer) -> *mut std::ffi::c_void { + fn buf_to_ptr(&self, mem: vk::DeviceMemory, buf: vk::Buffer) -> *mut std::ffi::c_void { let ptr = unsafe { self.dev .map_memory(mem, 0, vk::WHOLE_SIZE, vk::MemoryMapFlags::empty()) @@ -80,7 +80,7 @@ impl RenderCtx { ptr } - pub fn shader_mod_from_file( + fn shader_mod_from_file( &self, file: &str, flags: vk::ShaderModuleCreateFlags,