mirror of
https://github.com/ALEZ-DEV/Babylonia-terminal.git
synced 2026-03-21 21:58:52 +00:00
add rust to GUI launcher
This commit is contained in:
parent
6a34cb7126
commit
5c52ddb586
9
babylonia_terminal_launcher/.gitignore
vendored
9
babylonia_terminal_launcher/.gitignore
vendored
@ -46,4 +46,11 @@ app.*.map.json
|
|||||||
/linux
|
/linux
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
/test
|
/test
|
||||||
|
|
||||||
|
# Rust related
|
||||||
|
.cargo/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Generated messages
|
||||||
|
*/**/messages/
|
||||||
|
|||||||
8
babylonia_terminal_launcher/Cargo.toml
Normal file
8
babylonia_terminal_launcher/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# This file is used for telling Rust-related tools
|
||||||
|
# where various Rust crates are.
|
||||||
|
# This also unifies `./target` output folder and
|
||||||
|
# various Rust configurations.
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["./native/*"]
|
||||||
|
resolver = "2"
|
||||||
44
babylonia_terminal_launcher/README.md
Normal file
44
babylonia_terminal_launcher/README.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Using Rust Inside Flutter
|
||||||
|
|
||||||
|
This project leverages Flutter for GUI and Rust for the backend logic,
|
||||||
|
utilizing the capabilities of the
|
||||||
|
[Rinf](https://pub.dev/packages/rinf) framework.
|
||||||
|
|
||||||
|
To run and build this app, you need to have
|
||||||
|
[Flutter SDK](https://docs.flutter.dev/get-started/install)
|
||||||
|
and [Rust toolchain](https://www.rust-lang.org/tools/install)
|
||||||
|
installed on your system.
|
||||||
|
You can check that your system is ready with the commands below.
|
||||||
|
Note that all the Flutter subcomponents should be installed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rustc --version
|
||||||
|
flutter doctor
|
||||||
|
```
|
||||||
|
|
||||||
|
You also need to have the CLI tool for Rinf ready.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo install rinf
|
||||||
|
```
|
||||||
|
|
||||||
|
Messages sent between Dart and Rust are implemented using Protobuf.
|
||||||
|
If you have newly cloned the project repository
|
||||||
|
or made changes to the `.proto` files in the `./messages` directory,
|
||||||
|
run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rinf message
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can run and build this app just like any other Flutter projects.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flutter run
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed instructions on writing Rust and Flutter together,
|
||||||
|
please refer to Rinf's [documentation](https://rinf.cunarist.com).
|
||||||
|
|
||||||
@ -4,15 +4,22 @@ import 'package:yaru/yaru.dart';
|
|||||||
|
|
||||||
import './screens/screens.dart';
|
import './screens/screens.dart';
|
||||||
|
|
||||||
import './providers/settings_provider.dart';
|
import './providers/providers.dart';
|
||||||
|
|
||||||
class BabyloniaLauncher extends StatelessWidget {
|
class BabyloniaLauncher extends StatelessWidget {
|
||||||
const BabyloniaLauncher({super.key});
|
const BabyloniaLauncher({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ChangeNotifierProvider(
|
return MultiProvider(
|
||||||
create: (context) => SettingsProvider(),
|
providers: [
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => SettingsProvider(),
|
||||||
|
),
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => GameStateProvider(),
|
||||||
|
),
|
||||||
|
],
|
||||||
child: YaruTheme(
|
child: YaruTheme(
|
||||||
builder: (context, yaru, child) => MaterialApp(
|
builder: (context, yaru, child) => MaterialApp(
|
||||||
title: "Babylonia Terminal",
|
title: "Babylonia Terminal",
|
||||||
|
|||||||
@ -3,8 +3,10 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
|
|
||||||
import './app.dart';
|
import './app.dart';
|
||||||
|
import './messages/generated.dart';
|
||||||
|
|
||||||
void main() {
|
void main() async {
|
||||||
|
await initializeRust();
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
MediaKit.ensureInitialized();
|
MediaKit.ensureInitialized();
|
||||||
runApp(const BabyloniaLauncher());
|
runApp(const BabyloniaLauncher());
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
import 'package:babylonia_terminal_launcher/messages/game_state.pb.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class GameStateProvider with ChangeNotifier {
|
||||||
|
States? _gameState = null;
|
||||||
|
bool isUpdating = false;
|
||||||
|
|
||||||
|
Future updateGameState() async {
|
||||||
|
if (!isUpdating) {
|
||||||
|
isUpdating = true;
|
||||||
|
AskGameState().sendSignalToRust();
|
||||||
|
|
||||||
|
final stream = GameState.rustSignalStream;
|
||||||
|
await for (final rustSignal in stream) {
|
||||||
|
_gameState = rustSignal.message.state;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
isUpdating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
babylonia_terminal_launcher/lib/providers/providers.dart
Normal file
2
babylonia_terminal_launcher/lib/providers/providers.dart
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export './settings_provider.dart';
|
||||||
|
export './game_state_provider.dart';
|
||||||
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import './../widgets/background.dart';
|
import './../widgets/background.dart';
|
||||||
import './../providers/settings_provider.dart';
|
import './../providers/providers.dart';
|
||||||
import './../models/settings.dart';
|
import './../models/settings.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
@ -62,7 +62,11 @@ class HomeScreen extends StatelessWidget {
|
|||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.blue[500],
|
backgroundColor: Colors.blue[500],
|
||||||
),
|
),
|
||||||
onPressed: () {},
|
onPressed: () async {
|
||||||
|
Provider.of<GameStateProvider>(context,
|
||||||
|
listen: false)
|
||||||
|
.updateGameState();
|
||||||
|
},
|
||||||
child: const Center(
|
child: const Center(
|
||||||
child: Text("Download"),
|
child: Text("Download"),
|
||||||
),
|
),
|
||||||
|
|||||||
21
babylonia_terminal_launcher/messages/game_state.proto
Normal file
21
babylonia_terminal_launcher/messages/game_state.proto
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package game_state;
|
||||||
|
|
||||||
|
enum States {
|
||||||
|
ProtonNotInstalled = 0;
|
||||||
|
DXVKNotInstalled = 1;
|
||||||
|
FontNotInstalled = 2;
|
||||||
|
DependecieNotInstalled = 3;
|
||||||
|
GameNotInstalled = 4;
|
||||||
|
GameNeedUpdate = 5;
|
||||||
|
GameNotPatched = 6;
|
||||||
|
GameInstalled = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [RINF:RUST-SIGNAL]
|
||||||
|
message GameState {
|
||||||
|
States state = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [RINF:DART-SIGNAL]
|
||||||
|
message AskGameState {}
|
||||||
19
babylonia_terminal_launcher/native/hub/Cargo.toml
Executable file
19
babylonia_terminal_launcher/native/hub/Cargo.toml
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
# Do not change the name of this crate.
|
||||||
|
name = "hub"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
# `lib` is required for non-library targets,
|
||||||
|
# such as tests and benchmarks.
|
||||||
|
# `cdylib` is for Linux, Android, Windows, and web.
|
||||||
|
# `staticlib` is for iOS and macOS.
|
||||||
|
crate-type = ["lib", "cdylib", "staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rinf = "6.9.0"
|
||||||
|
prost = "0.12.3"
|
||||||
|
wasm-bindgen = "0.2.91"
|
||||||
|
tokio_with_wasm = "0.4.3"
|
||||||
|
babylonia-terminal-sdk = { path = "./../../../babylonia-terminal-sdk" }
|
||||||
31
babylonia_terminal_launcher/native/hub/src/game_state.rs
Normal file
31
babylonia_terminal_launcher/native/hub/src/game_state.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use babylonia_terminal_sdk::game_state::GameState;
|
||||||
|
|
||||||
|
use crate::messages::game_state::{AskGameState, GameState as GameStateMessage, States};
|
||||||
|
|
||||||
|
impl GameStateMessage {
|
||||||
|
fn from_sdk_state_to_msg_state(state: GameState) -> Self {
|
||||||
|
let game_state = match state {
|
||||||
|
GameState::ProtonNotInstalled => States::ProtonNotInstalled,
|
||||||
|
GameState::DXVKNotInstalled => States::DxvkNotInstalled,
|
||||||
|
GameState::FontNotInstalled => States::FontNotInstalled,
|
||||||
|
GameState::DependecieNotInstalled => States::DependecieNotInstalled,
|
||||||
|
GameState::GameNotInstalled => States::GameNotInstalled,
|
||||||
|
GameState::GameNeedUpdate => States::GameNeedUpdate,
|
||||||
|
GameState::GameNotPatched => States::GameNotPatched,
|
||||||
|
GameState::GameInstalled => States::GameInstalled,
|
||||||
|
};
|
||||||
|
GameStateMessage {
|
||||||
|
state: game_state.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_game_state() {
|
||||||
|
let mut receiver = AskGameState::get_dart_signal_receiver();
|
||||||
|
while let Some(_) = receiver.recv().await {
|
||||||
|
let result_state = GameState::get_current_state().await;
|
||||||
|
if let Ok(state) = result_state {
|
||||||
|
GameStateMessage::from_sdk_state_to_msg_state(state).send_signal_to_dart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
babylonia_terminal_launcher/native/hub/src/lib.rs
Executable file
25
babylonia_terminal_launcher/native/hub/src/lib.rs
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
//! This `hub` crate is the
|
||||||
|
//! entry point of the Rust logic.
|
||||||
|
|
||||||
|
// This `tokio` will be used by Rinf.
|
||||||
|
// You can replace it with the original `tokio`
|
||||||
|
// if you're not targeting the web.
|
||||||
|
use tokio_with_wasm::tokio;
|
||||||
|
|
||||||
|
mod game_state;
|
||||||
|
mod messages;
|
||||||
|
|
||||||
|
rinf::write_interface!();
|
||||||
|
|
||||||
|
// Always use non-blocking async functions
|
||||||
|
// such as `tokio::fs::File::open`.
|
||||||
|
// If you really need to use blocking code,
|
||||||
|
// use `tokio::task::spawn_blocking`.
|
||||||
|
async fn main() {
|
||||||
|
// Repeat `tokio::spawn` anywhere in your code
|
||||||
|
// if more concurrent tasks are needed.
|
||||||
|
//tokio::spawn(sample_functions::tell_numbers());
|
||||||
|
//tokio::spawn(sample_functions::stream_fractal());
|
||||||
|
//tokio::spawn(sample_functions::run_debug_tests());
|
||||||
|
tokio::spawn(game_state::get_game_state());
|
||||||
|
}
|
||||||
@ -44,6 +44,8 @@ dependencies:
|
|||||||
media_kit_libs_video: any
|
media_kit_libs_video: any
|
||||||
media_kit_native_event_loop: any
|
media_kit_native_event_loop: any
|
||||||
provider: ^6.1.2
|
provider: ^6.1.2
|
||||||
|
rinf: ^6.9.0
|
||||||
|
protobuf: ^3.1.0
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
media_kit:
|
media_kit:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user