Skip to content
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: 3 additions & 1 deletion .github/workflows/quality_control.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ jobs:
# That's why we are checking only the library crate.
- name: Check for errors with all features enabled
working-directory: rust_crate/
run: cargo clippy --all-features
run: |
cargo clippy --all-features
cargo clippy --all-features --target wasm32-unknown-unknown

- name: Analyze code
run: |
Expand Down
1 change: 0 additions & 1 deletion documentation/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,5 @@ Customizing the behavior of the Rinf crate is possible through its crate feature
rinf = { version = "0.0.0", features = ["feature-name"] }
```

- `rt-multi-thread`: Starts a worker thread for each CPU core available on the system within the `tokio` runtime by enabling its `rt-multi-thread` feature. By default, the `tokio` runtime uses only one thread. Enabling this feature allows the `tokio` runtime to utilize all the cores on your computer. This feature does not affect applications on the web platform.
- `show-backtrace`: Prints the full backtrace in the CLI when a panic occurs in debug mode. In general, backtrace is not very helpful when debugging async apps, so consider using [`tracing`](https://crates.io/crates/tracing) for logging purposes. Note that this feature does not affect debugging on the web platform.
- `bevy`: Implements the `Event` trait from `bevy_ecs` for `DartSignal`, allowing Bevy's entity component system to listen for events from Dart.
9 changes: 7 additions & 2 deletions flutter_ffi_plugin/example/native/hub/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ crate-type = ["lib", "cdylib", "staticlib"]
[dependencies]
rinf = "6.15.0"
prost = "0.13.0"
tokio = { version = "1", features = ["rt", "sync", "time"] }
tokio_with_wasm = { version = "0.6.3", features = ["rt", "sync", "time"] }
tokio = { version = "1", features = ["rt", "sync", "time", "macros"] }
tokio_with_wasm = { version = "0.7.1", features = [
"rt",
"sync",
"time",
"macros",
] }
wasm-bindgen = "0.2.93"
sample_crate = { path = "../sample_crate" }
12 changes: 11 additions & 1 deletion flutter_ffi_plugin/example/native/hub/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod messages;
mod sample_functions;

// use tokio;
use common::*;
use tokio_with_wasm::alias as tokio;

rinf::write_interface!();
Expand All @@ -15,8 +16,17 @@ rinf::write_interface!();
// such as `tokio::fs::File::open`.
// If you really need to use blocking code,
// use `tokio::task::spawn_blocking`.
async fn main() {
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
// Spawn the concurrent tasks.
tokio::spawn(sample_functions::tell_numbers());
tokio::spawn(sample_functions::stream_fractal());
tokio::spawn(sample_functions::run_debug_tests());

// Get the shutdown receiver from Rinf.
// This receiver will await a signal from Dart shutdown.
let shutdown_receiver = rinf::get_shutdown_receiver()?;
shutdown_receiver.await;

Ok(())
}
14 changes: 5 additions & 9 deletions flutter_ffi_plugin/example/native/hub/src/sample_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ use crate::messages;
use crate::tokio;
use rinf::debug_print;
use std::time::Duration;
use tokio::sync::Mutex;

// Using the `cfg` macro enables conditional statement.
#[cfg(debug_assertions)]
const IS_DEBUG_MODE: bool = true;
static IS_DEBUG_MODE: bool = true;
#[cfg(not(debug_assertions))]
const IS_DEBUG_MODE: bool = false;

// This is one of the ways to keep a global mutable state in Rust.
// You can also use `tokio::sync::RwLock` or `std::lazy::LazyLock`.
static VECTOR: Mutex<Vec<bool>> = Mutex::const_new(Vec::new());
static IS_DEBUG_MODE: bool = false;

// Business logic for the counter widget.
pub async fn tell_numbers() -> Result<()> {
use messages::counter_number::*;

let mut vector = Vec::new();

// Stream getter is generated from a marked Protobuf message.
let receiver = SampleNumberInput::get_dart_signal_receiver()?;
while let Some(dart_signal) = receiver.recv().await {
Expand All @@ -30,8 +27,7 @@ pub async fn tell_numbers() -> Result<()> {
let letter = number_input.letter;
debug_print!("{letter}");

// Use the global state and perform a simple calculation.
let mut vector = VECTOR.lock().await;
// Perform a simple calculation.
vector.push(true);
let current_number = (vector.len() as i32) * 7;

Expand Down
4 changes: 2 additions & 2 deletions flutter_ffi_plugin/template/native/hub/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ crate-type = ["lib", "cdylib", "staticlib"]
[dependencies]
rinf = "6.15.0"
prost = "0.12.6"
tokio = { version = "1", features = ["rt"] }
tokio = { version = "1", features = ["rt", "macros"] }

# Uncomment below to target the web.
# tokio_with_wasm = { version = "0.6.0", features = ["rt"] }
# tokio_with_wasm = { version = "0.6.0", features = ["rt", "macros"] }
# wasm-bindgen = "0.2.92"
14 changes: 13 additions & 1 deletion flutter_ffi_plugin/template/native/hub/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,31 @@ rinf::write_interface!();
// such as `tokio::fs::File::open`.
// If you really need to use blocking code,
// use `tokio::task::spawn_blocking`.
async fn main() {
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
// Spawn the concurrent tasks.
tokio::spawn(communicate());

// Get the shutdown receiver from Rinf.
// This receiver will await a signal from Dart shutdown.
let shutdown_receiver = rinf::get_shutdown_receiver()?;
shutdown_receiver.await;

Ok(())
}

async fn communicate() -> Result<()> {
use messages::basic::*;

// Send signals to Dart like below.
SmallNumber { number: 7 }.send_signal_to_dart();

// Get receivers that listen to Dart signals like below.
let receiver = SmallText::get_dart_signal_receiver()?;
while let Some(dart_signal) = receiver.recv().await {
let message: SmallText = dart_signal.message;
rinf::debug_print!("{message:?}");
}

Ok(())
}
2 changes: 0 additions & 2 deletions rust_crate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ documentation = "https://rinf.cunarist.com"
rust-version = "1.70"

[features]
rt-multi-thread = ["tokio/rt-multi-thread"]
show-backtrace = ["backtrace"]
bevy = ["bevy_ecs"]

Expand All @@ -23,7 +22,6 @@ protoc-prebuilt = "0.3.0"
home = "0.5.9"
which = "6.0.0"
allo-isolate = "0.1.25"
tokio = { version = "1", features = ["rt"] }

[target.'cfg(target_family = "wasm")'.dependencies]
js-sys = "0.3.69"
Expand Down
10 changes: 7 additions & 3 deletions rust_crate/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::fmt;
pub enum RinfError {
LockDartIsolate,
NoDartIsolate,
BuildRuntime,
LockShutdownReceiver,
NoShutdownReceiver,
LockMessageChannel,
BrokenMessageChannel,
ClosedMessageChannel,
Expand All @@ -24,8 +25,11 @@ impl fmt::Display for RinfError {
RinfError::NoDartIsolate => {
write!(f, "Dart isolate for Rust signals was not created.")
}
RinfError::BuildRuntime => {
write!(f, "Could not build the tokio runtime.")
RinfError::LockShutdownReceiver => {
write!(f, "Could not acquire the shutdown receiver lock.")
}
RinfError::NoShutdownReceiver => {
write!(f, "Shutdown receiver was not created.")
}
RinfError::LockMessageChannel => {
write!(f, "Could not acquire the message channel lock.")
Expand Down
14 changes: 6 additions & 8 deletions rust_crate/src/interface.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::error::RinfError;
use std::future::Future;

#[cfg(not(target_family = "wasm"))]
use super::interface_os::*;
Expand Down Expand Up @@ -27,23 +26,22 @@ pub struct DartSignal<T> {
/// the `Runtime` object itself might be moved between threads,
/// along with all the tasks it manages.
#[cfg(not(target_family = "wasm"))]
pub fn start_rust_logic<F, T>(main_future: F) -> Result<(), RinfError>
pub fn start_rust_logic<F, T>(main_fn: F) -> Result<(), RinfError>
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
F: Fn() -> T + Send + 'static,
{
start_rust_logic_real(main_future)
start_rust_logic_real(main_fn)
}

/// Runs the async main function in Rust.
/// On the web, futures usually don't implement the `Send` trait
/// because JavaScript environment is fundamentally single-threaded.
#[cfg(target_family = "wasm")]
pub fn start_rust_logic<F>(main_future: F) -> Result<(), RinfError>
pub fn start_rust_logic<F, T>(main_fn: F) -> Result<(), RinfError>
where
F: Future + 'static,
F: Fn() -> T + 'static,
{
start_rust_logic_real(main_future)
start_rust_logic_real(main_fn)
}

/// Send a signal to Dart.
Expand Down
Loading