Start removing interior mutability of GuiHandler

This commit is contained in:
Michael Hübner 2025-03-04 09:11:05 +01:00
parent 6d19f9bceb
commit 0976860b9f
12 changed files with 539 additions and 571 deletions

View file

@ -8,11 +8,13 @@ edition = "2024"
quick-xml = "0.31.0"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = { version = "1.0.120" }
paste = "1.0.15"
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" }
paste = "1.0.15"
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
anyhow = { version = "1.0.86", features = ["backtrace"] }
ecs = { git = "https://gavania.de/hodasemi/engine.git" }
# optional
audio = { git = "https://gavania.de/hodasemi/audio.git", optional = true }

View file

@ -4,13 +4,14 @@ use anyhow::Result;
use super::executable::Executable;
use super::framable::Framable;
use crate::prelude::*;
#[cfg(feature = "audio")]
use super::audible::Audible;
use std::sync::{
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
Arc, RwLock,
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
};
/// `Clickable` gives the ability to execute a closure when clicked
@ -54,12 +55,8 @@ impl Clickable {
/// # Arguments
///
/// * `clickable` is a `&Arc<Clickable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_clickable(self.ui_layer.load(SeqCst), self.clone())?;
Ok(())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_clickable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory
@ -67,11 +64,9 @@ impl Clickable {
/// # Arguments
///
/// * `clickable` is a `&Arc<Clickable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_clickable(self.ui_layer.load(SeqCst), self)?;
self.set_clicked(false)?;
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_clickable(self.ui_layer.load(SeqCst), self)?;
self.set_clicked(gui_handler, false)?;
Ok(())
}
@ -104,7 +99,7 @@ impl Clickable {
*self.audible.write().unwrap() = audible;
}
pub fn set_clicked(&self, clicked: bool) -> Result<bool> {
pub fn set_clicked(&self, gui_handler: &mut GuiHandler<'_>, clicked: bool) -> Result<bool> {
if self.clicked() != clicked {
self.clicked.store(clicked, SeqCst);
@ -122,7 +117,7 @@ impl Clickable {
}
}
self.executable.execute(())?;
self.executable.execute(gui_handler, ())?;
}
Ok(true)

View file

@ -2,6 +2,7 @@
use crate::prelude::*;
use anyhow::Result;
use utilities::{impl_reprc, prelude::*};
use vulkan_rs::prelude::*;
@ -33,17 +34,18 @@ pub struct Colorable {
impl Colorable {
/// Factory method for `Colorable`, returns `Arc<Colorable>`.
pub fn new(
gui_handler: &mut GuiHandler<'_>,
framable: Arc<Framable>,
color: Color,
fill_type: DisplayableFillType,
) -> Result<Arc<Self>> {
let set = framable.gui_handler().color_descriptor(color)?;
let set = gui_handler.color_descriptor(color)?;
let buffer = Buffer::builder()
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly)
.set_size(6)
.build(framable.gui_handler().device().clone())?;
.build(gui_handler.device().clone())?;
let colorable = Arc::new(Colorable {
framable,
@ -67,7 +69,7 @@ impl Colorable {
colorable.framable.add_callback(
weak_colorable,
Box::new(move || colorable_clone.update_frame()),
Box::new(move |gui_handler| colorable_clone.update_frame(gui_handler)),
);
Ok(colorable)
@ -78,10 +80,8 @@ impl Colorable {
/// # Arguments
///
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_colorable(self.ui_layer.load(SeqCst), self.clone())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_colorable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
@ -89,10 +89,8 @@ impl Colorable {
/// # Arguments
///
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_colorable(self.ui_layer.load(SeqCst), self)
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_colorable(self.ui_layer.load(SeqCst), self)
}
pub fn clear_callback(self: &Arc<Self>) {
@ -109,8 +107,8 @@ impl Colorable {
/// # Arguments
///
/// * `color` defines the color
pub fn set_color(&self, color: Color) -> Result<()> {
let set = self.framable.gui_handler().color_descriptor(color)?;
pub fn set_color(&self, color: Color, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
let set = gui_handler.color_descriptor(color)?;
*self.color.write().unwrap() = color;
*self.descriptor_set.write().unwrap() = set;
@ -149,7 +147,7 @@ impl Colorable {
}
/// Update frame method if the original frame is invalidated
pub fn update_frame(&self) -> Result<()> {
pub fn update_frame(&self, gui_handler: &GuiHandler<'_>) -> Result<()> {
let mut frame = self.buffer.map_complete()?;
let mut x_start = self.framable.left() as f32;
@ -177,12 +175,12 @@ impl Colorable {
let top = y_start + height * *self.top_factor.read().unwrap();
let bottom = y_start + height * *self.bottom_factor.read().unwrap();
frame[0].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[1].position = (self.framable.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
frame[2].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[3].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[4].position = (self.framable.ortho() * vec4(left, top, 0.0, 1.0)).xy();
frame[5].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[0].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[1].position = (gui_handler.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
frame[2].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[3].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[4].position = (gui_handler.ortho() * vec4(left, top, 0.0, 1.0)).xy();
frame[5].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
Ok(())
}

View file

@ -71,18 +71,17 @@ impl Displayable {
/// * `framable` is a `Arc<Framable>` instance
/// * `name` is the name for a png
pub fn new(
gui_handler: &mut GuiHandler<'_>,
framable: Arc<Framable>,
displayable_type: impl Into<DisplayableType>,
fill_type: DisplayableFillType,
) -> Result<Arc<Self>> {
let descriptor_set = framable.gui_handler().image_descriptor_set()?;
let descriptor_set = gui_handler.image_descriptor_set()?;
let displayable_type = displayable_type.into();
if let DisplayableType::Path(path) = &displayable_type {
let texture = framable
.gui_handler()
.displayable_image_from_path(path.clone())?;
let texture = gui_handler.displayable_image_from_path(path.clone())?;
descriptor_set.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
}
@ -90,7 +89,7 @@ impl Displayable {
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.set_memory_usage(MemoryUsage::CpuOnly)
.set_size(6)
.build(framable.gui_handler().device().clone())?;
.build(gui_handler.device().clone())?;
let displayable = Arc::new(Displayable {
framable,
@ -118,7 +117,7 @@ impl Displayable {
displayable.framable.add_callback(
weak_displayable,
Box::new(move || displayable_clone.update_frame()),
Box::new(move |gui_handler| displayable_clone.update_frame(gui_handler)),
);
Ok(displayable)
@ -129,10 +128,8 @@ impl Displayable {
/// # Arguments
///
/// * `displayable` is a `&Arc<Displayable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_displayable(self.ui_layer.load(SeqCst), self.clone())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_displayable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory
@ -140,10 +137,8 @@ impl Displayable {
/// # Arguments
///
/// * `displayable` is a `&Arc<Displayable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_displayable(self.ui_layer.load(SeqCst), self)
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_displayable(self.ui_layer.load(SeqCst), self)
}
pub fn inner_type(&self) -> DisplayableType {
@ -164,25 +159,21 @@ impl Displayable {
/// # Arguments
///
/// * `name` is the name of the texture in `gui/` without `.png` suffix
pub fn set_image(&self, displayable_type: impl Into<DisplayableType>) -> Result<()> {
pub fn set_image(
&self,
gui_handler: &mut GuiHandler<'_>,
displayable_type: impl Into<DisplayableType>,
) -> Result<()> {
let displayable_type = displayable_type.into();
let texture = match displayable_type.clone() {
DisplayableType::Path(path) => Some(
self.framable
.gui_handler()
.displayable_image_from_path(path)?,
),
DisplayableType::Path(path) => Some(gui_handler.displayable_image_from_path(path)?),
DisplayableType::Descriptor(descriptor) => {
let width = (self.framable.right() - self.framable.left()) as u32;
let height = (self.framable.bottom() - self.framable.top()) as u32;
if width > 0 && height > 0 {
Some(
self.framable
.gui_handler()
.displayable_image_from_descriptor(width, height, descriptor)?,
)
Some(gui_handler.displayable_image_from_descriptor(width, height, descriptor)?)
} else {
None
}
@ -242,7 +233,7 @@ impl Displayable {
}
/// Update frame method if the original frame is invalidated
pub fn update_frame(&self) -> Result<()> {
pub fn update_frame(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
let mut frame = self.buffer.map_complete()?;
let mut x_start = self.framable.left() as f32;
@ -267,14 +258,11 @@ impl Displayable {
if let DisplayableType::Descriptor(descriptor) = &*self.displayable_type.read().unwrap() {
if width > 0.0 && height > 0.0 {
let texture = self
.framable
.gui_handler()
.displayable_image_from_descriptor(
width as u32,
height as u32,
descriptor.clone(),
)?;
let texture = gui_handler.displayable_image_from_descriptor(
width as u32,
height as u32,
descriptor.clone(),
)?;
self.descriptor_set
.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
@ -286,12 +274,12 @@ impl Displayable {
let top = y_start + height * *self.top_factor.read().unwrap();
let bottom = y_start + height * *self.bottom_factor.read().unwrap();
frame[0].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[1].position = (self.framable.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
frame[2].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[3].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[4].position = (self.framable.ortho() * vec4(left, top, 0.0, 1.0)).xy();
frame[5].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[0].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[1].position = (gui_handler.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
frame[2].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[3].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
frame[4].position = (gui_handler.ortho() * vec4(left, top, 0.0, 1.0)).xy();
frame[5].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
frame[0].texture_coordinates = vec2(
*self.left_uv_factor.read().unwrap(),

View file

@ -8,15 +8,13 @@ use crate::prelude::*;
/// `Executable` holds a closure which can be executed
pub struct Executable<I: Send + Sync + 'static> {
gui_handler: Arc<GuiHandler>,
callback: RwLock<Option<Arc<dyn Fn(I) -> Result<()> + Send + Sync>>>,
}
impl<I: Send + Sync + 'static> Executable<I> {
/// Factory method for `Executable`, returns `Arc<Executable>`
pub fn new(gui_handler: &Arc<GuiHandler>) -> Arc<Self> {
pub fn new() -> Arc<Self> {
Arc::new(Executable {
gui_handler: gui_handler.clone(),
callback: RwLock::new(None),
})
}
@ -39,11 +37,11 @@ impl<I: Send + Sync + 'static> Executable<I> {
}
/// Execute the callback closure if possible
pub fn execute(&self, input: I) -> Result<()> {
pub fn execute(&self, gui_handler: &mut GuiHandler<'_>, input: I) -> Result<()> {
if let Some(callback) = self.callback.read().unwrap().as_ref() {
let callback = callback.clone();
self.gui_handler.add_callback(move || (callback)(input));
gui_handler.add_callback(move || (callback)(input));
}
Ok(())

View file

@ -6,13 +6,11 @@ use anyhow::Result;
use std::{
ffi::c_void,
sync::{
atomic::{AtomicBool, AtomicI32, AtomicU32, Ordering::SeqCst},
Arc, RwLock, Weak,
atomic::{AtomicBool, AtomicI32, AtomicU32, Ordering::SeqCst},
},
};
use vulkan_rs::prelude::cgmath::Matrix4;
/// Describes the vertical alignment for a `Framable`
#[derive(Copy, Clone, PartialEq)]
pub enum VerticalAlign {
@ -77,8 +75,6 @@ impl Drop for Handle {
/// `Framable` keeps track of the position and size of an item
/// and calls functions on resize to keep everything aligned correctly
pub struct Framable {
gui_handler: Arc<GuiHandler>,
left: AtomicI32,
right: AtomicI32,
top: AtomicI32,
@ -87,7 +83,12 @@ pub struct Framable {
vertical_alignment: RwLock<VerticalAlign>,
horizontal_alignment: RwLock<HorizontalAlign>,
resize_callbacks: RwLock<Vec<(Handle, Box<dyn Fn() -> Result<()> + Send + Sync>)>>,
resize_callbacks: RwLock<
Vec<(
Handle,
Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>,
)>,
>,
x_off: AtomicI32,
y_off: AtomicI32,
@ -111,12 +112,10 @@ pub struct Framable {
impl Framable {
/// Factory method for `Framable`, returns `Arc<Framable>`
pub fn new(gui_handler: Arc<GuiHandler>, resize_allowed: bool) -> Result<Arc<Self>> {
pub fn new(window_width: u32, window_height: u32, resize_allowed: bool) -> Result<Arc<Self>> {
Ok(Arc::new(Framable {
window_width: AtomicU32::new(gui_handler.width()),
window_height: AtomicU32::new(gui_handler.height()),
gui_handler,
window_width: AtomicU32::new(window_width),
window_height: AtomicU32::new(window_height),
left: AtomicI32::new(0),
right: AtomicI32::new(0),
@ -150,22 +149,21 @@ impl Framable {
/// # Arguments
///
/// * `framable` - is a `&Arc<Framable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
// check if window size is the same as last time
if self.gui_handler.width() != self.window_width.load(SeqCst)
|| self.gui_handler.height() != self.window_height.load(SeqCst)
if gui_handler.width() != self.window_width.load(SeqCst)
|| gui_handler.height() != self.window_height.load(SeqCst)
{
// update window size
self.window_width.store(self.gui_handler.width(), SeqCst);
self.window_height.store(self.gui_handler.height(), SeqCst);
self.window_width.store(gui_handler.width(), SeqCst);
self.window_height.store(gui_handler.height(), SeqCst);
// force resize
self.resize()?;
self.resize(gui_handler)?;
}
if self.resize_allowed() {
self.gui_handler
.add_framable(self.ui_layer.load(SeqCst), self.clone())?;
gui_handler.add_framable(self.ui_layer.load(SeqCst), self.clone())?;
}
Ok(())
@ -176,10 +174,9 @@ impl Framable {
/// # Arguments
///
/// * `framable` - is a `&Arc<Framable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
if self.resize_allowed() {
self.gui_handler
.delete_framable(self.ui_layer.load(SeqCst), self)?;
gui_handler.delete_framable(self.ui_layer.load(SeqCst), self)?;
}
Ok(())
@ -193,36 +190,49 @@ impl Framable {
self.ui_layer.load(SeqCst)
}
pub(crate) fn set_reference_size(&self, width: u32, height: u32) -> Result<()> {
pub(crate) fn set_reference_size(
&self,
gui_handler: &mut GuiHandler<'_>,
width: u32,
height: u32,
) -> Result<()> {
*self.reference_size.write().unwrap() = Some((width, height));
self.reference_scale_position.store(true, SeqCst);
self.reference_scale_size.store(true, SeqCst);
if self.is_framed() {
self.resize()?;
self.resize(gui_handler)?;
}
Ok(())
}
pub(crate) fn allow_position_scale(&self, allowed: bool) -> Result<()> {
pub(crate) fn allow_position_scale(
&self,
gui_handler: &mut GuiHandler<'_>,
allowed: bool,
) -> Result<()> {
if allowed != self.reference_scale_position.load(SeqCst) {
self.reference_scale_position.store(allowed, SeqCst);
if self.is_framed() {
self.resize()?;
self.resize(gui_handler)?;
}
}
Ok(())
}
pub(crate) fn allow_size_scale(&self, allowed: bool) -> Result<()> {
pub(crate) fn allow_size_scale(
&self,
gui_handler: &mut GuiHandler<'_>,
allowed: bool,
) -> Result<()> {
if allowed != self.reference_scale_size.load(SeqCst) {
self.reference_scale_size.store(allowed, SeqCst);
if self.is_framed() {
self.resize()?;
self.resize(gui_handler)?;
}
}
@ -237,6 +247,7 @@ impl Framable {
/// width and a certain alignment
pub fn set_frame(
&self,
gui_handler: &GuiHandler<'_>,
x_off: i32,
y_off: i32,
w: u32,
@ -252,7 +263,7 @@ impl Framable {
*self.vertical_alignment.write().unwrap() = vertical_align;
*self.horizontal_alignment.write().unwrap() = horizontal_align;
self.calculate_frame();
self.calculate_frame(gui_handler);
self.framed.store(true, SeqCst);
}
@ -296,16 +307,11 @@ impl Framable {
self.framed.load(SeqCst)
}
/// Returns the ortho 4x4 matrix, which describes the window
pub fn ortho(&self) -> Matrix4<f32> {
self.gui_handler.ortho()
}
/// Adds a callback closure which is executed on resize
pub fn add_callback(
&self,
handle: impl Into<Handle>,
callback: Box<dyn Fn() -> Result<()> + Send + Sync>,
callback: Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>,
) {
let handle = handle.into();
@ -348,9 +354,9 @@ impl Framable {
*self.horizontal_alignment.read().unwrap()
}
fn calculate_frame(&self) {
let width = self.gui_handler.width();
let height = self.gui_handler.height();
fn calculate_frame(&self, gui_handler: &GuiHandler<'_>) {
let width = gui_handler.width();
let height = gui_handler.height();
let y_align = match *self.vertical_alignment.read().unwrap() {
VerticalAlign::Top => 0,
@ -420,17 +426,27 @@ impl Framable {
self.bottom.store(bottom, SeqCst);
}
pub fn change_position(&self, x_offset: i32, y_offset: i32) -> Result<()> {
pub fn change_position(
&self,
gui_handler: &mut GuiHandler<'_>,
x_offset: i32,
y_offset: i32,
) -> Result<()> {
assert!(self.is_framed(), "framable needs to be framed first!");
self.x_off.store(x_offset, SeqCst);
self.y_off.store(y_offset, SeqCst);
self.resize()?;
self.resize(gui_handler)?;
Ok(())
}
pub fn change_position_unscaled(&self, x: i32, y: i32) -> Result<()> {
pub fn change_position_unscaled(
&self,
gui_handler: &mut GuiHandler<'_>,
x: i32,
y: i32,
) -> Result<()> {
assert!(self.is_framed(), "framable needs to be framed first!");
let left = self.left.load(SeqCst);
@ -447,23 +463,19 @@ impl Framable {
self.bottom.store(y + height, SeqCst);
for (_, callback) in self.resize_callbacks.read().unwrap().iter() {
callback()?;
callback(gui_handler)?;
}
Ok(())
}
pub fn resize(&self) -> Result<()> {
self.calculate_frame();
pub fn resize(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
self.calculate_frame(gui_handler);
for (_, callback) in self.resize_callbacks.read().unwrap().iter() {
callback()?;
callback(gui_handler)?;
}
Ok(())
}
pub(crate) fn gui_handler(&self) -> &Arc<GuiHandler> {
&self.gui_handler
}
}

View file

@ -5,8 +5,8 @@ use crate::prelude::*;
use anyhow::Result;
use std::sync::{
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
Arc,
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
};
#[cfg(feature = "audio")]
@ -56,10 +56,8 @@ impl Hoverable {
/// # Arguments
///
/// * `hoverable` is a `&Arc<Hoverable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_hoverable(self.ui_layer.load(SeqCst), self.clone())?;
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_hoverable(self.ui_layer.load(SeqCst), self.clone())?;
Ok(())
}
@ -69,11 +67,9 @@ impl Hoverable {
/// # Arguments
///
/// * `hoverable` is a `&Arc<Hoverable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_hoverable(self.ui_layer.load(SeqCst), self)?;
self.set_hovered(false)?;
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_hoverable(self.ui_layer.load(SeqCst), self)?;
self.set_hovered(gui_handler, false)?;
Ok(())
}
@ -107,12 +103,13 @@ impl Hoverable {
/// # Arguments
///
/// * `hovered` is the new hovered state
pub fn set_hovered(&self, hovered: bool) -> Result<()> {
pub fn set_hovered(&self, gui_handler: &mut GuiHandler<'_>, hovered: bool) -> Result<()> {
if self.hovered() != hovered {
self.hovered.store(hovered, SeqCst);
self.hover_changed_executable.execute(hovered)?;
self.on_hover_executable.execute(hovered)?;
self.hover_changed_executable
.execute(gui_handler, hovered)?;
self.on_hover_executable.execute(gui_handler, hovered)?;
#[cfg(feature = "audio")]
{

View file

@ -9,8 +9,8 @@ use vulkan_rs::prelude::*;
use super::texturedvertex::TexturedVertex;
use std::sync::{
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
Arc, RwLock,
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
};
#[derive(Clone, Debug)]
@ -85,16 +85,17 @@ impl Iconizable {
/// * `framable` is a `Arc<Framable>` instance
/// * `icon` is a reference to an `Arc<Image>`
pub fn new(
gui_handler: &mut GuiHandler<'_>,
framable: Arc<Framable>,
icon_builder: impl Into<IconBuilderType>,
positioning: impl Into<Option<IconizablePositioning>>,
) -> Result<Arc<Self>> {
let icon = framable.gui_handler().request_icon(icon_builder)?;
let icon = gui_handler.request_icon(icon_builder)?;
let device = framable.gui_handler().device();
let device = gui_handler.device();
let desc_pool = DescriptorPool::builder()
.set_layout(framable.gui_handler().icon_descriptor_layout().clone())
.set_layout(gui_handler.icon_descriptor_layout().clone())
.build(device.clone())?;
let descriptor_set = DescriptorPool::prepare_set(&desc_pool).allocate()?;
@ -125,7 +126,7 @@ impl Iconizable {
iconizable.framable.add_callback(
weak_iconizable,
Box::new(move || iconizable_clone.update_frame()),
Box::new(move |gui_handler| iconizable_clone.update_frame(gui_handler)),
);
Ok(iconizable)
@ -136,10 +137,8 @@ impl Iconizable {
/// # Arguments
///
/// * `iconizable` is a `&Arc<Iconizable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_iconizable(self.ui_layer.load(SeqCst), self.clone())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_iconizable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory
@ -147,10 +146,8 @@ impl Iconizable {
/// # Arguments
///
/// * `iconizable` is a `&Arc<Iconizable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_iconizable(self.ui_layer.load(SeqCst), self)
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_iconizable(self.ui_layer.load(SeqCst), self)
}
pub fn set_ui_layer(&self, ui_layer: i32) {
@ -175,7 +172,7 @@ impl Iconizable {
}
/// Updates the frame
pub fn update_frame(&self) -> Result<()> {
pub fn update_frame(&self, gui_handler: &GuiHandler<'_>) -> Result<()> {
assert!(self.framable.is_framed(), "framable is not framed yet");
// frame parameter
@ -239,7 +236,7 @@ impl Iconizable {
let right = left + resulting_width;
let bottom = top + resulting_height;
let ortho = self.framable.ortho();
let ortho = gui_handler.ortho();
let mut frame = self.buffer.map_complete()?;
@ -270,8 +267,12 @@ impl Iconizable {
/// # Arguments
///
/// * `icon` the new icon
pub fn set_icon(&self, icon_builder: impl Into<IconBuilderType>) -> Result<()> {
let icon = self.framable.gui_handler().request_icon(icon_builder)?;
pub fn set_icon(
&self,
gui_handler: &mut GuiHandler<'_>,
icon_builder: impl Into<IconBuilderType>,
) -> Result<()> {
let icon = gui_handler.request_icon(icon_builder)?;
self.descriptor_set
.update(&[DescriptorWrite::combined_samplers(0, &[&icon])])?;

View file

@ -5,22 +5,20 @@ use crate::prelude::*;
use anyhow::Result;
use std::sync::{
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
Arc, RwLock, Weak,
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
};
/// `Selectable` gives the ability to navigate per button or controller to
/// optionally adjacent neighbour Selectables and to execute a closure
/// when the current Selectable is pressed
pub struct Selectable<'a> {
selected: AtomicBool,
east_neighbour: RwLock<Option<Weak<Selectable>>>,
west_neighbour: RwLock<Option<Weak<Selectable>>>,
north_neighbour: RwLock<Option<Weak<Selectable>>>,
south_neighbour: RwLock<Option<Weak<Selectable>>>,
east_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
west_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
north_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
south_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
#[cfg(feature = "audio")]
select_audible: RwLock<Option<Arc<Audible>>>,
@ -38,10 +36,11 @@ pub struct Selectable<'a> {
selected_changed_executable: Arc<Executable<(&'a mut World, bool)>>,
// exposed externally for event
on_select_executable: Arc<Executable<(&'mut World, bool)>>,
on_select_executable: Arc<Executable<(&'a mut World, 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(&mut World, ControllerButton) -> Result<bool> + Send + Sync>>>,
}
impl<'a> Selectable<'a> {
@ -51,15 +50,12 @@ impl<'a> Selectable<'a> {
///
/// * `executable` is a `Arc<Executable>` instance
pub fn new(
gui_handler: &'a GuiHandler<'a>,
executable: Arc<Executable<()>>,
selected_changed_executable: Arc<Executable<bool>>,
on_select_executable: Arc<Executable<bool>>,
executable: Arc<Executable<&'a mut World>>,
selected_changed_executable: Arc<Executable<(&'a mut World, bool)>>,
on_select_executable: Arc<Executable<(&'a mut World, bool)>>,
isolate: bool,
) -> Arc<Self> {
Arc::new(Selectable {
selected: AtomicBool::new(false),
east_neighbour: RwLock::new(None),
@ -89,11 +85,8 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selectable` is a `&Arc<Selectable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.gui_handler
.add_selectable(self.ui_layer.load(SeqCst), self.clone())?;
Ok(())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_selectable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
@ -101,10 +94,9 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selectable` is a `&Arc<Selectable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.gui_handler
.delete_selectable(self.ui_layer.load(SeqCst), self)?;
self.set_selected(false)?;
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_selectable(self.ui_layer.load(SeqCst), self)?;
self.set_selected(gui_handler, false)?;
Ok(())
}
@ -118,8 +110,8 @@ impl<'a> Selectable<'a> {
/// # Argument
///
/// * `selectable` is a `Arc<Selectable>` instance
pub fn select(self: &Arc<Self>) -> Result<()> {
self.gui_handler.set_selectable(Some(self.clone()))
pub fn select(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.set_selectable(Some(self.clone()))
}
pub fn set_custom_callback<F>(&self, custom_callback: F)
@ -145,12 +137,13 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selected` is the new selected state
pub fn set_selected(&self, selected: bool) -> Result<()> {
pub fn set_selected(&self, gui_handler: &mut GuiHandler<'_>, selected: bool) -> Result<()> {
if self.selected() != selected {
self.selected.store(selected, SeqCst);
self.selected_changed_executable.execute(selected)?;
self.on_select_executable.execute(selected)?;
self.selected_changed_executable
.execute(gui_handler, selected)?;
self.on_select_executable.execute(gui_handler, selected)?;
#[cfg(feature = "audio")]
{
@ -171,7 +164,7 @@ impl<'a> Selectable<'a> {
}
/// Executes the `Executable`'s callback
pub(crate) fn click_event(&self) -> Result<()> {
pub(crate) fn click_event(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
#[cfg(feature = "audio")]
{
if let Some(audible) = self.click_audible.read().unwrap().as_ref() {
@ -179,7 +172,7 @@ impl<'a> Selectable<'a> {
}
}
self.executable.execute(())?;
self.executable.execute(gui_handler, ())?;
Ok(())
}
@ -202,7 +195,7 @@ impl<'a> Selectable<'a> {
}
/// Returns the current east neighbour, if possible
pub fn east_neighbour(&self) -> Option<Arc<Selectable>> {
pub fn east_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
if let Some(weak_neighbour) = self.east_neighbour.read().unwrap().as_ref() {
if let Some(neighbour) = weak_neighbour.upgrade() {
return Some(neighbour);
@ -217,7 +210,7 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selectable` the new east neighbour
pub fn set_east_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
pub fn set_east_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
if self.isolate {
return;
}
@ -231,7 +224,7 @@ impl<'a> Selectable<'a> {
}
/// Returns the current west neighbour, if possible
pub fn west_neighbour(&self) -> Option<Arc<Selectable>> {
pub fn west_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
if let Some(weak_neighbour) = self.west_neighbour.read().unwrap().as_ref() {
if let Some(neighbour) = weak_neighbour.upgrade() {
return Some(neighbour);
@ -246,7 +239,7 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selectable` the new west neighbour
pub fn set_west_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
pub fn set_west_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
if self.isolate {
return;
}
@ -260,7 +253,7 @@ impl<'a> Selectable<'a> {
}
/// Returns the current north neighbour, if possible
pub fn north_neighbour(&self) -> Option<Arc<Selectable>> {
pub fn north_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
if let Some(weak_neighbour) = self.north_neighbour.read().unwrap().as_ref() {
if let Some(neighbour) = weak_neighbour.upgrade() {
return Some(neighbour);
@ -275,7 +268,7 @@ impl<'a> Selectable<'a> {
/// # Argumnents
///
/// * `selectable` the new north neighbour
pub fn set_north_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
pub fn set_north_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
if self.isolate {
return;
}
@ -289,7 +282,7 @@ impl<'a> Selectable<'a> {
}
/// Returns the current south neighbour, if possible
pub fn south_neighbour(&self) -> Option<Arc<Selectable>> {
pub fn south_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
if let Some(weak_neighbour) = self.south_neighbour.read().unwrap().as_ref() {
if let Some(neighbour) = weak_neighbour.upgrade() {
return Some(neighbour);
@ -304,7 +297,7 @@ impl<'a> Selectable<'a> {
/// # Arguments
///
/// * `selectable` the new south neighbour
pub fn set_south_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
pub fn set_south_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
if self.isolate {
return;
}
@ -317,7 +310,7 @@ impl<'a> Selectable<'a> {
}
}
pub fn connect_vertically(upper: &Arc<Selectable>, lower: &Arc<Selectable>) {
pub fn connect_vertically<'c>(upper: &Arc<Selectable<'c>>, lower: &Arc<Selectable<'c>>) {
if upper.isolate || lower.isolate {
return;
}
@ -326,7 +319,7 @@ impl<'a> Selectable<'a> {
*lower.north_neighbour.write().unwrap() = Some(Arc::downgrade(upper));
}
pub fn connect_horizontally(left: &Arc<Selectable>, right: &Arc<Selectable>) {
pub fn connect_horizontally<'c>(left: &Arc<Selectable<'c>>, right: &Arc<Selectable<'c>>) {
if left.isolate || right.isolate {
return;
}

View file

@ -11,8 +11,8 @@ use super::texturedvertex::TexturedVertex;
use std::{
convert::TryFrom,
sync::{
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
Arc, RwLock,
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
},
};
@ -47,7 +47,7 @@ impl TryFrom<String> for TextAlignment {
return Err(anyhow::Error::msg(format!(
"Failed parsing TextAlignment from: {}",
text
)))
)));
}
})
}
@ -80,19 +80,20 @@ impl Textable {
/// * `height_ratio` the ratio of the height in respect to the framable height
/// * `text_alignment` where the text is aligned to
pub fn new(
gui_handler: &mut GuiHandler<'_>,
framable: Arc<Framable>,
text: String,
height_ratio: f32,
text_alignment: TextAlignment,
text_color: Color,
) -> Result<Arc<Self>> {
let set = framable.gui_handler().color_descriptor(text_color)?;
let set = gui_handler.color_descriptor(text_color)?;
let buffer = if text.is_empty() {
None
} else {
Some(Self::create_text_buffer(
framable.gui_handler().device(),
gui_handler.device(),
text.len() as u32 * 6,
)?)
};
@ -120,7 +121,7 @@ impl Textable {
textable.framable.add_callback(
weak_textable,
Box::new(move || textable_clone.update_text()),
Box::new(move |gui_handler| textable_clone.update_text(gui_handler)),
);
Ok(textable)
@ -142,10 +143,8 @@ impl Textable {
/// # Arguments
///
/// * `textable` is a `&Arc<Textable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.add_textable(self.ui_layer.load(SeqCst), self.clone())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_textable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
@ -153,10 +152,8 @@ impl Textable {
/// # Arguments
///
/// * `textable` is a `&Arc<Textable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.framable
.gui_handler()
.delete_textable(self.ui_layer.load(SeqCst), self)
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_textable(self.ui_layer.load(SeqCst), self)
}
pub fn set_ui_layer(&self, ui_layer: i32) {
@ -173,8 +170,12 @@ impl Textable {
/// # Arguments
///
/// * `text_color` defines the color of the text
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
let set = self.framable.gui_handler().color_descriptor(text_color)?;
pub fn set_text_color(
&self,
gui_handler: &mut GuiHandler<'_>,
text_color: Color,
) -> Result<()> {
let set = gui_handler.color_descriptor(text_color)?;
*self.descriptor_set.write().unwrap() = set;
@ -186,9 +187,13 @@ impl Textable {
/// # Arguments
///
/// * `text_alignment` where the text is aligned to
pub fn set_text_alignment(&self, text_alignment: TextAlignment) -> Result<()> {
pub fn set_text_alignment(
&self,
gui_handler: &mut GuiHandler<'_>,
text_alignment: TextAlignment,
) -> Result<()> {
*self.text_alignment.write().unwrap() = text_alignment;
self.update_text()?;
self.update_text(gui_handler)?;
Ok(())
}
@ -214,14 +219,14 @@ impl Textable {
///
/// * `text` the text to be displayed
/// * `height_ratio` the ratio of the height in respect to the framable height
pub fn set_text(&self, text: impl ToString) -> Result<()> {
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
let text = text.to_string();
if text.is_empty() {
self.vertex_count.store(0, SeqCst);
*self.text.write().unwrap() = String::new();
self.framable.gui_handler().enqueue_text_update({
gui_handler.enqueue_text_update({
let weak_buffer = Arc::downgrade(&self.buffer);
Box::new(move || {
@ -234,7 +239,7 @@ impl Textable {
} else {
self.vertex_count.store(text.len() as u32 * 6, SeqCst);
*self.text.write().unwrap() = text;
self.update_text()?;
self.update_text(gui_handler)?;
}
Ok(())
@ -245,9 +250,9 @@ impl Textable {
/// # Arguments
///
/// * `height_ratio` the ratio of the height in respect to the framable height
pub fn set_size(&self, height_ratio: f32) -> Result<()> {
pub fn set_size(&self, gui_handler: &mut GuiHandler<'_>, height_ratio: f32) -> Result<()> {
*self.height_ratio.write().unwrap() = height_ratio;
self.update_text()?;
self.update_text(gui_handler)?;
Ok(())
}
@ -279,12 +284,12 @@ impl Textable {
}
/// Updates the texts buffer
pub fn update_text(&self) -> Result<()> {
pub fn update_text(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
self.calculate_text_size();
let (x, y) = self.calc_pos_from_alignment();
self.create_buffer(x, y)?;
self.create_buffer(gui_handler, x, y)?;
Ok(())
}
@ -320,13 +325,18 @@ impl Textable {
}
}
fn create_buffer(&self, win_x: f32, win_y: f32) -> Result<()> {
fn create_buffer(
&self,
gui_handler: &mut GuiHandler<'_>,
win_x: f32,
win_y: f32,
) -> Result<()> {
let weak_buffer = Arc::downgrade(&self.buffer);
let text = self.text.read().unwrap().clone();
let character_size = self.character_size.load(SeqCst);
let ortho = self.framable.ortho();
let ortho = gui_handler.ortho();
let device = self.framable.gui_handler().device().clone();
let device = gui_handler.device().clone();
let async_buffer_creation = Box::new(move || {
if let Some(buffer) = weak_buffer.upgrade() {
@ -484,14 +494,12 @@ impl Textable {
Ok(())
});
self.framable
.gui_handler()
.enqueue_text_update(async_buffer_creation);
gui_handler.enqueue_text_update(async_buffer_creation);
Ok(())
}
fn text_changed_through_write(&self) -> Result<()> {
fn text_changed_through_write(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
self.vertex_count
.store(self.text.read().unwrap().len() as u32 * 6, SeqCst);
self.character_size.store(
@ -500,28 +508,28 @@ impl Textable {
SeqCst,
);
self.update_text()?;
self.update_text(gui_handler)?;
Ok(())
}
}
impl ModifyText for Textable {
fn set_text(&self, text: String) -> Result<()> {
fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()> {
*self.text.write().unwrap() = text;
self.text_changed_through_write()
self.text_changed_through_write(gui_handler)
}
fn add_letter(&self, letter: char) -> Result<String> {
fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<String> {
self.text.write().unwrap().push(letter);
self.text_changed_through_write()?;
self.text_changed_through_write(gui_handler)?;
Ok(self.text.read().unwrap().clone())
}
fn remove_last(&self) -> Result<Option<String>> {
fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<Option<String>> {
self.text.write().unwrap().pop();
self.text_changed_through_write()?;
self.text_changed_through_write(gui_handler)?;
let text = self.text.read().unwrap().clone();

View file

@ -4,20 +4,18 @@ use crate::prelude::*;
use anyhow::Result;
use std::sync::{
atomic::{AtomicI32, Ordering::SeqCst},
Arc, RwLock,
atomic::{AtomicI32, Ordering::SeqCst},
};
pub trait ModifyText: Send + Sync {
fn set_text(&self, text: String) -> Result<()>;
fn add_letter(&self, letter: char) -> Result<String>;
fn remove_last(&self) -> Result<Option<String>>;
fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()>;
fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<String>;
fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<Option<String>>;
}
/// `Writeable` gives the ability to modify the text inside an `Textable`
pub struct Writeable {
gui_handler: Arc<GuiHandler>,
modifyable: Arc<dyn ModifyText>,
text_change_executable: Arc<Executable<Option<String>>>,
@ -29,12 +27,10 @@ pub struct Writeable {
impl Writeable {
/// Factory method for `Writeable`, returns `Arc<Writeable>`.
pub fn new(
gui_handler: Arc<GuiHandler>,
modifyable: Arc<dyn ModifyText>,
text_change_executable: Arc<Executable<Option<String>>>,
) -> Result<Arc<Self>> {
Ok(Arc::new(Writeable {
gui_handler,
modifyable,
text_change_executable,
@ -44,8 +40,8 @@ impl Writeable {
}))
}
pub fn set_active(self: &Arc<Self>) -> Result<()> {
if self.gui_handler.set_active_writeable(self.clone())? {
pub fn set_active(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
if gui_handler.set_active_writeable(self.clone())? {
if let Some(exec) = &*self.activation_changed_executable.read().unwrap() {
exec(true)?;
}
@ -74,9 +70,8 @@ impl Writeable {
/// # Arguments
///
/// * `writeable` is a `&Arc<Writeable>` instance that is going to be added
pub fn add(self: &Arc<Self>) -> Result<()> {
self.gui_handler
.add_writeable(self.ui_layer.load(SeqCst), self.clone())
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.add_writeable(self.ui_layer.load(SeqCst), self.clone())
}
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
@ -84,9 +79,8 @@ impl Writeable {
/// # Arguments
///
/// * `writeable` is a `&Arc<Writeable>` instance that is going to be deleted
pub fn delete(self: &Arc<Self>) -> Result<()> {
self.gui_handler
.delete_writeable(self.ui_layer.load(SeqCst), self)
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
gui_handler.delete_writeable(self.ui_layer.load(SeqCst), self)
}
pub fn set_ui_layer(&self, ui_layer: i32) {
@ -98,11 +92,11 @@ impl Writeable {
/// # Arguments
///
/// * `text` that replaces the current text
pub fn set_text(&self, text: String) -> Result<()> {
self.modifyable.set_text(text.clone())?;
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()> {
self.modifyable.set_text(gui_handler, text.clone())?;
self.text_change_executable
.execute(if text.is_empty() { None } else { Some(text) })?;
.execute(gui_handler, if text.is_empty() { None } else { Some(text) })?;
Ok(())
}
@ -112,17 +106,19 @@ impl Writeable {
/// # Arguments
///
/// * `letter` the letter thats going to be added
pub fn add_letter(&self, letter: char) -> Result<()> {
self.text_change_executable
.execute(Some(self.modifyable.add_letter(letter)?))?;
pub fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<()> {
self.text_change_executable.execute(
gui_handler,
Some(self.modifyable.add_letter(gui_handler, letter)?),
)?;
Ok(())
}
/// Removes the last letter
pub fn remove_last(&self) -> Result<()> {
pub fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
self.text_change_executable
.execute(self.modifyable.remove_last()?)?;
.execute(gui_handler, self.modifyable.remove_last(gui_handler)?)?;
Ok(())
}

File diff suppressed because it is too large Load diff