Skip to content

Commit

Permalink
ui: Make a no_std build possible.
Browse files Browse the repository at this point in the history
The part that we can neatly cut off, in this case, is `Session`
and its associated UI -- stuff that requires channels and mutexes.
What we keep is the `vui` and `logo` modules.
  • Loading branch information
kpreid committed Oct 4, 2024
1 parent d0d880a commit bd1ca4c
Show file tree
Hide file tree
Showing 32 changed files with 123 additions and 37 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ jobs:

- name: no_std lint
run: |
cargo clippy --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render -p all-is-cubes-mesh
cargo clippy --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render -p all-is-cubes-ui -p all-is-cubes-mesh
- name: no_std build
# This is `cargo build`, not `cargo check`, because `cargo check` won't detect problems like
# use of undefined linker symbols. Not sure if that matters.
run: |
cargo build --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render -p all-is-cubes-mesh
cargo build --target=thumbv7em-none-eabihf --no-default-features -p all-is-cubes -p all-is-cubes-render -p all-is-cubes-ui -p all-is-cubes-mesh
fuzz:
# Don't spend time on fuzzing if the build failed indicating the code is bad other ways
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion all-is-cubes-desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ all-is-cubes-mesh = { workspace = true, optional = true, features = ["dynamic"]
all-is-cubes-port = { workspace = true, features = ["import", "native"] }
# TODO: make raytracer optional
all-is-cubes-render = { workspace = true, features = ["raytracer"] }
all-is-cubes-ui = { workspace = true }
all-is-cubes-ui = { workspace = true, features = ["session"] }
anyhow = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-port/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dot-vox = [

[dependencies]
# Non-optional generally required dependencies
# need all-is-cubes/std because we have boxed Send futures
# need all-is-cubes/std because we have boxed Send futures and errors
all-is-cubes = { workspace = true, features = ["std"] }
cfg-if = { workspace = true }
futures-core = { workspace = true }
Expand Down
36 changes: 25 additions & 11 deletions all-is-cubes-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,41 @@ categories = ["games", "gui"]
keywords = ["all-is-cubes", "voxel"]

[package.metadata.docs.rs]
features = []
features = ["session"]

[lib]
# Disable running as benchmark so that the default doesn't interfere with Criterion usage.
bench = false

[features]
# Enable the `apps` and `notification` modules, particularly including the `Session` type,
# and require `std` support.
session = [
"all-is-cubes/std",
"dep:async_fn_traits",
"dep:flume",
"dep:futures-core",
"dep:futures-task",
"dep:futures-util",
"dep:scopeguard",
"dep:sync_wrapper",
]

[dependencies]
# TODO: Disable default features. Requires more `maybe_sync` work.
all-is-cubes = { workspace = true, default-features = true }
all-is-cubes-render = { workspace = true, default-features = true }
async_fn_traits = { workspace = true }
all-is-cubes = { workspace = true, default-features = false }
all-is-cubes-render = { workspace = true, default-features = false }
async_fn_traits = { workspace = true, optional = true }
displaydoc = { workspace = true }
exhaust = { workspace = true }
flume = { workspace = true }
futures-core = { workspace = true }
futures-task = { workspace = true }
futures-util = { workspace = true }
flume = { workspace = true, optional = true }
futures-core = { workspace = true, optional = true }
futures-task = { workspace = true, optional = true }
futures-util = { workspace = true, optional = true }
indoc = { workspace = true }
log = { workspace = true }
scopeguard = { workspace = true }
sync_wrapper = { workspace = true }
num-traits = { workspace = true }
scopeguard = { workspace = true, optional = true }
sync_wrapper = { workspace = true, optional = true }

[dev-dependencies]
futures-channel = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-ui/src/apps/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
reason = "module is private; https://github.com/rust-lang/rust-clippy/issues/8524"
)]


use alloc::vec::Vec;
use core::time::Duration;
use std::collections::{HashMap, HashSet};

Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-ui/src/apps/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
reason = "module is private; https://github.com/rust-lang/rust-clippy/issues/8524"
)]

use alloc::boxed::Box;
use alloc::string::ToString as _;
use alloc::sync::{Arc, Weak};
use core::fmt;
use core::future::Future;
Expand Down
4 changes: 3 additions & 1 deletion all-is-cubes-ui/src/editor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! VUI components related to allowing the user to inspect universe contents.
use all_is_cubes::universe::Handle;
use alloc::sync::Arc;
use alloc::vec;
use alloc::vec::Vec;

use all_is_cubes::arcstr::{self, literal, ArcStr};
use all_is_cubes::block::{self, Block};
use all_is_cubes::character::Cursor;
use all_is_cubes::euclid::size3;
use all_is_cubes::math::Face6;
use all_is_cubes::universe::Handle;

use crate::ui_content::hud::HudInputs;
use crate::ui_content::pages::back_button;
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-ui/src/inv_watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! "derived information from a `ListenableSource` that requires computation" and should become
//! general code that handles the re-listening problem.
use std::sync::Arc;
use alloc::sync::Arc;

use all_is_cubes::character::{Character, CharacterChange};
use all_is_cubes::inv::{Inventory, TOOL_SELECTIONS};
Expand Down
12 changes: 10 additions & 2 deletions all-is-cubes-ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,29 @@
//! [`Space`]: all_is_cubes::space::Space
//! [`Universe`]: all_is_cubes::universe::Universe
// This crate is not `no_std` because it currently uses `std::sync::mpsc`.

#![no_std]
// Crate-specific lint settings. (General settings can be found in the workspace manifest.)
#![forbid(unsafe_code)]

extern crate alloc;

#[cfg(any(test, feature = "session"))]
#[macro_use]
extern crate std;

#[cfg(feature = "session")]
mod editor;
#[cfg(feature = "session")]
mod inv_watch;

#[cfg(feature = "session")]
pub mod apps;

pub mod logo;

#[cfg(feature = "session")]
mod ui_content;
#[cfg(feature = "session")]
pub use ui_content::notification;

pub mod vui;
1 change: 1 addition & 0 deletions all-is-cubes-ui/src/ui_content/notification.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Types used to create notifications displayed to the user.
use alloc::sync::{Arc, Weak};
use alloc::vec::Vec;
use std::sync::Mutex;

use all_is_cubes::listen;
Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-ui/src/ui_content/options.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use alloc::boxed::Box;
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::fmt;

use all_is_cubes::arcstr::{self, literal};
Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-ui/src/ui_content/pages.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Contents of various UI pages.
use alloc::string::String;
use alloc::sync::Arc;

use all_is_cubes::arcstr::{literal, ArcStr};
Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-ui/src/ui_content/vui_manager.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::string::{String, ToString as _};
use alloc::sync::Arc;
use core::future::Future;
use flume::TryRecvError;
Expand Down
3 changes: 3 additions & 0 deletions all-is-cubes-ui/src/vui/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
reason = "module is private; https://github.com/rust-lang/rust-clippy/issues/8524"
)]

use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::sync::Arc;
use alloc::vec;
use alloc::vec::Vec;
use core::fmt;

use all_is_cubes::euclid::{self, size3, Size3D, Vector3D};
Expand Down
3 changes: 3 additions & 0 deletions all-is-cubes-ui/src/vui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#[doc(hidden)] // public for use by test-renderers only
pub mod blocks;
#[cfg(feature = "session")]
pub(crate) use blocks::UiBlocks;
mod layout;
pub use layout::*;
#[cfg(feature = "session")]
mod page;
#[cfg(feature = "session")]
pub(crate) use page::*;
mod widget_trait;
pub use widget_trait::*;
Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-ui/src/vui/page.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::sync::Arc;
use alloc::vec;

use all_is_cubes::arcstr::ArcStr;
use all_is_cubes::block::{text, AIR};
Expand Down Expand Up @@ -336,6 +337,7 @@ pub(crate) mod parts {
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;

#[test]
fn ui_size() {
Expand Down
15 changes: 9 additions & 6 deletions all-is-cubes-ui/src/vui/widget_trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! UI [`Widget`] trait and related glue.
use all_is_cubes::time::Tick;
use alloc::boxed::Box;
use alloc::sync::Arc;
use core::error::Error;
use core::fmt::Debug;
Expand All @@ -10,7 +11,7 @@ use all_is_cubes::math::GridAab;
use all_is_cubes::space::{self, Space, SpaceTransaction};
use all_is_cubes::transaction::{self, Merge as _};
use all_is_cubes::universe::{HandleVisitor, UniverseTransaction, VisitHandles};
use all_is_cubes::util::maybe_sync::{Mutex, SendSyncIfStd};
use all_is_cubes::util::maybe_sync::{self, SendSyncIfStd};

// reused for WidgetController
pub use all_is_cubes::behavior::Then;
Expand Down Expand Up @@ -112,7 +113,9 @@ pub type StepSuccess = (WidgetTransaction, Then);
/// Error return of [`WidgetController::step()`].
///
/// TODO: This should become a more specific error type.
pub type StepError = Box<dyn Error + Send + Sync>;
//---
// This is a type alias to cope with the maybe-Sync kludge without exposing that everywhere.
pub type StepError = maybe_sync::BoxError;

impl WidgetController for Box<dyn WidgetController> {
fn step(&mut self, context: &WidgetContext<'_>) -> Result<StepSuccess, StepError> {
Expand All @@ -136,7 +139,7 @@ impl WidgetController for Box<dyn WidgetController> {
pub(super) struct WidgetBehavior {
/// Original widget -- not used directly but for error reporting
widget: Positioned<Arc<dyn Widget>>,
controller: Mutex<Box<dyn WidgetController>>,
controller: maybe_sync::Mutex<Box<dyn WidgetController>>,
}

impl WidgetBehavior {
Expand All @@ -163,7 +166,7 @@ impl WidgetBehavior {
space::SpaceBehaviorAttachment::new(widget.position.bounds),
Arc::new(WidgetBehavior {
widget,
controller: Mutex::new(controller),
controller: maybe_sync::Mutex::new(controller),
}),
);
init_txn
Expand Down Expand Up @@ -324,11 +327,11 @@ pub(crate) fn instantiate_widget<W: Widget + 'static>(
#[cfg(test)]
mod tests {
use super::*;
use all_is_cubes::util::assert_send_sync;
use all_is_cubes::util::assert_conditional_send_sync;

#[test]
fn error_is_send_sync() {
assert_send_sync::<InstallVuiError>()
assert_conditional_send_sync::<InstallVuiError>()
}

fn _assert_widget_trait_is_object_safe(_: &dyn Widget) {}
Expand Down
5 changes: 4 additions & 1 deletion all-is-cubes-ui/src/vui/widgets/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
reason = "module is private; https://github.com/rust-lang/rust-clippy/issues/8524"
)]

use alloc::borrow::ToOwned as _;
use alloc::boxed::Box;
use alloc::format;
use alloc::sync::Arc;
use core::fmt;
use core::hash::Hash;
Expand Down Expand Up @@ -549,7 +552,7 @@ mod theme {
/// Build a [`Block`] for [`ButtonBase`].
pub fn common_block(space: Handle<Space>, name: &str) -> Block {
Block::builder()
.display_name(name.to_string())
.display_name(name)
.voxels_handle(MULTI_RESOLUTION, space)
.animation_hint(block::AnimationHint::replacement(
block::AnimationChange::Shape,
Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-ui/src/vui/widgets/crosshair.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::boxed::Box;
use alloc::sync::Arc;

use all_is_cubes::block::{Block, AIR};
Expand Down
1 change: 1 addition & 0 deletions all-is-cubes-ui/src/vui/widgets/debug.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::boxed::Box;
use alloc::sync::Arc;

use all_is_cubes::block::{self, text, Block, Resolution::R64};
Expand Down
2 changes: 2 additions & 0 deletions all-is-cubes-ui/src/vui/widgets/frame.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use alloc::boxed::Box;
use alloc::sync::Arc;
use alloc::vec;

use all_is_cubes::block::Block;
use all_is_cubes::euclid::size3;
Expand Down
7 changes: 7 additions & 0 deletions all-is-cubes-ui/src/vui/widgets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Specific UI widgets.
use alloc::boxed::Box;
use alloc::sync::Arc;

use all_is_cubes::block::Block;
Expand All @@ -8,7 +9,9 @@ use all_is_cubes::space::SpaceTransaction;

use crate::vui;

#[cfg(feature = "session")]
mod crosshair;
#[cfg(feature = "session")]
pub(crate) use crosshair::*;
mod frame;
pub use frame::*;
Expand All @@ -22,9 +25,13 @@ mod progress_bar;
pub use progress_bar::*;
mod theme;
pub use theme::*;
#[cfg(feature = "session")]
mod toolbar;
#[cfg(feature = "session")]
pub(crate) use toolbar::*;
#[cfg(feature = "session")]
mod tooltip;
#[cfg(feature = "session")]
pub(crate) use tooltip::*;
mod voxels;
pub use voxels::*;
Expand Down
10 changes: 9 additions & 1 deletion all-is-cubes-ui/src/vui/widgets/progress_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
reason = "module is private; https://github.com/rust-lang/rust-clippy/issues/8524"
)]

use std::sync::Arc;
use alloc::boxed::Box;
use alloc::sync::Arc;

/// Acts as polyfill for float methods
#[cfg(not(feature = "session"))]
#[allow(unused_imports)]
use num_traits::float::FloatCore as _;

use all_is_cubes::block::{self, Block, Composite, CompositeOperator, AIR};
use all_is_cubes::color_block;
Expand Down Expand Up @@ -208,6 +214,8 @@ mod tests {
use all_is_cubes::transaction::Transaction as _;
use all_is_cubes::util::yield_progress_for_testing;
use all_is_cubes::{transaction, universe};
use alloc::string::String;
use alloc::vec::Vec;

#[tokio::test]
async fn progress_output() {
Expand Down
Loading

0 comments on commit bd1ca4c

Please sign in to comment.