Process callbacks asynchronously
This commit is contained in:
parent
20332deb41
commit
9c0250e1f6
5 changed files with 32 additions and 12 deletions
|
@ -135,9 +135,9 @@ impl ButtonBuilder {
|
|||
},
|
||||
)?;
|
||||
|
||||
let click_executable = Executable::new();
|
||||
let select_executable = Executable::new();
|
||||
let on_select_executable = Executable::new();
|
||||
let click_executable = Executable::new(&gui_handler);
|
||||
let select_executable = Executable::new(&gui_handler);
|
||||
let on_select_executable = Executable::new(&gui_handler);
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
let click_sound = self
|
||||
|
|
|
@ -82,7 +82,7 @@ impl MultiLineTextFieldBuilder {
|
|||
}
|
||||
|
||||
let text = Arc::new(SplittedText::new(self.text));
|
||||
let text_changed_exec = Executable::new();
|
||||
let text_changed_exec = Executable::new(&gui_handler);
|
||||
let writeable = Writeable::new(gui_handler, text.clone(), text_changed_exec.clone())?;
|
||||
|
||||
let multi_line_text_field = Arc::new(MultiLineTextField {
|
||||
|
|
|
@ -69,7 +69,7 @@ impl TextFieldBuilder {
|
|||
self.text_color,
|
||||
)?;
|
||||
|
||||
let text_changed_executable = Executable::new();
|
||||
let text_changed_executable = Executable::new(&gui_handler);
|
||||
|
||||
let writeable = Writeable::new(
|
||||
gui_handler,
|
||||
|
|
|
@ -4,15 +4,19 @@ use anyhow::Result;
|
|||
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
/// `Executable` holds a closure which can be executed
|
||||
pub struct Executable<I> {
|
||||
callback: RwLock<Option<Box<dyn Fn(I) -> Result<()> + Send + Sync>>>,
|
||||
pub struct Executable<I: Send + Sync + 'static> {
|
||||
gui_handler: Arc<GuiHandler>,
|
||||
callback: RwLock<Option<Arc<dyn Fn(I) -> Result<()> + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl<I> Executable<I> {
|
||||
impl<I: Send + Sync + 'static> Executable<I> {
|
||||
/// Factory method for `Executable`, returns `Arc<Executable>`
|
||||
pub fn new() -> Arc<Self> {
|
||||
pub fn new(gui_handler: &Arc<GuiHandler>) -> Arc<Self> {
|
||||
Arc::new(Executable {
|
||||
gui_handler: gui_handler.clone(),
|
||||
callback: RwLock::new(None),
|
||||
})
|
||||
}
|
||||
|
@ -29,7 +33,7 @@ impl<I> Executable<I> {
|
|||
let mut function = self.callback.write().unwrap();
|
||||
|
||||
match callback.into() {
|
||||
Some(f) => *function = Some(Box::new(f)),
|
||||
Some(f) => *function = Some(Arc::new(f)),
|
||||
None => *function = None,
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +41,9 @@ impl<I> Executable<I> {
|
|||
/// Execute the callback closure if possible
|
||||
pub fn execute(&self, input: I) -> Result<()> {
|
||||
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
||||
(callback)(input)?;
|
||||
let callback = callback.clone();
|
||||
|
||||
self.gui_handler.add_callback(move || (callback)(input));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -14,12 +14,12 @@ use super::{
|
|||
|
||||
use cgmath::{ortho, vec2};
|
||||
|
||||
use std::sync::Weak;
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
||||
Arc, Mutex, RwLock,
|
||||
};
|
||||
use std::{collections::HashMap, ptr};
|
||||
use std::{mem, sync::Weak};
|
||||
|
||||
use paste::paste;
|
||||
|
||||
|
@ -257,6 +257,8 @@ pub struct GuiHandler {
|
|||
current_selectable: RwLock<Option<Arc<Selectable>>>,
|
||||
|
||||
text_sample_count: VkSampleCountFlags,
|
||||
|
||||
callback_list: Mutex<Vec<Box<dyn FnOnce() -> Result<()> + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl GuiHandler {
|
||||
|
@ -403,6 +405,8 @@ impl GuiHandler {
|
|||
current_writeable: RwLock::new(None),
|
||||
|
||||
text_sample_count,
|
||||
|
||||
callback_list: Mutex::default(),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -881,6 +885,16 @@ impl GuiHandler {
|
|||
*self.tooltip_ui.write().unwrap() = tooltip;
|
||||
}
|
||||
|
||||
pub(crate) fn add_callback<F: FnOnce() -> Result<()> + Send + Sync + 'static>(&self, f: F) {
|
||||
self.callback_list.lock().unwrap().push(Box::new(f));
|
||||
}
|
||||
|
||||
pub fn process_callbacks(&self) -> Result<()> {
|
||||
mem::take(&mut *self.callback_list.lock().unwrap())
|
||||
.into_iter()
|
||||
.try_for_each(|callback| callback())
|
||||
}
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
|
|
Loading…
Reference in a new issue