Add replay finished popups
This commit is contained in:
parent
7ebef6172c
commit
c6961134c0
@ -1,4 +1,10 @@
|
|||||||
use std::{collections::HashMap, fs, io::Cursor, thread};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs,
|
||||||
|
io::Cursor,
|
||||||
|
sync::mpsc::{Receiver, channel},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
use flate2::{Compression, bufread::GzDecoder, write::GzEncoder};
|
use flate2::{Compression, bufread::GzDecoder, write::GzEncoder};
|
||||||
use godot::{
|
use godot::{
|
||||||
@ -484,6 +490,11 @@ impl ReplayPlayback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ReplaySaveEvent {
|
||||||
|
Error(String),
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(base=Node, init)]
|
#[class(base=Node, init)]
|
||||||
pub struct ReplayRecorder {
|
pub struct ReplayRecorder {
|
||||||
@ -494,6 +505,8 @@ pub struct ReplayRecorder {
|
|||||||
|
|
||||||
recording: bool,
|
recording: bool,
|
||||||
|
|
||||||
|
pub recv: Option<Receiver<ReplaySaveEvent>>,
|
||||||
|
|
||||||
base: Base<Node>,
|
base: Base<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,17 +559,42 @@ impl INode for ReplayRecorder {
|
|||||||
self.current_frame = self.record_frame();
|
self.current_frame = self.record_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process(&mut self, _: f64) {
|
||||||
|
if let Some(recv) = &self.recv {
|
||||||
|
if let Ok(data) = recv.recv() {
|
||||||
|
match data {
|
||||||
|
ReplaySaveEvent::Error(err) => self.signals().on_saved().emit(&err),
|
||||||
|
ReplaySaveEvent::Done => self.signals().on_saved().emit(&String::new()),
|
||||||
|
}
|
||||||
|
self.recv.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
impl ReplayRecorder {
|
impl ReplayRecorder {
|
||||||
pub fn save_to(&self, path: &GString) {
|
#[signal]
|
||||||
|
pub fn on_saved(error: GString);
|
||||||
|
|
||||||
|
pub fn save_to(&mut self, path: &GString) {
|
||||||
let path = path.to_string();
|
let path = path.to_string();
|
||||||
let replay = self.replay.clone();
|
let replay = self.replay.clone();
|
||||||
|
|
||||||
|
let (send, recv) = channel();
|
||||||
|
self.recv = Some(recv);
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
let encoder = GzEncoder::new(&mut bytes, Compression::default());
|
let encoder = GzEncoder::new(&mut bytes, Compression::default());
|
||||||
ciborium::into_writer(&replay, encoder).ok();
|
match ciborium::into_writer(&replay, encoder) {
|
||||||
fs::write(path, bytes).ok();
|
Ok(_) => match fs::write(path, bytes) {
|
||||||
|
Ok(_) => send.send(ReplaySaveEvent::Done).ok(),
|
||||||
|
Err(e) => send.send(ReplaySaveEvent::Error(e.to_string())).ok(),
|
||||||
|
},
|
||||||
|
Err(e) => send.send(ReplaySaveEvent::Error(e.to_string())).ok(),
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
use godot::{
|
use godot::{
|
||||||
classes::{Button, FileDialog, HBoxContainer, IPanel, Label, Panel},
|
classes::{
|
||||||
|
AcceptDialog, Button, FileDialog, HBoxContainer, IPanel, Label, Panel, PopupPanel,
|
||||||
|
window::WindowInitialPosition,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,6 +24,9 @@ pub struct GameFinishedScreen {
|
|||||||
#[export]
|
#[export]
|
||||||
save_file_dialog: Option<Gd<FileDialog>>,
|
save_file_dialog: Option<Gd<FileDialog>>,
|
||||||
|
|
||||||
|
saving_replay_popup: Option<Gd<PopupPanel>>,
|
||||||
|
saving_replay_accept_dialog: Option<Gd<AcceptDialog>>,
|
||||||
|
|
||||||
base: Base<Panel>,
|
base: Base<Panel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +51,15 @@ impl IPanel for GameFinishedScreen {
|
|||||||
.file_selected()
|
.file_selected()
|
||||||
.connect_other(self, Self::save_replay);
|
.connect_other(self, Self::save_replay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(game) = &mut Game::singleton()
|
||||||
|
&& let Some(recorder) = &mut game.bind_mut().replay_recorder
|
||||||
|
{
|
||||||
|
recorder
|
||||||
|
.signals()
|
||||||
|
.on_saved()
|
||||||
|
.connect_other(self, Self::on_replay_saved);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,10 +118,44 @@ impl GameFinishedScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_replay(&mut self, path: GString) {
|
pub fn save_replay(&mut self, path: GString) {
|
||||||
if let Some(game) = &Game::singleton()
|
if let Some(game) = &mut Game::singleton()
|
||||||
&& let Some(recorder) = &game.bind().replay_recorder
|
&& let Some(recorder) = &mut game.bind_mut().replay_recorder
|
||||||
{
|
{
|
||||||
recorder.bind().save_to(&path);
|
let mut popup = PopupPanel::new_alloc();
|
||||||
|
popup.set_initial_position(WindowInitialPosition::CENTER_MAIN_WINDOW_SCREEN);
|
||||||
|
popup.set_title("Saving replay");
|
||||||
|
let mut label = Label::new_alloc();
|
||||||
|
label.set_text("Saving replay");
|
||||||
|
popup.add_child(&label);
|
||||||
|
self.base_mut().add_child(&popup);
|
||||||
|
|
||||||
|
popup.show();
|
||||||
|
|
||||||
|
self.saving_replay_popup = Some(popup);
|
||||||
|
|
||||||
|
recorder.bind_mut().save_to(&path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_replay_saved(&mut self, err: GString) {
|
||||||
|
if let Some(popup) = self.saving_replay_popup.clone() {
|
||||||
|
self.base_mut().remove_child(&popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut popup = AcceptDialog::new_alloc();
|
||||||
|
popup.set_initial_position(WindowInitialPosition::CENTER_MAIN_WINDOW_SCREEN);
|
||||||
|
popup.set_title("Save Finished");
|
||||||
|
let mut label = Label::new_alloc();
|
||||||
|
let text: GString = if err.is_empty() {
|
||||||
|
"Replay Saved!".into()
|
||||||
|
} else {
|
||||||
|
(&format!("Error: {}", err)).into()
|
||||||
|
};
|
||||||
|
label.set_text(&text);
|
||||||
|
popup.add_child(&label);
|
||||||
|
|
||||||
|
popup.show();
|
||||||
|
|
||||||
|
self.base_mut().add_child(&popup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,12 +85,4 @@ impl ReplayFinishedScreen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_replay(&mut self, path: GString) {
|
|
||||||
if let Some(game) = &Game::singleton()
|
|
||||||
&& let Some(recorder) = &game.bind().replay_recorder
|
|
||||||
{
|
|
||||||
recorder.bind().save_to(&path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user