can now start the game from GUI

This commit is contained in:
ALEZ-DEV 2024-06-10 21:39:06 +02:00
parent 62ffdd2dff
commit 787b1ea216
11 changed files with 189 additions and 84 deletions

View File

@ -11,8 +11,14 @@ enum GameInstallationState {
patching, patching,
} }
enum GameRunState {
idle,
running,
}
class Game with ChangeNotifier { class Game with ChangeNotifier {
GameInstallationState gameInstallationState = GameInstallationState.idle; GameInstallationState gameInstallationState = GameInstallationState.idle;
GameRunState gameRunState = GameRunState.idle;
Int64 currentProgress = Int64(0); Int64 currentProgress = Int64(0);
Int64 maxProgress = Int64(0); Int64 maxProgress = Int64(0);
@ -55,4 +61,17 @@ class Game with ChangeNotifier {
break; break;
} }
} }
Future startGame() async {
RunGame().sendSignalToRust();
gameRunState = GameRunState.running;
notifyListeners();
final stream = GameStopped.rustSignalStream;
await for (final _ in stream) {
gameRunState = GameRunState.idle;
notifyListeners();
break;
}
}
} }

View File

@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
import '../widgets/background_widget.dart'; import '../widgets/background_widget.dart';
import '../widgets/serious_lee_widget.dart'; import '../widgets/serious_lee_widget.dart';
import '../widgets/simple_button.dart'; import '../widgets/play_button.dart';
import '../widgets/steps/game_steps_widget.dart'; import '../widgets/steps/game_steps_widget.dart';
import './../providers/providers.dart'; import './../providers/providers.dart';
import './../models/settings.dart'; import './../models/settings.dart';
@ -22,38 +22,7 @@ class HomeScreen extends StatelessWidget {
const ShowBackground(), const ShowBackground(),
gameStateProvider.gameState != States.GameInstalled gameStateProvider.gameState != States.GameInstalled
? const GameSteps() ? const GameSteps()
: Padding( : const PlayButton(),
padding: const EdgeInsets.all(50.0),
child: Row(
children: [
const Expanded(
child: SizedBox(),
),
const Expanded(
child: SizedBox(),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 600,
maxHeight: 50,
),
child: SimpleButton(
onPressed: () async {},
child: const Center(
child: Text("Play"),
),
),
),
],
),
),
],
),
),
], ],
); );
} }

View File

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './simple_button.dart';
import './../models/game.dart';
class PlayButton extends StatelessWidget {
const PlayButton({super.key});
@override
Widget build(BuildContext context) {
final game = Provider.of<Game>(context);
return Padding(
padding: const EdgeInsets.all(50.0),
child: Row(
children: [
const Expanded(
child: SizedBox(),
),
const Expanded(
child: SizedBox(),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 600,
maxHeight: 50,
),
child: SimpleButton(
onPressed: game.gameRunState == GameRunState.idle
? () {
Provider.of<Game>(context, listen: false)
.startGame();
}
: null,
child: Center(
child: game.gameRunState == GameRunState.idle
? const Text("Play")
: const Text("Running..."),
),
),
),
],
),
),
],
),
);
}
}

View File

@ -20,3 +20,9 @@ message NotifyGameStartPatching {}
// [RINF:RUST-SIGNAL] // [RINF:RUST-SIGNAL]
message NotifyGameSuccessfullyInstalled {} message NotifyGameSuccessfullyInstalled {}
// [RINF:DART-SIGNAL]
message RunGame {}
// [RINF:RUST-SIGNAL]
message GameStopped {}

View File

@ -17,5 +17,12 @@ prost = "0.12.3"
wasm-bindgen = "0.2.91" wasm-bindgen = "0.2.91"
tokio_with_wasm = "0.4.3" tokio_with_wasm = "0.4.3"
babylonia-terminal-sdk = { path = "./../../../babylonia-terminal-sdk" } babylonia-terminal-sdk = { path = "./../../../babylonia-terminal-sdk" }
downloader = { git = "https://github.com/ALEZ-DEV/downloader" } # version = "0.2.7", downloader = { git = "https://github.com/ALEZ-DEV/downloader" } # version = "0.2.7",
once_cell = "1.19.0" once_cell = "1.19.0"
wincompatlib = { version = "0.7.4", features = [
"dxvk",
"wine-bundles",
"wine-proton",
"wine-fonts",
"winetricks",
] }

View File

@ -5,23 +5,20 @@ use babylonia_terminal_sdk::{
}; };
use tokio_with_wasm::tokio; use tokio_with_wasm::tokio;
use crate::messages::{ use crate::{
error::ReportError, messages::{
steps::dependencies::{NotifyDependenciesSuccessfullyInstalled, StartDependenciesInstallation}, error::ReportError,
steps::dependencies::{
NotifyDependenciesSuccessfullyInstalled, StartDependenciesInstallation,
},
},
proton::get_proton,
}; };
pub async fn listen_dependecies_installation() { pub async fn listen_dependecies_installation() {
let mut receiver = StartDependenciesInstallation::get_dart_signal_receiver(); let mut receiver = StartDependenciesInstallation::get_dart_signal_receiver();
while let Some(_) = receiver.recv().await { while let Some(_) = receiver.recv().await {
let proton_component = ProtonComponent::new(GameState::get_config().await.config_dir); let proton = get_proton().await;
let proton = proton_component.init_proton();
if let Err(e) = proton {
ReportError {
error_message: format!("Failed to install DXVK : {}", e),
}
.send_signal_to_dart();
continue;
}
thread::spawn(move || { thread::spawn(move || {
tokio::runtime::Builder::new_current_thread() tokio::runtime::Builder::new_current_thread()
@ -29,7 +26,7 @@ pub async fn listen_dependecies_installation() {
.build() .build()
.unwrap() .unwrap()
.block_on(async { .block_on(async {
match GameManager::install_dependencies(&proton.unwrap()).await { match GameManager::install_dependencies(&proton).await {
Err(e) => ReportError { Err(e) => ReportError {
error_message: format!("Failed to install dependencies : {}", e), error_message: format!("Failed to install dependencies : {}", e),
} }

View File

@ -20,6 +20,7 @@ use crate::{
StartDxvkInstallation, StartDxvkInstallation,
}, },
}, },
proton::get_proton,
}; };
pub async fn listen_dxvk_installation() { pub async fn listen_dxvk_installation() {
@ -48,15 +49,7 @@ pub async fn listen_dxvk_installation() {
continue; continue;
} }
let proton_component = ProtonComponent::new(GameState::get_config().await.config_dir); let proton = get_proton().await;
let proton = proton_component.init_proton();
if let Err(e) = proton {
ReportError {
error_message: format!("Failed to install DXVK : {}", e),
}
.send_signal_to_dart();
continue;
}
thread::spawn(move || { thread::spawn(move || {
tokio::runtime::Builder::new_current_thread() tokio::runtime::Builder::new_current_thread()
@ -65,7 +58,7 @@ pub async fn listen_dxvk_installation() {
.unwrap() .unwrap()
.block_on(async { .block_on(async {
match GameManager::install_dxvk( match GameManager::install_dxvk(
&proton.unwrap(), &proton,
GameState::get_config().await.config_dir, GameState::get_config().await.config_dir,
release_index.unwrap(), release_index.unwrap(),
Some(DownloadReporter::create()), Some(DownloadReporter::create()),

View File

@ -5,25 +5,20 @@ use babylonia_terminal_sdk::{
}; };
use tokio_with_wasm::tokio; use tokio_with_wasm::tokio;
use crate::messages::{ use crate::{
error::ReportError, messages::{
steps::fonts::{ error::ReportError,
FontsInstallationProgress, NotifyFontsSuccessfullyInstalled, StartFontsInstallation, steps::fonts::{
FontsInstallationProgress, NotifyFontsSuccessfullyInstalled, StartFontsInstallation,
},
}, },
proton::get_proton,
}; };
pub async fn listen_fonts_installation() { pub async fn listen_fonts_installation() {
let mut receiver = StartFontsInstallation::get_dart_signal_receiver(); let mut receiver = StartFontsInstallation::get_dart_signal_receiver();
while let Some(_) = receiver.recv().await { while let Some(_) = receiver.recv().await {
let proton_component = ProtonComponent::new(GameState::get_config().await.config_dir); let proton = get_proton().await;
let proton = proton_component.init_proton();
if let Err(e) = proton {
ReportError {
error_message: format!("Failed to install DXVK : {}", e),
}
.send_signal_to_dart();
continue;
}
thread::spawn(move || { thread::spawn(move || {
tokio::runtime::Builder::new_current_thread() tokio::runtime::Builder::new_current_thread()
@ -31,11 +26,8 @@ pub async fn listen_fonts_installation() {
.build() .build()
.unwrap() .unwrap()
.block_on(async { .block_on(async {
match GameManager::install_font( match GameManager::install_font(&proton, Some(InstallationReporter::create()))
&proton.unwrap(), .await
Some(InstallationReporter::create()),
)
.await
{ {
Err(e) => ReportError { Err(e) => ReportError {
error_message: format!("Failed to install DXVK : {}", e), error_message: format!("Failed to install DXVK : {}", e),

View File

@ -6,14 +6,38 @@ use babylonia_terminal_sdk::{
use rinf::debug_print; use rinf::debug_print;
use tokio_with_wasm::tokio; use tokio_with_wasm::tokio;
use crate::messages::{ use crate::{
error::ReportError, messages::{
steps::game::{ error::ReportError,
GameInstallationProgress, NotifyGameStartDownloading, NotifyGameStartPatching, steps::game::{
NotifyGameSuccessfullyInstalled, StartGameInstallation, GameInstallationProgress, GameStopped, NotifyGameStartDownloading,
NotifyGameStartPatching, NotifyGameSuccessfullyInstalled, RunGame,
StartGameInstallation,
},
}, },
proton::get_proton,
}; };
pub async fn listen_game_running() {
let mut receiver = RunGame::get_dart_signal_receiver();
while let Some(_) = receiver.recv().await {
let proton = get_proton().await;
let game_dir = GameState::get_game_dir().await;
if game_dir.is_none() {
ReportError {
error_message: "Failed to start game, the game directory was not found".to_string(),
}
.send_signal_to_dart();
GameStopped {}.send_signal_to_dart();
continue;
}
GameManager::start_game(&proton, game_dir.unwrap()).await;
GameStopped {}.send_signal_to_dart();
}
}
pub async fn listen_game_installation() { pub async fn listen_game_installation() {
let mut receiver = StartGameInstallation::get_dart_signal_receiver(); let mut receiver = StartGameInstallation::get_dart_signal_receiver();
while let Some(info) = receiver.recv().await { while let Some(info) = receiver.recv().await {
@ -24,6 +48,21 @@ pub async fn listen_game_installation() {
.build() .build()
.unwrap() .unwrap()
.block_on(async { .block_on(async {
if GameState::get_game_dir().await.is_none() {
if let Err(e) = GameState::set_game_dir(Some(
GameState::get_config_directory()
.await
.join("babylonia-terminal-config"),
))
.await
{
ReportError {
error_message: format!("Failed to set new path : {}", e),
}
.send_signal_to_dart();
}
}
if info.message.is_updating { if info.message.is_updating {
if let Err(e) = GameManager::update_game().await { if let Err(e) = GameManager::update_game().await {
ReportError { ReportError {
@ -33,10 +72,16 @@ pub async fn listen_game_installation() {
} }
} }
let game_dir = GameState::get_config().await.config_dir; let game_dir = GameState::get_game_dir().await;
if game_dir.is_none() {
ReportError {
error_message: "Failed to get the game directory".to_string(),
}
.send_signal_to_dart();
}
match GameManager::install_game( match GameManager::install_game(
game_dir.clone(), game_dir.clone().unwrap(),
InstallationReporter::create(), InstallationReporter::create(),
) )
.await .await
@ -48,7 +93,7 @@ pub async fn listen_game_installation() {
Ok(_) => { Ok(_) => {
NotifyGameStartPatching {}.send_signal_to_dart(); NotifyGameStartPatching {}.send_signal_to_dart();
debug_print!("start patching game..."); debug_print!("start patching game...");
match GameManager::patch_game(game_dir).await { match GameManager::patch_game(game_dir.unwrap()).await {
Err(e) => ReportError { Err(e) => ReportError {
error_message: format!("Failed to install game : {}", e), error_message: format!("Failed to install game : {}", e),
} }

View File

@ -27,4 +27,7 @@ async fn main() {
tokio::spawn(fonts::listen_fonts_installation()); tokio::spawn(fonts::listen_fonts_installation());
tokio::spawn(dependencies::listen_dependecies_installation()); tokio::spawn(dependencies::listen_dependecies_installation());
tokio::spawn(game::listen_game_installation()); tokio::spawn(game::listen_game_installation());
// game
tokio::spawn(game::listen_game_running());
} }

View File

@ -10,7 +10,8 @@ use babylonia_terminal_sdk::{
utils::github_requester::{GithubRelease, GithubRequester}, utils::github_requester::{GithubRelease, GithubRequester},
}; };
use rinf::debug_print; use rinf::debug_print;
use tokio_with_wasm::tokio; use tokio_with_wasm::tokio::{self, sync::OnceCell};
use wincompatlib::wine::bundle::proton::Proton;
use crate::{ use crate::{
github::GithubInfo, github::GithubInfo,
@ -23,6 +24,25 @@ use crate::{
}, },
}; };
static PROTON: OnceCell<Proton> = OnceCell::const_new();
pub async fn get_proton() -> Proton {
PROTON
.get_or_init(|| async {
let proton_component = ProtonComponent::new(GameState::get_config().await.config_dir);
let proton = proton_component.init_proton();
if let Err(ref e) = proton {
ReportError {
error_message: format!("Failed to initialize proton : {}", e),
}
.send_signal_to_dart();
}
proton.unwrap()
})
.await
.clone()
}
pub async fn listen_proton_installation() { pub async fn listen_proton_installation() {
let mut receiver = StartProtonInstallation::get_dart_signal_receiver(); let mut receiver = StartProtonInstallation::get_dart_signal_receiver();
while let Some(info) = receiver.recv().await { while let Some(info) = receiver.recv().await {