Compare commits

..

1 commit

Author SHA1 Message Date
87893d2973 Update Rust crate quick-xml to 0.37.0
Some checks failed
Gavania Merge Build / build (pull_request) Failing after 2m18s
2025-03-04 15:05:35 +00:00
16 changed files with 152 additions and 217 deletions

View file

@ -14,7 +14,7 @@ anyhow = { version = "1.0.86", features = ["backtrace"] }
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
ecs = { git = "https://gavania.de/hodasemi/ecs.git" }
ecs = { git = "https://gavania.de/hodasemi/engine.git" }
# optional
audio = { git = "https://gavania.de/hodasemi/audio.git", optional = true }

View file

@ -2,7 +2,6 @@ use crate::prelude::*;
use anyhow::{Context, Result, bail};
use assetpath::AssetPath;
use ecs::World;
use super::validator::buttoninfo::{NeighbourDirection, NeighbourInfo};
use super::validator::gridinfo::GridInfo;
@ -179,7 +178,10 @@ impl GuiBuilder {
impl Functionality for GuiBuilder {
fn set_click_callbacks(
&self,
functions: Vec<(&str, Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>)>,
functions: Vec<(
&str,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
) -> Result<()> {
for (function_name, callback) in functions {
let suffix_less_function_name = handle_function_suffix(function_name);
@ -193,20 +195,14 @@ impl Functionality for GuiBuilder {
fn set_vec_callbacks(
&self,
_functions: Vec<(
&str,
Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>,
)>,
_functions: Vec<(&str, Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>)>,
) -> Result<()> {
Ok(())
}
fn set_select_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, bool) -> Result<()> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<bool, ()>>)>,
) -> Result<()> {
for (function_name, callback) in callbacks {
let suffix_less_function_name = handle_function_suffix(function_name);
@ -220,10 +216,7 @@ impl Functionality for GuiBuilder {
fn set_custom_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<ControllerButton, bool>>)>,
) -> Result<()> {
for (function_name, callback) in callbacks {
let suffix_less_function_name = handle_function_suffix(function_name);
@ -269,7 +262,7 @@ impl GuiElementTraits for GuiBuilder {
}
impl TopGui for GuiBuilder {
fn decline(&self, _world: &mut World) -> Result<()> {
fn decline(&self, _gui_handler: &mut GuiHandler) -> Result<()> {
if let Some(decline_callback) = self.decline_callback.read().unwrap().as_ref() {
decline_callback()?;
}
@ -277,11 +270,11 @@ impl TopGui for GuiBuilder {
Ok(())
}
fn next_tab(&self, _world: &mut World, _: bool) -> Result<()> {
fn next_tab(&self, _gui_handler: &mut GuiHandler, _: bool) -> Result<()> {
Ok(())
}
fn previous_tab(&self, _world: &mut World, _: bool) -> Result<()> {
fn previous_tab(&self, _gui_handler: &mut GuiHandler, _: bool) -> Result<()> {
Ok(())
}
}

View file

@ -1,7 +1,6 @@
use std::{any::Any, collections::HashMap, sync::Arc};
use assetpath::AssetPath;
use ecs::World;
use super::validator::{
buttoninfo::NeighbourInfo,
@ -148,7 +147,10 @@ impl Gridable for GuiSnippet {
impl Functionality for GuiSnippet {
fn set_click_callbacks(
&self,
functions: Vec<(&str, Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>)>,
functions: Vec<(
&str,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
) -> Result<()> {
for (function_name, callback) in functions {
let suffix_less_function_name = handle_function_suffix(function_name);
@ -162,20 +164,14 @@ impl Functionality for GuiSnippet {
fn set_vec_callbacks(
&self,
_functions: Vec<(
&str,
Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>,
)>,
_functions: Vec<(&str, Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>)>,
) -> Result<()> {
Ok(())
}
fn set_select_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, bool) -> Result<()> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<bool, ()>>)>,
) -> Result<()> {
for (function_name, callback) in callbacks {
let suffix_less_function_name = handle_function_suffix(function_name);
@ -189,10 +185,7 @@ impl Functionality for GuiSnippet {
fn set_custom_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<ControllerButton, bool>>)>,
) -> Result<()> {
for (function_name, callback) in callbacks {
let suffix_less_function_name = handle_function_suffix(function_name);

View file

@ -5,7 +5,6 @@ use crate::{
use anyhow::{Result, anyhow};
use assetpath::AssetPath;
use ecs::World;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
@ -315,23 +314,23 @@ impl Button {
pub fn set_callback<F>(&self, callback: F)
where
F: Fn(&mut World) -> Result<()> + Send + Sync + 'static,
F: Fn(&mut GuiHandler) -> Result<()> + Send + Sync + 'static,
{
self.click_executable
.set_callback(move |world: &mut World, _: ()| callback(world));
.set_callback(move |gui_handler: &mut GuiHandler, _: ()| callback(gui_handler));
}
pub fn set_select_callback<F>(&self, callback: F)
where
F: Fn(&mut World, bool) -> Result<()> + Send + Sync + 'static,
F: Fn(bool) -> Result<()> + Send + Sync + 'static,
{
self.on_select_executable
.set_callback(move |world: &mut World, select: bool| callback(world, select));
.set_callback(move |_: &mut GuiHandler, select: bool| callback(select));
}
pub fn set_custom_callback<F>(&self, callback: F)
where
F: Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync + 'static,
F: Fn(ControllerButton) -> Result<bool> + Send + Sync + 'static,
{
self.selectable.set_custom_callback(callback);
}
@ -579,10 +578,8 @@ impl Button {
fn create_selected_changed_callback(button: Arc<Button>) {
let button_weak = Arc::downgrade(&button);
let selected_changed = move |world: &mut World, selected: bool| {
let selected_changed = move |gui_handler: &mut GuiHandler, selected: bool| {
if let Some(button) = button_weak.upgrade() {
let gui_handler = world.resources.get_mut::<GuiHandler>();
if selected {
button.set_button_state(gui_handler, ButtonState::Selected)?;
} else {

View file

@ -1,7 +1,6 @@
use std::any::Any;
use anyhow::Result;
use ecs::World;
use super::ControllerButton;
use crate::prelude::*;
@ -28,21 +27,18 @@ macro_rules! callbacks {
};
}
callbacks!(ClickCallbacks, Fn(&mut World, &mut GuiHandler) -> Result<()> + Send + Sync);
callbacks!(SelectCallbacks, Fn(&mut World, &mut GuiHandler, bool) -> anyhow::Result<()> + Send + Sync);
callbacks!(CustomCallbacks, Fn(&mut World, &mut GuiHandler, ControllerButton) -> anyhow::Result<bool> + Send + Sync);
callbacks!(
VecCallbacks,
Fn(&mut World, &mut GuiHandler, &dyn Any) -> Result<()> + Send + Sync
);
callbacks!(ClickCallbacks, Fn(&mut GuiHandler) -> Result<()> + Send + Sync);
callbacks!(SelectCallbacks, Fn(bool) -> anyhow::Result<()> + Send + Sync);
callbacks!(CustomCallbacks, Fn(ControllerButton) -> anyhow::Result<bool> + Send + Sync);
callbacks!(VecCallbacks, Fn(&dyn Any) -> Result<()> + Send + Sync);
#[cfg(test)]
mod test {
use super::*;
use anyhow::Result;
fn normal_fn() -> impl Fn(&mut World, &mut GuiHandler) -> Result<()> + Send + Sync {
|_, _| Ok(())
fn normal_fn() -> impl Fn(&mut GuiHandler) -> Result<()> + Send + Sync {
|_| Ok(())
}
#[test]
@ -54,7 +50,7 @@ mod test {
&self,
_callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, &mut GuiHandler) -> Result<()> + Send + Sync>,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
) -> Result<()> {
Ok(())

View file

@ -10,7 +10,6 @@ use std::sync::{
};
use anyhow::{Context, Result};
use ecs::World;
use utilities::prelude::*;
use super::fill_type::InnerFillType;
@ -97,9 +96,9 @@ impl MultiLineTextFieldBuilder {
multi_line_text_field.text_changed_exec.set_callback({
let weak_tf = Arc::downgrade(&multi_line_text_field);
move |world: &mut World, _text| {
move |gui_handler: &mut GuiHandler, _text| {
if let Some(tf) = weak_tf.upgrade() {
tf.update_text(world.resources.get_mut::<GuiHandler>())?;
tf.update_text(gui_handler)?;
}
Ok(())

View file

@ -1,6 +1,5 @@
use crate::{builder::validator::textfieldinfo::TextFieldInfo, prelude::*};
use anyhow::Result;
use ecs::World;
use utilities::prelude::*;
use std::sync::{
@ -170,7 +169,7 @@ impl TextField {
pub fn set_text_changed_callback<F>(&self, f: F)
where
F: Fn(&mut World, Option<String>) -> Result<()> + Send + Sync + 'static,
F: Fn(&mut GuiHandler, Option<String>) -> Result<()> + Send + Sync + 'static,
{
self.text_changed_executable.set_callback(f);
}

View file

@ -1,6 +1,5 @@
use crate::prelude::*;
use anyhow::Result;
use ecs::World;
use std::{any::Any, collections::HashMap, sync::Arc};
@ -27,31 +26,25 @@ where
pub trait Functionality {
fn set_click_callbacks(
&self,
callbacks: Vec<(&str, Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>)>,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
) -> Result<()>;
fn set_select_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, bool) -> Result<()> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<bool, ()>>)>,
) -> Result<()>;
fn set_custom_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<CustomCallback<ControllerButton, bool>>)>,
) -> Result<()>;
fn set_vec_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>)>,
) -> Result<()>;
}

View file

@ -1,7 +1,6 @@
//! `Executable` is a property to execute a closure
use anyhow::Result;
use ecs::World;
use std::sync::{Arc, RwLock};
@ -9,7 +8,7 @@ use crate::prelude::*;
/// `Executable` holds a closure which can be executed
pub struct Executable<I: Send + Sync> {
callback: RwLock<Option<Arc<dyn Fn(&mut World, I) -> Result<()> + Send + Sync>>>,
callback: RwLock<Option<Arc<dyn Fn(&mut GuiHandler, I) -> Result<()> + Send + Sync>>>,
}
impl<I: Send + Sync + 'static> Executable<I> {
@ -27,7 +26,7 @@ impl<I: Send + Sync + 'static> Executable<I> {
/// * `callback` is a `Option<Callback>` closure
pub fn set_callback<F>(&self, callback: impl Into<Option<F>>)
where
F: Fn(&mut World, I) -> Result<()> + Send + Sync + 'static,
F: Fn(&mut GuiHandler, I) -> Result<()> + Send + Sync + 'static,
{
let mut function = self.callback.write().unwrap();

View file

@ -3,7 +3,6 @@
use super::executable::Executable;
use crate::prelude::*;
use anyhow::Result;
use ecs::World;
use std::sync::{
Arc, RwLock, Weak,
@ -40,8 +39,7 @@ pub struct Selectable {
on_select_executable: Arc<Executable<bool>>,
// used for custom buttons
custom_callback:
RwLock<Option<Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>>>,
custom_callback: RwLock<Option<Box<dyn Fn(ControllerButton) -> Result<bool> + Send + Sync>>>,
}
impl Selectable {
@ -117,7 +115,7 @@ impl Selectable {
pub fn set_custom_callback<F>(&self, custom_callback: F)
where
F: Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync + 'static,
F: Fn(ControllerButton) -> Result<bool> + Send + Sync + 'static,
{
*self.custom_callback.write().unwrap() = Some(Box::new(custom_callback));
}
@ -178,13 +176,9 @@ impl Selectable {
Ok(())
}
pub(crate) fn custom_click_event(
&self,
world: &mut World,
button: ControllerButton,
) -> Result<bool> {
pub(crate) fn custom_click_event(&self, button: ControllerButton) -> Result<bool> {
if let Some(custom_callback) = self.custom_callback.read().unwrap().as_ref() {
if custom_callback(world, button)? {
if custom_callback(button)? {
#[cfg(feature = "audio")]
{
if let Some(audible) = self.click_audible.read().unwrap().as_ref() {

View file

@ -1,20 +1,21 @@
/// A trait that is used by the gui handler as the target for input
use anyhow::Result;
use ecs::World;
use crate::prelude::*;
pub trait TopGui: Send + Sync {
/// Decline method which is executed on `InputMap::B` press
fn decline(&self, world: &mut World) -> Result<()>;
fn decline(&self, gui_handler: &mut GuiHandler) -> Result<()>;
/// Method which is executed on `InputMap::RightButton` press
///
/// # Arguments
/// * `second_level` adds support for multiple tab layers, e.g. RB and RT press on controller
fn next_tab(&self, world: &mut World, second_level: bool) -> Result<()>;
fn next_tab(&self, gui_handler: &mut GuiHandler, second_level: bool) -> Result<()>;
/// Method which is executed on `InputMap::LeftButton` press
/// ///
/// # Arguments
/// * `second_level` adds support for multiple tab layers, e.g. RB and RT press on controller
fn previous_tab(&self, world: &mut World, second_level: bool) -> Result<()>;
fn previous_tab(&self, gui_handler: &mut GuiHandler, second_level: bool) -> Result<()>;
}

View file

@ -2,7 +2,6 @@ use crate::prelude::*;
use anyhow::{Result, anyhow};
use assetpath::AssetPath;
use ecs::World;
use serde::{Deserialize, Serialize};
use utilities::{impl_reprc, prelude::*};
use vulkan_rs::{prelude::*, render_target::sub_pass::InputAttachmentInfo};
@ -244,7 +243,7 @@ pub struct GuiHandler {
text_sample_count: VkSampleCountFlags,
callback_list: Vec<Box<dyn FnOnce(&mut World) -> Result<()> + Send + Sync>>,
callback_list: Vec<Box<dyn FnOnce(&mut Self) -> Result<()> + Send + Sync>>,
}
impl GuiHandler {
@ -727,13 +726,9 @@ impl GuiHandler {
Ok(false)
}
pub fn accept_custom_selection(
&self,
world: &mut World,
button: ControllerButton,
) -> Result<bool> {
pub fn accept_custom_selection(&self, button: ControllerButton) -> Result<bool> {
if let Some(current_selectable) = &self.current_selectable {
if current_selectable.custom_click_event(world, button)? {
if current_selectable.custom_click_event(button)? {
return Ok(true);
}
}
@ -741,36 +736,36 @@ impl GuiHandler {
Ok(false)
}
pub fn decline_topgui(&mut self, world: &mut World) -> Result<bool> {
pub fn decline_topgui(&mut self) -> Result<bool> {
// workaround for unwanted borrowing behaviour inside decline function
let opt_topgui = self.top_ui.as_ref().cloned();
if let Some(topgui) = opt_topgui {
topgui.decline(world)?;
topgui.decline(self)?;
return Ok(true);
}
Ok(false)
}
pub fn next_tab_topgui(&mut self, world: &mut World, second_level: bool) -> Result<bool> {
pub fn next_tab_topgui(&mut self, second_level: bool) -> Result<bool> {
// workaround for unwanted borrowing behaviour inside decline function
let opt_topgui = self.top_ui.as_ref().cloned();
if let Some(topgui) = opt_topgui {
topgui.next_tab(world, second_level)?;
topgui.next_tab(self, second_level)?;
return Ok(true);
}
Ok(false)
}
pub fn previous_tab_topgui(&mut self, world: &mut World, second_level: bool) -> Result<bool> {
pub fn previous_tab_topgui(&mut self, second_level: bool) -> Result<bool> {
// workaround for unwanted borrowing behaviour inside decline function
let opt_topgui = self.top_ui.as_ref().cloned();
if let Some(topgui) = opt_topgui {
topgui.previous_tab(world, second_level)?;
topgui.previous_tab(self, second_level)?;
return Ok(true);
}
@ -865,19 +860,19 @@ impl GuiHandler {
self.tooltip_ui = tooltip;
}
pub(crate) fn add_callback<F: FnOnce(&mut World) -> Result<()> + Send + Sync + 'static>(
pub(crate) fn add_callback<F: FnOnce(&mut Self) -> Result<()> + Send + Sync + 'static>(
&mut self,
f: F,
) {
self.callback_list.push(Box::new(f));
}
pub fn process_callbacks(&mut self, world: &mut World) -> Result<()> {
pub fn process_callbacks(&mut self) -> Result<()> {
let callbacks = mem::take(&mut self.callback_list);
callbacks
.into_iter()
.try_for_each(|callback| callback(world))
.try_for_each(|callback| callback(self))
}
fn render(

View file

@ -1,6 +1,5 @@
use crate::prelude::*;
use anyhow::Result;
use ecs::World;
use std::any::Any;
use std::collections::HashMap;
@ -26,9 +25,8 @@ pub struct Keyboard {
mode: Arc<RwLock<KeyboardMode>>,
decline_callback: Arc<RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>>,
accept_callback:
Arc<RwLock<Option<Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>>>>,
decline_callback: Arc<RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>>,
accept_callback: Arc<RwLock<Option<Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>>>>,
elements: HashMap<String, UiElement>,
}
@ -41,11 +39,11 @@ impl Keyboard {
let text_field: Arc<TextField> = text_field_gui.element("field")?;
let decline_callback: Arc<
RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
> = Arc::new(RwLock::new(None));
let accept_callback: Arc<
RwLock<Option<Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>>>,
RwLock<Option<Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>>>,
> = Arc::new(RwLock::new(None));
let mode = Arc::new(RwLock::new(KeyboardMode::UpperCase));
@ -86,10 +84,10 @@ impl Keyboard {
gui_handler: &mut GuiHandler,
textfield: Arc<TextField>,
mode: &Arc<RwLock<KeyboardMode>>,
decline_callback: Arc<RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>>,
accept_callback: Arc<
RwLock<Option<Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>>>,
decline_callback: Arc<
RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
>,
accept_callback: Arc<RwLock<Option<Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>>>>,
) -> Result<(Arc<GuiBuilder>, Arc<GuiBuilder>, Arc<GuiBuilder>)> {
let lower_case = GuiBuilder::from_str(gui_handler, include_str!("lower_case.xml"))?;
let upper_case = GuiBuilder::from_str(gui_handler, include_str!("upper_case.xml"))?;
@ -195,9 +193,9 @@ impl Keyboard {
Self::set_text_callback(&specials, ".", textfield.clone())?;
Self::set_text_callback(&specials, "_", textfield.clone())?;
let back = Box::new(move |world: &mut World| {
let back = Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(callback) = decline_callback.read().unwrap().as_ref() {
(callback)(world)?;
(callback)(gui_handler)?;
}
Ok(())
@ -207,12 +205,12 @@ impl Keyboard {
let weak_textfield = Arc::downgrade(&textfield);
let weak_accept = Arc::downgrade(&accept_callback);
Box::new(move |world: &mut World| {
Box::new(move |_: &mut GuiHandler| {
if let Some(textfield) = weak_textfield.upgrade() {
if let Some(accept_callback) = weak_accept.upgrade() {
if let Some(text) = textfield.text() {
if let Some(callback) = accept_callback.read().unwrap().as_ref() {
(callback)(world, &text)?;
(callback)(&text)?;
}
}
}
@ -227,16 +225,13 @@ impl Keyboard {
let weak_lower = Arc::downgrade(&lower_case);
let weak_upper = Arc::downgrade(&upper_case);
Box::new(move |world: &mut World| {
Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(lower) = weak_lower.upgrade() {
if let Some(upper) = weak_upper.upgrade() {
let mut mode = mode.write().unwrap();
if let KeyboardMode::LowerCase = mode.deref() {
*mode = KeyboardMode::UpperCase;
let gui_handler = world.resources.get_mut::<GuiHandler>();
lower.disable(gui_handler)?;
upper.enable(gui_handler)?;
}
@ -252,16 +247,13 @@ impl Keyboard {
let weak_upper = Arc::downgrade(&upper_case);
let weak_specials = Arc::downgrade(&specials);
Box::new(move |world: &mut World| {
Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(specials) = weak_specials.upgrade() {
if let Some(upper) = weak_upper.upgrade() {
let mut mode = mode.write().unwrap();
if let KeyboardMode::UpperCase = mode.deref() {
*mode = KeyboardMode::Specials;
let gui_handler = world.resources.get_mut::<GuiHandler>();
upper.disable(gui_handler)?;
specials.enable(gui_handler)?;
}
@ -277,16 +269,13 @@ impl Keyboard {
let weak_lower = Arc::downgrade(&lower_case);
let weak_specials = Arc::downgrade(&specials);
Box::new(move |world: &mut World| {
Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(lower) = weak_lower.upgrade() {
if let Some(specials) = weak_specials.upgrade() {
let mut mode = mode.write().unwrap();
if let KeyboardMode::Specials = mode.deref() {
*mode = KeyboardMode::LowerCase;
let gui_handler = world.resources.get_mut::<GuiHandler>();
specials.disable(gui_handler)?;
lower.enable(gui_handler)?;
}
@ -300,9 +289,8 @@ impl Keyboard {
let space_bar = {
let weak_textfield = Arc::downgrade(&textfield);
Box::new(move |world: &mut World| {
Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(text_field) = weak_textfield.upgrade() {
let gui_handler = world.resources.get_mut::<GuiHandler>();
text_field.add_letter(gui_handler, ' ')?;
}
@ -342,11 +330,10 @@ impl Keyboard {
let weak_textfield = Arc::downgrade(&textfield);
let weak_button = Arc::downgrade(&button_ref);
button_ref.set_callback(Box::new(move |world: &mut World| {
button_ref.set_callback(Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(textfield) = weak_textfield.upgrade() {
if let Some(button) = weak_button.upgrade() {
if let Some(text) = button.text()? {
let gui_handler = world.resources.get_mut::<GuiHandler>();
textfield.add_letter(gui_handler, text.as_bytes()[0] as char)?;
}
}
@ -360,22 +347,21 @@ impl Keyboard {
}
impl TopGui for Keyboard {
fn decline(&self, world: &mut World) -> Result<()> {
fn decline(&self, gui_handler: &mut GuiHandler) -> Result<()> {
if let Some(callback) = self.decline_callback.read().unwrap().as_ref() {
(callback)(world)?;
(callback)(gui_handler)?;
}
Ok(())
}
fn next_tab(&self, _world: &mut World, _: bool) -> Result<()> {
fn next_tab(&self, _gui_handler: &mut GuiHandler, _: bool) -> Result<()> {
Ok(())
}
fn previous_tab(&self, world: &mut World, second_level: bool) -> Result<()> {
fn previous_tab(&self, gui_handler: &mut GuiHandler, second_level: bool) -> Result<()> {
// abuse event
if !second_level {
let gui_handler = world.resources.get_mut::<GuiHandler>();
self.text_field.remove_last(gui_handler)?;
}
@ -463,22 +449,21 @@ impl TopLevelGui for Keyboard {
impl Functionality for Keyboard {
fn set_click_callbacks(
&self,
callbacks: Vec<(&str, Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>)>,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
) -> Result<()> {
if let Some((_, callback)) = callbacks.into_iter().find(|(name, _)| *name == "decline") {
*self.decline_callback.write().unwrap() = Some(callback);
for (name, callback) in callbacks {
if name == "decline" {
*self.decline_callback.write().unwrap() = Some(callback);
}
}
Ok(())
}
fn set_select_callbacks(
&self,
_: Vec<(
&str,
Box<dyn Fn(&mut World, bool) -> Result<()> + Send + Sync>,
)>,
) -> Result<()> {
fn set_select_callbacks(&self, _: Vec<(&str, Box<CustomCallback<bool, ()>>)>) -> Result<()> {
Ok(())
}
@ -486,7 +471,7 @@ impl Functionality for Keyboard {
&self,
_: Vec<(
&str,
Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>,
Box<dyn Fn(ControllerButton) -> Result<bool> + Send + Sync>,
)>,
) -> Result<()> {
Ok(())
@ -494,10 +479,7 @@ impl Functionality for Keyboard {
fn set_vec_callbacks(
&self,
callbacks: Vec<(
&str,
Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>,
)>,
callbacks: Vec<(&str, Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>)>,
) -> Result<()> {
for (name, callback) in callbacks {
if name == "accept" {

View file

@ -13,3 +13,5 @@ mod element_creator;
mod gui_direction;
mod mouse_button;
pub mod prelude;
pub type CustomCallback<I, O> = dyn Fn(I) -> anyhow::Result<O> + Send + Sync;

View file

@ -9,3 +9,5 @@ pub use super::keyboard::Keyboard;
pub use super::mouse_button::MouseButton;
pub use super::states::*;
pub use super::tab_control::TabControl;
pub use super::CustomCallback;

View file

@ -1,20 +1,18 @@
use crate::prelude::*;
use anyhow::Result;
use assetpath::AssetPath;
use ecs::World;
use utilities::prelude::remove_life_time_mut;
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex, RwLock, Weak};
pub trait FutureStateChange: Fn(&mut World) -> Result<()> + Send + Sync {
pub trait FutureStateChange: Fn(&mut GuiHandler) -> Result<()> + Send + Sync {
fn clone_box<'a>(&self) -> Box<dyn 'a + FutureStateChange>
where
Self: 'a;
fn as_fn(&self) -> &(dyn Fn(&mut World) -> Result<()> + Send + Sync)
fn as_fn(&self) -> &(dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync)
where
Self: Sized,
{
@ -23,7 +21,7 @@ pub trait FutureStateChange: Fn(&mut World) -> Result<()> + Send + Sync {
fn as_static(
&'static self,
) -> &'static (dyn Fn(&mut World) -> Result<()> + Send + Sync + 'static)
) -> &'static (dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync + 'static)
where
Self: Sized,
{
@ -31,7 +29,7 @@ pub trait FutureStateChange: Fn(&mut World) -> Result<()> + Send + Sync {
}
}
impl<F: Fn(&mut World) -> Result<()> + Clone + Send + Sync> FutureStateChange for F {
impl<F: Fn(&mut GuiHandler) -> Result<()> + Clone + Send + Sync> FutureStateChange for F {
fn clone_box<'a>(&self) -> Box<dyn 'a + FutureStateChange>
where
Self: 'a,
@ -51,12 +49,12 @@ struct State {
top_level_gui: Arc<dyn TopLevelGui>,
on_activate: RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
on_deactivate: RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
on_activate: RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
on_deactivate: RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
next_tab: RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
previous_tab: RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
decline: RwLock<Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>>,
next_tab: RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
previous_tab: RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
decline: RwLock<Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>>,
}
/// Opaque handle for a State
@ -152,46 +150,36 @@ impl GetElement<ProgressBar> for StateHandle {
/// Update type
pub enum StateUpdateType<'a> {
/// Updates the callback which is executed on next tab event
NextTab(Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>),
NextTab(Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>),
/// Updates the callback which is executed on previous tab event
PreviousTab(Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>),
PreviousTab(Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>),
/// Updates the callback which is executed on decline event
Decline(Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>),
Decline(Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>),
/// Updates callbacks by identifier
ClickCallbacks(Vec<(&'a str, Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>)>),
/// Updates callbacks by identifier
SelectCallbacks(
ClickCallbacks(
Vec<(
&'a str,
Box<dyn Fn(&mut World, bool) -> Result<()> + Send + Sync>,
Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>,
)>,
),
/// Updates callbacks by identifier
CustomClickCallbacks(
Vec<(
&'a str,
Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>,
)>,
),
SelectCallbacks(Vec<(&'a str, Box<CustomCallback<bool, ()>>)>),
/// Updates callbacks by identifier
CustomClickCallbacks(Vec<(&'a str, Box<CustomCallback<ControllerButton, bool>>)>),
/// Updates callbacks by identifier with input parameters
VecCallbacks(
Vec<(
&'a str,
Box<dyn Fn(&mut World, &dyn Any) -> Result<()> + Send + Sync>,
)>,
),
VecCallbacks(Vec<(&'a str, Box<dyn Fn(&dyn Any) -> Result<()> + Send + Sync>)>),
/// Updates the callback which is executed when this state gets activated on state change
OnActivate(Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>),
OnActivate(Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>),
/// Updates the callback which is executed when this state gets deactivated on state change
OnDeactivate(Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>),
OnDeactivate(Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>),
}
/// Type of the state to be created
@ -286,13 +274,14 @@ impl States {
/// # Arguments
///
/// * `id` - Set state with the given identifier or None
pub fn set_state<'b>(&self, world: &mut World, id: impl Into<Option<&'b str>>) -> Result<()> {
let gui_handler = unsafe { remove_life_time_mut(world.resources.get_mut::<GuiHandler>()) };
pub fn set_state<'b>(
&self,
gui_handler: &mut GuiHandler,
id: impl Into<Option<&'b str>>,
) -> Result<()> {
Self::_set_state(
id.into().map(|id| self.get_state(id)).transpose()?,
&mut *self.current_state.lock().unwrap(),
world,
gui_handler,
self.log_state_change,
)
@ -301,7 +290,6 @@ impl States {
fn _set_state(
state: Option<Arc<State>>,
current: &mut Option<Arc<State>>,
world: &mut World,
gui_handler: &mut GuiHandler,
logging: bool,
) -> Result<()> {
@ -314,13 +302,13 @@ impl States {
}
// execute deactivate on old state
old_state.deactivate(world, gui_handler)?;
old_state.deactivate(gui_handler)?;
}
// set new state, either no state or requested state
match state {
Some(state) => {
state.activate(world, gui_handler)?;
state.activate(gui_handler)?;
gui_handler.set_top_gui(Some(state.clone()));
if logging {
@ -366,15 +354,11 @@ impl States {
let weak_current_state = Arc::downgrade(&self.current_state);
let logging = self.log_state_change;
Ok(Box::new(move |world: &mut World| {
Ok(Box::new(move |gui_handler: &mut GuiHandler| {
if let Some(current) = weak_current_state.upgrade() {
let gui_handler =
unsafe { remove_life_time_mut(world.resources.get_mut::<GuiHandler>()) };
Self::_set_state(
weak_state.as_ref().map(|w| w.upgrade()).flatten(),
&mut *current.lock().unwrap(),
world,
gui_handler,
logging,
)?;
@ -445,21 +429,21 @@ impl State {
}
}
fn activate(&self, world: &mut World, gui_handler: &mut GuiHandler) -> Result<()> {
fn activate(&self, gui_handler: &mut GuiHandler) -> Result<()> {
self.top_level_gui.enable(gui_handler)?;
if let Some(activate) = self.on_activate.read().unwrap().as_ref() {
(activate)(world)?;
(activate)(gui_handler)?;
}
Ok(())
}
fn deactivate(&self, world: &mut World, gui_handler: &mut GuiHandler) -> Result<()> {
fn deactivate(&self, gui_handler: &mut GuiHandler) -> Result<()> {
self.top_level_gui.disable(gui_handler)?;
if let Some(deactivate) = self.on_deactivate.read().unwrap().as_ref() {
(deactivate)(world)?;
(deactivate)(gui_handler)?;
}
Ok(())
@ -467,43 +451,49 @@ impl State {
fn set_on_activate(
&self,
on_activate: Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>,
on_activate: Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>,
) {
*self.on_activate.write().unwrap() = on_activate;
}
fn set_on_deactivate(
&self,
on_deactivate: Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>,
on_deactivate: Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>,
) {
*self.on_deactivate.write().unwrap() = on_deactivate;
}
fn set_previous_tab(
&self,
previous_tab: Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>,
previous_tab: Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>,
) {
*self.previous_tab.write().unwrap() = previous_tab;
}
fn set_next_tab(&self, next_tab: Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>) {
fn set_next_tab(
&self,
next_tab: Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>,
) {
*self.next_tab.write().unwrap() = next_tab;
}
fn set_decline(&self, decline: Option<Box<dyn Fn(&mut World) -> Result<()> + Send + Sync>>) {
fn set_decline(
&self,
decline: Option<Box<dyn Fn(&mut GuiHandler) -> Result<()> + Send + Sync>>,
) {
*self.decline.write().unwrap() = decline;
}
}
impl TopGui for State {
fn decline(&self, world: &mut World) -> Result<()> {
fn decline(&self, gui_handler: &mut GuiHandler) -> Result<()> {
match self.decline.read().unwrap().as_ref() {
Some(decline) => {
(decline)(world)?;
(decline)(gui_handler)?;
}
None => {
if let Some(top_gui) = self.top_level_gui.top_gui() {
top_gui.decline(world)?;
top_gui.decline(gui_handler)?;
}
}
}
@ -511,14 +501,14 @@ impl TopGui for State {
Ok(())
}
fn next_tab(&self, world: &mut World, second_level: bool) -> Result<()> {
fn next_tab(&self, gui_handler: &mut GuiHandler, second_level: bool) -> Result<()> {
match self.next_tab.read().unwrap().as_ref() {
Some(next_tab) => {
(next_tab)(world)?;
(next_tab)(gui_handler)?;
}
None => {
if let Some(top_gui) = self.top_level_gui.top_gui() {
top_gui.next_tab(world, second_level)?;
top_gui.next_tab(gui_handler, second_level)?;
}
}
}
@ -526,14 +516,14 @@ impl TopGui for State {
Ok(())
}
fn previous_tab(&self, world: &mut World, second_level: bool) -> Result<()> {
fn previous_tab(&self, gui_handler: &mut GuiHandler, second_level: bool) -> Result<()> {
match self.previous_tab.read().unwrap().as_ref() {
Some(previous_tab) => {
(previous_tab)(world)?;
(previous_tab)(gui_handler)?;
}
None => {
if let Some(top_gui) = self.top_level_gui.top_gui() {
top_gui.previous_tab(world, second_level)?;
top_gui.previous_tab(gui_handler, second_level)?;
}
}
}