diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f65ed0a..634528e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,6 +8,12 @@ need [mise](https://mise.jdx.dev/), an environment manager and task runner.
Once you install mise, run `mise install` and `mise run` to get all the
necessary tools and view the available actions.
+## Why a monorepo?
+
+These crates are all very closely related. It's likely that if you edit one,
+you'll need to edit another. Additionally, they all use the same build tooling,
+so overall it's more convenient to have them all in the same place.
+
## Testing
Tests are handled
diff --git a/crates/cmd_prompt/README.md b/crates/cmd_prompt/README.md
index c58e19c..1dbcda3 100644
--- a/crates/cmd_prompt/README.md
+++ b/crates/cmd_prompt/README.md
@@ -1,8 +1,8 @@
-

+
-[](https://coveralls.io/github/ada-x64/qproj?branch=main)
+[](https://coveralls.io/github/ada-x64/qproj?branch=q_cmd_prompt)
This is an attempt at a `bevy_ui`-native dev console.
diff --git a/crates/screens/README.md b/crates/screens/README.md
index 18ba735..39d4211 100644
--- a/crates/screens/README.md
+++ b/crates/screens/README.md
@@ -1,9 +1,9 @@
-

+
-[](https://coveralls.io/github/ada-x64/qproj?branch=main)
+[](https://coveralls.io/github/ada-x64/qproj?branch=q_screens)
Screen implementation for Bevy.
diff --git a/crates/screens/src/data.rs b/crates/screens/src/data.rs
index a4d1939..ccbd1fb 100644
--- a/crates/screens/src/data.rs
+++ b/crates/screens/src/data.rs
@@ -16,6 +16,8 @@ mod general_api {
/// [SwitchToScreenMsg] with the screen's [ComponentId].
#[derive(Event, Debug, PartialEq, Eq, Clone, Deref, Default)]
pub struct SwitchToScreen(PhantomData);
+
+ /// See [SwitchToScreen]
pub fn switch_to_screen() -> SwitchToScreen {
SwitchToScreen::::default()
}
@@ -31,6 +33,8 @@ mod general_api {
/// screen is not currently loading.
#[derive(Event, Debug, PartialEq, Eq, Clone, Deref, Default)]
pub struct FinishLoading(PhantomData);
+
+ /// See [FinishLoading]
pub fn finish_loading() -> FinishLoading {
FinishLoading::::default()
}
@@ -39,13 +43,15 @@ mod general_api {
/// screen is not currently unloading.
#[derive(Event, Debug, PartialEq, Eq, Clone, Deref, Default)]
pub struct FinishUnloading(PhantomData);
+
+ /// See [FinishUnloading]
pub fn finish_unloading() -> FinishUnloading {
FinishUnloading::::default()
}
/// Scopes an entity to the current screen. The entity will be cleaned up when
- /// the [Screens] state changes. By default, all entities _except_ those listed
- /// in the [module documentation](crate::framework::screen) are screen-scoped.
+ /// the [Screen] state changes. By default, all entities _except_ top-level
+ /// [Observer] and [Window] components are screen-scoped.
///
/// Note: This is effectively used to skip the propagation of the
/// [Persistent] component. Since screen scoping is the default behavior, it
@@ -55,8 +61,7 @@ mod general_api {
/// Marks an entity as screen-persistent, i.e., this entity will _not_ be
/// automatically cleaned up when the screen changes. By default, all entites
- /// _except_ those listed in the [module
- /// documentation](crate::framework::screen) are screen-scoped.
+ /// _except_ top-level [Observer] and [Window] components and are screen-scoped.
///
/// In order to mark the children of this component as Persistent, you should
/// use the [Propagate](bevy::app::Propagate) component.
@@ -68,9 +73,11 @@ mod general_api {
#[derive(Resource, Default, Debug, Deref)]
pub struct InitialScreen(Option);
impl InitialScreen {
+ #[allow(missing_docs)]
pub fn new() -> Self {
Self(Some(S::name()))
}
+ #[allow(missing_docs)]
pub fn from_name(name: String) -> Self {
Self(Some(name))
}
@@ -113,6 +120,7 @@ mod screens {
skip_unload: bool,
}
impl ScreenData {
+ #[allow(missing_docs)]
pub fn new(id: ComponentId, tick: Tick) -> Self {
Self {
name: S::name(),
@@ -174,54 +182,67 @@ mod screens {
}
}
+ #[allow(missing_docs)]
pub fn load_strategy(&self) -> LoadStrategy {
self.load_strategy
}
+ #[allow(missing_docs)]
pub fn skip_load(&self) -> bool {
self.skip_load
}
+ #[allow(missing_docs)]
pub fn skip_unload(&self) -> bool {
self.skip_unload
}
+ #[allow(missing_docs)]
pub fn set_skip_unload(&mut self, skip_unload: bool) {
self.skip_unload = skip_unload;
}
+ #[allow(missing_docs)]
pub fn set_skip_load(&mut self, skip_load: bool) {
self.skip_load = skip_load;
}
+ #[allow(missing_docs)]
pub fn set_load_strategy(&mut self, load_strategy: LoadStrategy) {
self.load_strategy = load_strategy;
}
+ #[allow(missing_docs)]
pub fn initialized(&self) -> bool {
self.initialized
}
+ #[allow(missing_docs)]
pub fn changed_at(&self) -> Tick {
self.changed_at
}
+ #[allow(missing_docs)]
pub fn needs_update(&self) -> bool {
self.needs_update
}
+ #[allow(missing_docs)]
pub fn type_id(&self) -> TypeId {
self.type_id
}
+ #[allow(missing_docs)]
pub fn state(&self) -> ScreenState {
self.state
}
+ #[allow(missing_docs)]
pub fn id(&self) -> ComponentId {
self.id
}
+ #[allow(missing_docs)]
pub fn name(&self) -> &str {
&self.name
}
@@ -231,15 +252,18 @@ pub use screens::*;
mod schedules {
use super::*;
- /// Describes a screen's [Schedule]. All systems added to this schedule, using the
- /// [ScreenScope] below, will be scoped to this screen's lifetime. That is,
- /// they will only run when the screen is in [ScreenStatus::Ready].
+ /// Describes a screen's [Schedule]. All systems added to this schedule
+ /// will be scoped to this screen's lifetime.
/// To use as a schedule, wrap it with [ScreenScheduleLabel].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter)]
pub enum ScreenSchedule {
+ /// Runs on [Update] when the screen has [ScreenState::Ready]
Update,
+ /// Runs on [FixedUpdate] when the screen has [ScreenState::Ready]
FixedUpdate,
+ /// Runs on [Update] when the screen has [ScreenState::Loading]
Loading,
+ /// Runs on [Update] when the screen has [ScreenState::Unloading]
Unloading,
/// Can also be specified as [on_screen_load]
OnLoad,
@@ -258,12 +282,14 @@ mod schedules {
kind: ScreenSchedule,
}
impl ScreenScheduleLabel {
+ #[allow(missing_docs)]
pub fn new(kind: ScreenSchedule) -> Self {
Self {
id: TypeId::of::(),
kind,
}
}
+ #[allow(missing_docs)]
pub fn from_id(kind: ScreenSchedule, id: TypeId) -> Self {
Self { id, kind }
}
@@ -306,6 +332,7 @@ mod system_params {
_ghost: PhantomData,
}
impl<'w, S: Screen> ScreenDataRef<'w, S> {
+ #[allow(missing_docs)]
pub fn data(&self) -> &'w ScreenData {
self.data
}
@@ -373,6 +400,7 @@ mod system_params {
let tick = self.change_tick;
self.data_mut().finish_unloading(tick);
}
+ #[allow(missing_docs)]
pub fn data(&self) -> &ScreenData {
self.registry.get(&self.cid).unwrap()
}
@@ -444,6 +472,8 @@ mod helpers {
/// Label of a schedule which fires when the screen has begun to load.
#[derive(ScheduleLabel, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct OnScreenLoad(pub TypeId);
+
+ /// See [OnScreenLoad]
pub fn on_screen_load() -> impl ScheduleLabel {
OnScreenLoad(TypeId::of::())
}
@@ -451,6 +481,8 @@ mod helpers {
/// Label of a schedule which fires when the screen has finished loading.
#[derive(ScheduleLabel, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct OnScreenReady(pub TypeId);
+
+ /// See [OnScreenReady]
pub fn on_screen_ready() -> impl ScheduleLabel {
OnScreenReady(TypeId::of::())
}
@@ -458,6 +490,8 @@ mod helpers {
/// Label of a schedule which fires when the screen is beginning to unload. Not to be confused with [OnScreenUnloaded].
#[derive(ScheduleLabel, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct OnScreenUnload(pub TypeId);
+
+ /// See [OnScreenUnload]
pub fn on_screen_unload() -> impl ScheduleLabel {
OnScreenUnload(TypeId::of::())
}
@@ -465,6 +499,8 @@ mod helpers {
/// Label of a schedule which fires when the screen has finished unloading and is no longer active.
#[derive(ScheduleLabel, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub struct OnScreenUnloaded(pub TypeId);
+
+ /// See [OnScreenUnloaded]
pub fn on_screen_unloaded() -> impl ScheduleLabel {
OnScreenUnloaded(TypeId::of::())
}
diff --git a/crates/screens/src/doc.md b/crates/screens/src/doc.md
deleted file mode 100644
index 45a2c2a..0000000
--- a/crates/screens/src/doc.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Screens
-
-The [Screen] trait
-
-## Screen scoping
-
-First, let's go over some terminology to make sure we have a clear conceptual
-understanding.
-
-| term | definition |
-| ------------- | -------------------------------------------------------------------------------------------------------------------------- |
-| Screen | A type of world-state which can help determine behavior. |
-| Screen-scoped | This entity will be despawned when the screen changes. |
-| Persistent | This entity will _not_ be despawned when the screen changes. |
-| Propagate | A propogating component will descend the parent/child hierarchy and clone its inner component onto its recursive children. |
-| Top-level | An entity without any parents. |
-
-By default, all entities are screen-scoped. This means that, whenever the screen
-changes, all entities are removed from the world. However, there are some
-exceptions to this rule. First, there are a few built-in components that mark
-an entity as persistent. They are listed below:
-
-- [Window]
-- [Observer] [^1]
-
-[^1]: These components are persistent _only if_ they are top-level.
-
-Second, there is the explicitly-marked [Persistent] component. This component
-is designed to make screen-persistent interfaces, such as UI and global
-settings.
diff --git a/crates/screens/src/lib.rs b/crates/screens/src/lib.rs
index af1b890..d7e0d02 100644
--- a/crates/screens/src/lib.rs
+++ b/crates/screens/src/lib.rs
@@ -1,14 +1,21 @@
+#![doc = include_str!("../README.md")]
#![feature(register_tool)]
#![register_tool(bevy)]
#![allow(bevy::panicking_methods)]
-#![doc = include_str!("./doc.md")]
+#![deny(missing_docs)]
-mod data;
+#[allow(unused_imports, reason = "used in docs")]
+use prelude::*;
+/// Resources, components, states, etc.
+pub mod data;
mod plugin;
-mod scope;
+/// The [ScreenScopeBuilder] and friends.
+pub mod scope;
mod systems;
-mod trait_impl;
+/// The [Screen] trait.
+pub mod trait_impl;
+/// The main export.
pub mod prelude {
pub use super::data::*;
pub use super::plugin::*;
diff --git a/crates/screens/src/scope.rs b/crates/screens/src/scope.rs
index df32aad..172ebfc 100644
--- a/crates/screens/src/scope.rs
+++ b/crates/screens/src/scope.rs
@@ -2,18 +2,32 @@ pub use crate::prelude::*;
use bevy::{ecs::system::ScheduleSystem, platform::collections::HashMap};
use strum::IntoEnumIterator;
+#[allow(missing_docs)]
pub trait RegisterScreen {
/// Registers a [Screen] to the application.
fn register_screen(&mut self) -> &mut Self;
}
impl RegisterScreen for App {
fn register_screen(&mut self) -> &mut Self {
- S::builder(ScreenScopeBuilder::::new()).build(self);
+ S::builder(ScreenScopeBuilder::::default()).build(self);
self
}
}
-// TODO: DOCUMENT ME
+/// The [ScreenScopeBuilder] is the main entrypoint for screen registration.
+/// Use it to add scoped systems to your screen. These scoped systems will only run
+/// when the screen is in the [ScreenState] analgous to the specified [ScreenSchedule].
+///
+/// When a screen is unloaded, it will clean up all entities marked as non-[Persistent] entities.
+/// Entities can be marked as [ScreenScoped] to opt out of persistence. This is primarily useful
+/// when propagating entity persistence, using [Propagate(Persistence).](bevy::app::Propagate)
+///
+/// Be aware that loading is _disabled by default,_ unless you specify
+/// a system to run in [ScreenSchedule::Loading], or you
+/// manually specify [Self::with_skip_load]. The same is true for unloading.
+///
+/// If you want to allow the screen to run its [Update] schedule while it is in
+/// [ScreenState::Loading], set [Self::with_load_strategy] to [LoadStrategy::Nonblocking].
pub struct ScreenScopeBuilder
where
S: Screen,
@@ -54,7 +68,7 @@ where
self.skip_unload = Some(val);
self
}
- /// Sets the [LoadingStrategy]. By default, this is Blocking.
+ /// Sets the [LoadStrategy]. By default, this is Blocking.
pub fn with_load_strategy(&mut self, val: LoadStrategy) -> &mut Self {
self.load_strategy = val;
self
diff --git a/crates/screens/src/systems.rs b/crates/screens/src/systems.rs
index 9249d8a..2dab051 100644
--- a/crates/screens/src/systems.rs
+++ b/crates/screens/src/systems.rs
@@ -24,7 +24,7 @@ fn handle_switch_msg(
}
}
/// NOTE: This is registered in scope.rs
-pub fn on_switch_screen(
+pub(crate) fn on_switch_screen(
_trigger: On>,
id: ComponentIdFor,
mut commands: Commands,
@@ -32,10 +32,13 @@ pub fn on_switch_screen(
commands.write_message(SwitchToScreenMsg(id.get()));
}
-pub fn on_finish_loading(_trigger: On>, mut data: ScreenDataMut) {
+pub(crate) fn on_finish_loading(
+ _trigger: On>,
+ mut data: ScreenDataMut,
+) {
data.finish_loading();
}
-pub fn on_finish_unloading(
+pub(crate) fn on_finish_unloading(
_trigger: On>,
mut data: ScreenDataMut,
) {
@@ -132,7 +135,7 @@ fn run_fixed_schedules(registry: ResMut, mut commands: Commands)
}
}
-pub fn initial_screen(
+pub(crate) fn initial_screen(
mut commands: Commands,
initial_screen: Res,
registry: Res,
@@ -150,7 +153,7 @@ pub fn initial_screen(
}
}
-pub fn plugin(app: &mut App) {
+pub(crate) fn plugin(app: &mut App) {
app.add_systems(Startup, initial_screen);
app.add_systems(PostUpdate, handle_switch_msg);
app.add_systems(Update, run_schedules);
diff --git a/crates/template/README.md b/crates/template/README.md
index 2a7d031..74714fd 100644
--- a/crates/template/README.md
+++ b/crates/template/README.md
@@ -1,5 +1,5 @@
-

+
This is a template-based template for a bevy project. It is a simplification of the work done for [q_service.](https://github.com/ada-x64/q_service)
diff --git a/crates/test_harness/README.md b/crates/test_harness/README.md
index cad4a31..87ed36d 100644
--- a/crates/test_harness/README.md
+++ b/crates/test_harness/README.md
@@ -1,8 +1,8 @@
-

+
-[  ]( https://coveralls.io/github/ada-x64/qproj?branch=main )
+[  ]( https://coveralls.io/github/ada-x64/qproj?branch=q_test_harness )
This is a simple test harness for bevy projects.