Skip to content

Commit

Permalink
docs: add more jumpy crate API docs. (fishfolk#815)
Browse files Browse the repository at this point in the history
This finishes adding basic docs to almost everything other than the `ui`
module, which is probably not super important right now.
  • Loading branch information
zicklag committed Jun 18, 2023
1 parent 4a8565a commit eefd8a3
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 13 deletions.
9 changes: 9 additions & 0 deletions src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
//! Debugging tools.
//!
//! Sets up the Bevy world inspector, and the puffin profiler.
//!
//! More debug related ui code can be found in [`ui::debug_tools`].

use crate::prelude::*;
use bevy::window::PrimaryWindow;
use bevy_egui::EguiContext;
use bevy_inspector_egui::{bevy_inspector, inspector_egui_impls};

/// Debug plugin.
pub struct JumpyDebugPlugin;

/// Resource that tracks whether or not the world inspector window is visible.
#[derive(Resource, Deref, DerefMut, Default)]
pub struct WorldInspectorEnabled(pub bool);

Expand All @@ -23,6 +31,7 @@ impl Plugin for JumpyDebugPlugin {
}
}

/// Renders the world-inspector UI.
pub fn world_inspector(world: &mut World) {
if !**world.resource::<WorldInspectorEnabled>() {
return;
Expand Down
9 changes: 9 additions & 0 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
//! Player input types.
//!
//! We use the [`leafwing-input-manager`] plugin for collecting user input in Jumpy. This crate
//! installs the input manager plugin and registers the [`PlayerAction`] type as the collectible
//! player input.
//!
//! [`leafwing-input-manager`]: https://docs.rs/leafwing-input-manager

use crate::prelude::*;

/// Input plugin.
pub struct JumpyPlayerInputPlugin;

impl Plugin for JumpyPlayerInputPlugin {
Expand Down
22 changes: 19 additions & 3 deletions src/loading.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Initial game loading implementation.

use bevy::ecs::system::SystemParam;
use bevy_egui::{egui, EguiContexts};
use bevy_fluent::Locale;
Expand All @@ -13,6 +15,7 @@ use crate::{
prelude::*,
};

/// Loading plugin.
pub struct JumpyLoadingPlugin;

impl Plugin for JumpyLoadingPlugin {
Expand Down Expand Up @@ -99,9 +102,21 @@ fn core_assets_loaded(
true
}

/// Component added to the entities used to collect player input.
///
/// The inner [`usize`] is the player index.
///
/// The `leafwing-input-manager` tracks input for specific entities, instead of globally collecting
/// input. This usually makes things easier, but for our usje-case, we need to be able to collect
/// user input even for players that haven't, spawned yet.
///
/// To facilitate this, for every user we spawn [`jumpy_core::MAX_PLAYERS`] entities with a
/// [`PlayerInputCollector`] and the `InputManagerBundle` that is needed for
/// `leafwing-input-manager`.
#[derive(Component)]
pub struct PlayerInputCollector(pub usize);

/// Systemrunonce to spawn the menu input collector.
fn setup(mut commands: Commands) {
commands.spawn((
Name::new("Menu Input Collector"),
Expand All @@ -112,7 +127,7 @@ fn setup(mut commands: Commands) {
));
}

/// System param used to load and hot reload the game
/// System param used to load and hot reload the game.
#[derive(SystemParam)]
pub struct GameLoader<'w, 's> {
skip_next_asset_update_event: Local<'s, bool>,
Expand Down Expand Up @@ -335,6 +350,7 @@ impl<'w, 's> GameLoader<'w, 's> {
}
}

/// Get the input map for the menu controls.
fn menu_input_map() -> InputMap<MenuAction> {
InputMap::default()
.set_gamepad(Gamepad::new(0))
Expand Down Expand Up @@ -404,12 +420,12 @@ fn menu_input_map() -> InputMap<MenuAction> {
.build()
}

/// System to run the initial game load
/// System to run the initial game load.
fn load_game(loader: GameLoader) {
loader.load(false);
}

/// System to check for asset changes and hot reload the game
/// System to check for asset changes and hot reload the game.
fn hot_reload_game(loader: GameLoader) {
loader.load(true);
}
11 changes: 9 additions & 2 deletions src/localization.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Localization utilities & initialization.

use std::borrow::Borrow;

use bevy::{prelude::*, utils::HashMap};
Expand All @@ -6,6 +8,8 @@ use fluent::FluentArgs;
use fluent_content::{Content, Request};

/// Plugin for initializing and loading the [`Localization`] resource.
///
/// [`Localization`]: https://docs.rs/bevy_fluent/latest/bevy_fluent/struct.Localization.html
pub struct JumpyLocalizationPlugin;

impl Plugin for JumpyLocalizationPlugin {
Expand All @@ -19,6 +23,8 @@ impl Plugin for JumpyLocalizationPlugin {
}

/// Extension trait to reduce boilerplate when getting values from a [`Localization`].
///
/// [`Localization`]: https://docs.rs/bevy_fluent/latest/bevy_fluent/struct.Localization.html
pub trait LocalizationExt<'a, T: Into<Request<'a, U>>, U: Borrow<FluentArgs<'a>>> {
/// Request message content and get an empty string if it doesn't exist.
fn get(&self, request: T) -> String;
Expand All @@ -44,8 +50,9 @@ where
}
}

/// Watch for locale [`BundleAsset`] load events and add any new bundles to the [`Localization`]
/// resource.
/// Watch for locale load events and add any new bundles to the [`Localization`] resource.
///
/// [`Localization`]: https://docs.rs/bevy_fluent/latest/bevy_fluent/struct.Localization.html
fn load_locales(
locale: Res<Locale>,
mut loading_bundles: Local<Vec<Handle<BundleAsset>>>,
Expand Down
18 changes: 13 additions & 5 deletions src/platform.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//! Systems and utilities related to specific platform support or platform abstractions
//! Platform abstractions.
//!
//! This module contains abstractions over platform-specific details. Currently this is just the
//! [`Storage`] abstraction, which allows us to persist key-value data in a way that works on both
//! native platforms and on web.

use crate::prelude::*;

Expand All @@ -12,6 +16,7 @@ use native as backend;
#[cfg(target_arch = "wasm32")]
use wasm as backend;

/// Platform plugin.
pub struct JumpyPlatformPlugin;

impl Plugin for JumpyPlatformPlugin {
Expand Down Expand Up @@ -71,6 +76,7 @@ impl FromWorld for Storage {
}
}

/// An error that may occur while accessing [`Storage`].
#[derive(thiserror::Error, Debug)]
pub enum StorageError {
#[error("Storage has not been loaded yet")]
Expand Down Expand Up @@ -261,17 +267,18 @@ impl SaveTask {
}
}

/// Message type sent over a channel to the storage task.
enum StorageRequest {
Load {
result_sender: Sender<StorageData>,
},
/// Load the storage and send it to the `result_sender`.
Load { result_sender: Sender<StorageData> },
/// Save the storage and send confirmation to the `result_sender`.
Save {
data: StorageData,
result_sender: Sender<()>,
},
}

/// Native platform support
/// Native platform support.
#[cfg(not(target_arch = "wasm32"))]
mod native {
use std::{
Expand All @@ -288,6 +295,7 @@ mod native {

use super::StorageRequest;

/// Initialize storage backend.
pub(super) fn init_storage() -> Sender<StorageRequest> {
trace!("Initialize platform storage backend");
let io_task_pool = IoTaskPool::get();
Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Internal prelude used to easily import common types.

pub use crate::{
assets::*, audio::*, bevy_states::*, camera::*, config::*, debug::*, input::*, loading::*,
localization::*, metadata::*, platform::*, session::*, ui::*, utils::*, *,
Expand Down
39 changes: 36 additions & 3 deletions src/session.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
//! Session management for matches.
//!
//! The [`SessionManager`] is used to create, stop, snapshot, and restore game matches. A session
//! refers to an in-progress game match.
//!
//! Right now there are two kinds of sessions: local sessions and network sessions. These are
//! implemented by the [`LocalSessionRunner`] and
//! [`GgrsSessionRunner`][crate::networking::GgrsSessionRunner] types respectively.
//!
//! Both of them implmenent [`SessionRunner`] which is a trait used by the [`SessionManager`] to
//! advance the game simulation properly.

use bevy::utils::Instant;
use downcast_rs::{impl_downcast, Downcast};
use jumpy_core::input::PlayerControl;

use crate::{main_menu::MenuPage, prelude::*};

/// Session plugin.
pub struct JumpySessionPlugin;

/// Stage label for the game session stages
Expand Down Expand Up @@ -64,22 +77,37 @@ impl Plugin for JumpySessionPlugin {
}
}

/// A resource containing an in-progress game session.
/// A resource containing the in-progress game session.
#[derive(Resource, Deref, DerefMut)]
pub struct Session(pub Box<dyn SessionRunner>);

/// Trait implemented by types that know how to advance the core game simulation.
///
/// Things like fixed frame updates are expected to be handled by the session runner.
///
/// The [`GgrsSessionRunner`][crate::networking::GgrsSessionRunner] is an example of how a custom
/// runner can be used for running a network game.
pub trait SessionRunner: Sync + Send + Downcast {
/// Get mutable access to the [`CoreSession`].
fn core_session(&mut self) -> &mut CoreSession;
/// Get mutable access to the [`bones::World`] from in the [`CoreSession`].
fn world(&mut self) -> &mut bones::World {
&mut self.core_session().world
}
/// Restart the session.
fn restart(&mut self);
/// Get the control input for the player with the given `player_idx`.
fn get_player_input(&mut self, player_idx: usize) -> PlayerControl {
self.core_session()
.update_input(|inputs| inputs.players[player_idx].control.clone())
}
/// Set the player input for the player with the given `player_idx`.
fn set_player_input(&mut self, player_idx: usize, control: PlayerControl);
/// Advance the game simmulation.
fn advance(&mut self, bevy_world: &mut World) -> Result<(), SessionError>;
/// Return whether or not the simulation should run, given the current time.
///
/// This is used to created fixed refresh rates.
fn run_criteria(&mut self, time: &Time) -> ShouldRun;
/// Returns the player index of the player if we are in a network game.
///
Expand All @@ -96,6 +124,10 @@ pub enum SessionError {
Disconnected,
}

/// Implementation of [`SessionRunner`] for local games.
///
/// This is almost as simple as a [`SessionRunner`] can get: it just advances the game simulation at
/// the fixed [`jumpy_core::FPS`].
pub struct LocalSessionRunner {
pub core: CoreSession,
pub accumulator: f64,
Expand Down Expand Up @@ -198,15 +230,16 @@ impl<'w, 's> SessionManager<'w, 's> {
self.menu_camera.for_each_mut(|mut x| x.is_active = false);
}

/// Start a network game session.
#[cfg(not(target_arch = "wasm32"))]
pub fn start_network(
&mut self,
core_info: CoreSessionInfo,
lan_info: crate::networking::GgrsSessionRunnerInfo,
ggrs_info: crate::networking::GgrsSessionRunnerInfo,
) {
let session = Session(Box::new(crate::networking::GgrsSessionRunner::new(
CoreSession::new(core_info),
lan_info,
ggrs_info,
)));
self.commands.insert_resource(session);
self.menu_camera.for_each_mut(|mut x| x.is_active = false);
Expand Down
2 changes: 2 additions & 0 deletions src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! User interface.

use bevy::{
ecs::system::SystemState,
window::{PrimaryWindow, WindowMode},
Expand Down
2 changes: 2 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Miscellaneous utilities.

use async_channel::*;

/// Create a bi-directional channel with a given request and response type.
Expand Down

0 comments on commit eefd8a3

Please sign in to comment.