Add channel to send messages up from methods like fetch_events to hud

This commit is contained in:
Joey Maher 2020-06-05 14:14:07 -05:00
parent 33ca76a52f
commit fb75587f2d
5 changed files with 49 additions and 10 deletions

View File

@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Eyebrows and shapes can now be selected - Eyebrows and shapes can now be selected
- Character name and level information to chat, social tab and `/players` command. - Character name and level information to chat, social tab and `/players` command.
- Added inventory, armour and weapon saving - Added inventory, armour and weapon saving
- Show where screenshots are saved to in the chat
### Changed ### Changed

View File

@ -7,11 +7,11 @@ use crate::{
window::Event as WinEvent, window::Event as WinEvent,
Direction, GlobalState, PlayState, PlayStateResult, Direction, GlobalState, PlayState, PlayStateResult,
}; };
use client::{self, Client}; use client::{self, Client, Event as ClientEvent};
use common::{assets, clock::Clock, comp, msg::ClientState, state::DeltaTime}; use common::{assets, clock::Clock, comp, msg::ClientState, state::DeltaTime};
use log::error; use log::error;
use specs::WorldExt; use specs::WorldExt;
use std::{cell::RefCell, rc::Rc, time::Duration}; use std::{cell::RefCell, rc::Rc, time::Duration, sync::mpsc};
use ui::CharSelectionUi; use ui::CharSelectionUi;
pub struct CharSelectionState { pub struct CharSelectionState {
@ -42,10 +42,12 @@ impl PlayState for CharSelectionState {
// Load the player's character list // Load the player's character list
self.client.borrow_mut().load_character_list(); self.client.borrow_mut().load_character_list();
let (message_sender, _message_receiver): (mpsc::Sender<ClientEvent>, mpsc::Receiver<ClientEvent>) = mpsc::channel();
let mut current_client_state = self.client.borrow().get_client_state(); let mut current_client_state = self.client.borrow().get_client_state();
while let ClientState::Pending | ClientState::Registered = current_client_state { while let ClientState::Pending | ClientState::Registered = current_client_state {
// Handle window events // Handle window events
for event in global_state.window.fetch_events(&mut global_state.settings) { for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) {
if self.char_selection_ui.handle_event(event.clone()) { if self.char_selection_ui.handle_event(event.clone()) {
continue; continue;
} }

View File

@ -11,6 +11,8 @@ use log::{error, warn};
#[cfg(feature = "singleplayer")] #[cfg(feature = "singleplayer")]
use std::time::Duration; use std::time::Duration;
use ui::{Event as MainMenuEvent, MainMenuUi}; use ui::{Event as MainMenuEvent, MainMenuUi};
use std::sync::mpsc;
use client::{self, Event as ClientEvent};
pub struct MainMenuState { pub struct MainMenuState {
main_menu_ui: MainMenuUi, main_menu_ui: MainMenuUi,
@ -47,9 +49,11 @@ impl PlayState for MainMenuState {
&crate::i18n::i18n_asset_key(&global_state.settings.language.selected_language), &crate::i18n::i18n_asset_key(&global_state.settings.language.selected_language),
); );
let (message_sender, _message_receiver): (mpsc::Sender<ClientEvent>, mpsc::Receiver<ClientEvent>) = mpsc::channel();
loop { loop {
// Handle window events. // Handle window events.
for event in global_state.window.fetch_events(&mut global_state.settings) { for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) {
match event { match event {
Event::Close => return PlayStateResult::Shutdown, Event::Close => return PlayStateResult::Shutdown,
// Pass events to ui. // Pass events to ui.

View File

@ -9,7 +9,7 @@ use crate::{
window::{AnalogGameInput, Event, GameInput}, window::{AnalogGameInput, Event, GameInput},
Direction, Error, GlobalState, PlayState, PlayStateResult, Direction, Error, GlobalState, PlayState, PlayStateResult,
}; };
use client::{self, Client, Event::Chat}; use client::{self, Client, Event::Chat, Event as ClientEvent};
use common::{ use common::{
assets::{load_watched, watch}, assets::{load_watched, watch},
clock::Clock, clock::Clock,
@ -23,7 +23,7 @@ use common::{
}; };
use log::error; use log::error;
use specs::{Join, WorldExt}; use specs::{Join, WorldExt};
use std::{cell::RefCell, rc::Rc, time::Duration}; use std::{cell::RefCell, rc::Rc, time::Duration, sync::mpsc};
use vek::*; use vek::*;
/// The action to perform after a tick /// The action to perform after a tick
@ -143,6 +143,8 @@ impl PlayState for SessionState {
let mut ori = self.scene.camera().get_orientation(); let mut ori = self.scene.camera().get_orientation();
let mut free_look = false; let mut free_look = false;
let (message_sender, message_receiver): (mpsc::Sender<ClientEvent>, mpsc::Receiver<ClientEvent>) = mpsc::channel();
// Game loop // Game loop
let mut current_client_state = self.client.borrow().get_client_state(); let mut current_client_state = self.client.borrow().get_client_state();
while let ClientState::Pending | ClientState::Character = current_client_state { while let ClientState::Pending | ClientState::Character = current_client_state {
@ -224,8 +226,14 @@ impl PlayState for SessionState {
.unwrap_or(false) .unwrap_or(false)
})); }));
// Receive any ClientEvents sent through the message channel
match message_receiver.try_recv() {
Ok(message_event) => self.hud.new_message(message_event),
Err(_x) => {},
};
// Handle window events. // Handle window events.
for event in global_state.window.fetch_events(&mut global_state.settings) { for event in global_state.window.fetch_events(&mut global_state.settings, &message_sender) {
// Pass all events to the ui first. // Pass all events to the ui first.
if self.hud.handle_event(event.clone(), global_state) { if self.hud.handle_event(event.clone(), global_state) {
continue; continue;

View File

@ -10,6 +10,11 @@ use hashbrown::HashMap;
use log::{error, warn}; use log::{error, warn};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::sync::mpsc::Sender;
use client::{self, Event as ClientEvent};
use common::{
ChatType,
};
use vek::*; use vek::*;
/// Represents a key that the game recognises after input mapping. /// Represents a key that the game recognises after input mapping.
@ -483,7 +488,7 @@ impl Window {
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer } pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
pub fn fetch_events(&mut self, settings: &mut Settings) -> Vec<Event> { pub fn fetch_events(&mut self, settings: &mut Settings, message_sender: &Sender<ClientEvent>) -> Vec<Event> {
let mut events = vec![]; let mut events = vec![];
events.append(&mut self.supplement_events); events.append(&mut self.supplement_events);
// Refresh ui size (used when changing playstates) // Refresh ui size (used when changing playstates)
@ -651,7 +656,7 @@ impl Window {
} }
if take_screenshot { if take_screenshot {
self.take_screenshot(&settings); self.take_screenshot(&settings, &message_sender);
} }
if toggle_fullscreen { if toggle_fullscreen {
@ -924,10 +929,11 @@ impl Window {
pub fn send_supplement_event(&mut self, event: Event) { self.supplement_events.push(event) } pub fn send_supplement_event(&mut self, event: Event) { self.supplement_events.push(event) }
pub fn take_screenshot(&mut self, settings: &Settings) { pub fn take_screenshot(&mut self, settings: &Settings, message_sender: &Sender<ClientEvent>) {
match self.renderer.create_screenshot() { match self.renderer.create_screenshot() {
Ok(img) => { Ok(img) => {
let mut path = settings.screenshots_path.clone(); let mut path = settings.screenshots_path.clone();
let sender = message_sender.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
use std::time::SystemTime; use std::time::SystemTime;
@ -935,6 +941,10 @@ impl Window {
if !path.exists() { if !path.exists() {
if let Err(err) = std::fs::create_dir_all(&path) { if let Err(err) = std::fs::create_dir_all(&path) {
warn!("Couldn't create folder for screenshot: {:?}", err); warn!("Couldn't create folder for screenshot: {:?}", err);
let _result = sender.send(ClientEvent::Chat {
chat_type: ChatType::Meta,
message: String::from("Couldn't create folder for screenshot"),
});
} }
} }
path.push(format!( path.push(format!(
@ -946,6 +956,20 @@ impl Window {
)); ));
if let Err(err) = img.save(&path) { if let Err(err) = img.save(&path) {
warn!("Couldn't save screenshot: {:?}", err); warn!("Couldn't save screenshot: {:?}", err);
let _result = sender.send(ClientEvent::Chat {
chat_type: ChatType::Meta,
message: String::from("Couldn't save screenshot"),
});
} else {
match path.to_str() {
Some(x) => {
let _result = sender.send(ClientEvent::Chat {
chat_type: ChatType::Meta,
message: format!("Screenshot saved to {}", x),
});
},
None => {}
}
} }
}); });
}, },