Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: Make a no_std build possible. #538

Merged
merged 3 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

12 changes: 5 additions & 7 deletions all-is-cubes-content/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ categories = ["games"]
keywords = ["all-is-cubes"]

[package.metadata.docs.rs]
features = ["_full-documentation"]
features = ["arbitrary"]

[lib]
# Disable running as benchmark so that the default doesn't interfere with Criterion usage.
Expand All @@ -25,12 +25,10 @@ harness = false
[features]
# Adds `UniverseTemplate::Random`.
arbitrary = ["dep:arbitrary", "all-is-cubes/arbitrary"]
# Internal use only. Used to ensure that docs.rs builds have complete information;
# in particular, `all-is-cubes/std` would otherwise be missing, making types appear `!Sync`.
_full-documentation = ["all-is-cubes/std", "arbitrary"]

[dependencies]
all-is-cubes = { workspace = true }
# std feature is required because this library does not yet participate in `maybe_sync`.
all-is-cubes = { workspace = true, features = ["std"] }
all-is-cubes-ui = { workspace = true }
arbitrary = { workspace = true, optional = true }
exhaust = { workspace = true }
Expand All @@ -39,9 +37,9 @@ hashbrown = { workspace = true }
itertools = { workspace = true }
log = { workspace = true }
macro_rules_attribute = { workspace = true }
noise = { workspace = true }
noise = { workspace = true } # TODO: not no_std compatible (fixable)
paste = { workspace = true }
petgraph = { workspace = true }
petgraph = { workspace = true } # TODO: not no_std compatible (might become so someday)
rand = { workspace = true }
rand_xoshiro = { workspace = true }
strum = { workspace = true, features = ["derive"] }
Expand Down
4 changes: 4 additions & 0 deletions all-is-cubes-content/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
//! provide [`UniverseTemplate`]; other items should be assumed not particularly
//! stable.

// This crate is *almost* `no_std` compatible; critically, some dependencies are not.
// See comments in `Cargo.toml` for details.
// For now, the code is just in a state of “reveal how close it is”, hence using `core` and
// `alloc` imports only.
#![no_std]
//
// Crate-specific lint settings. (General settings can be found in the workspace manifest.)
Expand Down
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
16 changes: 9 additions & 7 deletions all-is-cubes-ui/src/vui/widget_trait.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
//! 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;
use std::sync::Mutex;

use all_is_cubes::behavior::{self, Behavior};
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::SendSyncIfStd;
use all_is_cubes::util::maybe_sync::{self, SendSyncIfStd};

// reused for WidgetController
pub use all_is_cubes::behavior::Then;
Expand Down Expand Up @@ -113,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 @@ -137,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 @@ -164,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 @@ -325,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
Loading
Loading