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

Split pages #340

Merged
merged 1 commit into from
May 30, 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: 3 additions & 1 deletion documentation/docs/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ nav:
- running-and-building.md
- messaging.md
- tutorial.md
- writing-code.md
- detailed-techniques.md
- state-management.md
- printing-for-debugging.md
- graceful-shutdown.md
- configuration.md
- frequently-asked-questions.md
- contribution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Writing Code
# Detailed Techniques

## 🏷️ Signal Details

Expand Down Expand Up @@ -53,58 +53,3 @@ This applies same to marked Protobuf messages.
// responsible for...
message OtherData { ... }
```

## 🖨️ Printing for Debugging

You might be used to `println!` macro in Rust. However, using that macro isn't a very good idea in our apps made with Flutter and Rust because `println!` outputs cannot be seen on the web and mobile emulators.

When writing Rust code in the `hub` crate, you can simply print your debug message with the `debug_print!` macro provided by this framework like below. Once you use this macro, Flutter will take care of the rest.

```rust title="Rust"
use rinf::debug_print;
debug_print!("My object is {my_object:?}");
```

`debug_print!` is also better than `println!` because it only works in debug mode, resulting in a smaller and cleaner release binary.

## 🌅 Closing the App Gracefully

When the Flutter app is closed, the whole `tokio` runtime on the Rust side will be terminated automatically. However, some error messages can appear in the console if the Rust side sends messages to the Dart side even after the Dart VM has stopped. To prevent this, you can call `finalizeRust()` in Dart to terminate all Rust tasks before closing the Flutter app.

```dart title="lib/main.dart"
import 'dart:ui';
import 'package:flutter/material.dart';
import './messages/generated.dart';
...
class MyApp extends StatefulWidget {
const MyApp({super.key});

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
final _appLifecycleListener = AppLifecycleListener(
onExitRequested: () async {
// Terminate Rust tasks before closing the Flutter app.
await finalizeRust();
return AppExitResponse.exit;
},
);

@override
void dispose() {
_appLifecycleListener.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Some App',
home: MyHomePage(),
);
}
}
...
```
41 changes: 41 additions & 0 deletions documentation/docs/graceful-shutdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Graceful Shutdown

When the Flutter app is closed, the entire `tokio` runtime on the Rust side will be terminated automatically. However, you might need to run some finalization code in Rust before the app closes. This might involve saving files or disposing of resources. To achieve this, you can call `finalizeRust()` in Dart to terminate all Rust tasks before closing the Flutter app.

```dart title="lib/main.dart"
import 'dart:ui';
import 'package:flutter/material.dart';
import './messages/generated.dart';
...
class MyApp extends StatefulWidget {
const MyApp({super.key});

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
final _appLifecycleListener = AppLifecycleListener(
onExitRequested: () async {
// Terminate Rust tasks before closing the Flutter app.
await finalizeRust();
return AppExitResponse.exit;
},
);

@override
void dispose() {
_appLifecycleListener.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Some App',
home: MyHomePage(),
);
}
}
...
```
12 changes: 12 additions & 0 deletions documentation/docs/printing-for-debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Printing for Debugging

You might be used to `println!` macro in Rust. However, using that macro isn't a very good idea in our apps made with Flutter and Rust because `println!` outputs cannot be seen on the web and mobile emulators.

When writing Rust code in the `hub` crate, you can simply print your debug message with the `debug_print!` macro provided by this framework like below. Once you use this macro, Flutter will take care of the rest.

```rust title="Rust"
use rinf::debug_print;
debug_print!("My object is {my_object:?}");
```

`debug_print!` is also better than `println!` because it only works in debug mode, resulting in a smaller and cleaner release binary.
14 changes: 6 additions & 8 deletions documentation/docs/state-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ async fn main() {
}

pub async fn do_something_with_state(data: Arc<Mutex<Vec<i32>>>) {
// Get the mutex guard.
let mut vector = data.lock().await;
vector.push(3);
// Mutate the shared variable directly.
VECTOR.lock().await.push(3);
}
```

Expand All @@ -35,12 +34,11 @@ use tokio::sync::Mutex;
static VECTOR: Mutex<Vec<bool>> = Mutex::const_new(Vec::new());

pub async fn do_something_with_state() {
// Get the mutex guard.
let mut vector = VECTOR.lock().await;
VECTOR.lock().await.push(true);

// Custom logic here.
vector.push(true);
let length = vector.len();
// Use the global variable by acquiring the guard.
let guard = VECTOR.lock().await;
let length = guard.len();
debug_print!("{length}");
}
```
Expand Down