Free from context dependency

This commit is contained in:
hodasemi 2023-01-16 12:58:59 +01:00 committed by Michael Hübner
parent 7c359462a9
commit 6024ae6806
30 changed files with 272 additions and 42 deletions

View file

@ -7,11 +7,12 @@ edition = "2021"
[dependencies] [dependencies]
quick-xml = "0.27.1" quick-xml = "0.27.1"
serde = { version = "1.0.152", features = ["derive"] } serde = { version = "1.0.152", features = ["derive"] }
# context = { path = "../context" } vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
utilities = { git = "https://gavania.de/hodasemi/utilities.git" } utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
paste = "1.0.11" paste = "1.0.11"
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" } assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
anyhow = { version = "1.0.68", features = ["backtrace"] } anyhow = { version = "1.0.68", features = ["backtrace"] }
cgmath = "0.18.0"
[features] [features]
audio = [] audio = []

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use assetpath::AssetPath; use assetpath::AssetPath;

View file

@ -1,6 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,5 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::gridinfo::GridInfo; use super::gridinfo::GridInfo;
use super::mandatory::Mandatory; use super::mandatory::Mandatory;

View file

@ -1,6 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use quick_xml::{events::Event, Reader}; use quick_xml::{events::Event, Reader};

60
src/context_interface.rs Normal file
View file

@ -0,0 +1,60 @@
use std::sync::{Arc, Mutex};
use vulkan_rs::prelude::*;
pub trait ContextInterface: Send + Sync {
fn device(&self) -> &Arc<Device>;
fn queue(&self) -> &Arc<Mutex<Queue>>;
fn format(&self) -> VkFormat;
fn image_layout(&self) -> VkImageLayout;
fn image_count(&self) -> usize;
fn images(&self) -> TargetMode<Vec<Arc<Image>>>;
fn width(&self) -> u32;
fn height(&self) -> u32;
}
pub enum TargetMode<T> {
Mono(T),
Stereo(T, T),
}
impl<T> TargetMode<T> {
pub fn mono(&self) -> &T {
match self {
TargetMode::Mono(s) => s,
TargetMode::Stereo(_, _) => panic!("Expected another target mode"),
}
}
pub fn mono_mut(&mut self) -> &mut T {
match self {
TargetMode::Mono(s) => s,
TargetMode::Stereo(_, _) => panic!("Expected another target mode"),
}
}
pub fn stereo(&self) -> (&T, &T) {
match self {
TargetMode::Mono(_) => panic!("Expected another target mode"),
TargetMode::Stereo(l, r) => (l, r),
}
}
pub fn stereo_mut(&mut self) -> (&mut T, &mut T) {
match self {
TargetMode::Mono(_) => panic!("Expected another target mode"),
TargetMode::Stereo(l, r) => (l, r),
}
}
}
impl<T: Clone> Clone for TargetMode<T> {
fn clone(&self) -> TargetMode<T> {
match self {
TargetMode::Mono(t) => TargetMode::Mono(t.clone()),
TargetMode::Stereo(lhs, rhs) => TargetMode::Stereo(lhs.clone(), rhs.clone()),
}
}
}

115
src/controller_button.rs Normal file
View file

@ -0,0 +1,115 @@
use anyhow::Result;
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum ControllerButton {
A,
B,
Y,
X,
Start,
Select,
RightButton,
LeftButton,
RightTrigger,
LeftTrigger,
DPadUp,
DPadDown,
DPadRight,
DPadLeft,
Guide,
LeftStick,
RightStick,
Misc,
Paddle1,
Paddle2,
Paddle3,
Paddle4,
Touchpad,
}
impl TryFrom<&str> for ControllerButton {
type Error = anyhow::Error;
fn try_from(text: &str) -> Result<Self> {
match text {
"A" => Ok(ControllerButton::A),
"B" => Ok(ControllerButton::B),
"X" => Ok(ControllerButton::X),
"Y" => Ok(ControllerButton::Y),
"Select" => Ok(ControllerButton::Select),
"Start" => Ok(ControllerButton::Start),
"RightButton" => Ok(ControllerButton::RightButton),
"LeftButton" => Ok(ControllerButton::LeftButton),
"RightTrigger" => Ok(ControllerButton::RightTrigger),
"LeftTrigger" => Ok(ControllerButton::LeftTrigger),
"DPadUp" => Ok(ControllerButton::DPadUp),
"DPadDown" => Ok(ControllerButton::DPadDown),
"DPadLeft" => Ok(ControllerButton::DPadLeft),
"DPadRight" => Ok(ControllerButton::DPadRight),
"Guide" => Ok(ControllerButton::Guide),
"LeftStick" => Ok(ControllerButton::LeftStick),
"RightStick" => Ok(ControllerButton::RightStick),
_ => Err(anyhow::Error::msg(format!(
"Failed converting ControllerButton from {}",
text
))),
}
}
}
impl Into<&'static str> for ControllerButton {
fn into(self) -> &'static str {
use ControllerButton::*;
match self {
A => "A",
B => "B",
Y => "Y",
X => "X",
Start => "Start",
Select => "Select",
RightButton => "RightButton",
LeftButton => "LeftButton",
RightTrigger => "RightTrigger",
LeftTrigger => "LeftTrigger",
DPadUp => "DPadUp",
DPadDown => "DPadDown",
DPadRight => "DPadRight",
DPadLeft => "DPadLeft",
Guide => "Guide",
LeftStick => "LeftStick",
RightStick => "RightStick",
Misc => "Misc",
Paddle1 => "Paddle1",
Paddle2 => "Paddle2",
Paddle3 => "Paddle3",
Paddle4 => "Paddle4",
Touchpad => "Touchpad",
}
}
}

View file

@ -2,6 +2,8 @@ use crate::{builder::validator::buttoninfo::ButtonInfo, prelude::*};
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use super::{ use super::{
fill_type::{FillType, InnerFillType}, fill_type::{FillType, InnerFillType},

View file

@ -1,6 +1,7 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use std::sync::{ use std::sync::{
atomic::{AtomicBool, Ordering::SeqCst}, atomic::{AtomicBool, Ordering::SeqCst},

View file

@ -1,5 +1,7 @@
use crate::{builder::validator::iconinfo::IconInfo, prelude::*}; use crate::{builder::validator::iconinfo::IconInfo, prelude::*};
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use std::sync::{ use std::sync::{
atomic::{AtomicBool, Ordering::SeqCst}, atomic::{AtomicBool, Ordering::SeqCst},

View file

@ -8,6 +8,7 @@ use std::sync::{
}; };
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
pub struct LabelBuilder { pub struct LabelBuilder {
text_alignment: TextAlignment, text_alignment: TextAlignment,

View file

@ -4,6 +4,8 @@ use std::sync::{
atomic::{AtomicU32, Ordering::SeqCst}, atomic::{AtomicU32, Ordering::SeqCst},
Arc, Mutex, Arc, Mutex,
}; };
use utilities::prelude::*;
use vulkan_rs::prelude::*;
pub mod button; pub mod button;
pub mod fill_type; pub mod fill_type;
@ -115,7 +117,12 @@ impl TextableWrapper {
} }
pub(crate) fn text(&self) -> Result<Option<String>> { pub(crate) fn text(&self) -> Result<Option<String>> {
Ok(self.textable.lock().unwrap().as_ref().map(|textable| textable.text())) Ok(self
.textable
.lock()
.unwrap()
.as_ref()
.map(|textable| textable.text()))
} }
pub(crate) fn set_height_ratio(&self, height_ratio: f32) -> Result<()> { pub(crate) fn set_height_ratio(&self, height_ratio: f32) -> Result<()> {

View file

@ -6,6 +6,7 @@ use std::sync::{
}; };
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
pub struct MultiLineLabelBuilder { pub struct MultiLineLabelBuilder {
text_alignment: TextAlignment, text_alignment: TextAlignment,

View file

@ -9,6 +9,7 @@ use std::sync::{
}; };
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use super::fill_type::InnerFillType; use super::fill_type::InnerFillType;

View file

@ -5,6 +5,7 @@ use std::sync::{
atomic::{AtomicBool, Ordering::SeqCst}, atomic::{AtomicBool, Ordering::SeqCst},
Arc, Mutex, Arc, Mutex,
}; };
use utilities::prelude::*;
use super::{ use super::{
fill_type::{FillType, InnerFillType}, fill_type::{FillType, InnerFillType},

View file

@ -1,5 +1,6 @@
use crate::{builder::validator::textfieldinfo::TextFieldInfo, prelude::*}; use crate::{builder::validator::textfieldinfo::TextFieldInfo, prelude::*};
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use std::sync::{ use std::sync::{
atomic::{AtomicBool, Ordering::SeqCst}, atomic::{AtomicBool, Ordering::SeqCst},

10
src/guidirection.rs Normal file
View file

@ -0,0 +1,10 @@
//! Enum for gui direction input abstraction
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum GuiDirection {
Left,
Right,
Up,
Down,
None,
}

View file

@ -2,6 +2,8 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use cgmath::{vec4, Vector4}; use cgmath::{vec4, Vector4};

View file

@ -3,6 +3,8 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use cgmath::{vec2, vec4}; use cgmath::{vec2, vec4};

View file

@ -3,6 +3,8 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use super::texturedvertex::TexturedVertex; use super::texturedvertex::TexturedVertex;

View file

@ -3,6 +3,8 @@
use super::writeable::ModifyText; use super::writeable::ModifyText;
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use super::texturedvertex::TexturedVertex; use super::texturedvertex::TexturedVertex;

View file

@ -1,4 +1,6 @@
use cgmath::prelude::Zero; use cgmath::prelude::Zero;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use std::mem; use std::mem;

View file

@ -1,6 +1,8 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use assetpath::AssetPath; use assetpath::AssetPath;
use utilities::prelude::*;
use vulkan_rs::prelude::*;
use super::{ use super::{
elements::Elements, elements::Elements,
@ -64,7 +66,7 @@ struct CommandBufferState {
} }
pub struct GuiHandler { pub struct GuiHandler {
context: Arc<Context>, context: Arc<dyn ContextInterface>,
device: Arc<Device>, device: Arc<Device>,
queue: Arc<Mutex<Queue>>, queue: Arc<Mutex<Queue>>,
@ -126,31 +128,28 @@ pub struct GuiHandler {
impl GuiHandler { impl GuiHandler {
pub fn new( pub fn new(
gui_handler_create_info: GuiHandlerCreateInfo, gui_handler_create_info: GuiHandlerCreateInfo,
context: &Arc<Context>, context: &Arc<dyn ContextInterface>,
) -> Result<Arc<GuiHandler>> { ) -> Result<Arc<GuiHandler>> {
let device = context.device(); let device = context.device();
let queue = context.queue(); let queue = context.queue();
let render_core = context.render_core();
let command_buffers = match render_core.images() { let command_buffers = match context.images() {
TargetMode::Single(_) => { TargetMode::Mono(_) => {
let command_buffers = Self::create_command_buffers(device, queue, render_core)?; let command_buffers = Self::create_command_buffers(device, queue, context)?;
TargetMode::Single(command_buffers) TargetMode::Mono(command_buffers)
} }
TargetMode::Stereo(_, _) => { TargetMode::Stereo(_, _) => {
let left_command_buffers = let left_command_buffers = Self::create_command_buffers(device, queue, context)?;
Self::create_command_buffers(device, queue, render_core)?; let right_command_buffers = Self::create_command_buffers(device, queue, context)?;
let right_command_buffers =
Self::create_command_buffers(device, queue, render_core)?;
TargetMode::Stereo(left_command_buffers, right_command_buffers) TargetMode::Stereo(left_command_buffers, right_command_buffers)
} }
}; };
let render_pass = let render_pass =
Self::create_render_pass(device, render_core.format(), render_core.image_layout())?; Self::create_render_pass(device, context.format(), context.image_layout())?;
let framebuffers = Self::create_framebuffers(device, &render_core.images(), &render_pass)?; let framebuffers = Self::create_framebuffers(device, &context.images(), &render_pass)?;
let (text_objs, color_layout) = Self::init_text_objects(device, &render_pass)?; let (text_objs, color_layout) = Self::init_text_objects(device, &render_pass)?;
let rect_objs = Self::init_rectangle_objects(device, &render_pass)?; let rect_objs = Self::init_rectangle_objects(device, &render_pass)?;
@ -172,14 +171,14 @@ impl GuiHandler {
) )
.build(device.clone())?; .build(device.clone())?;
let gui_handler = Arc::new(GuiHandler { Ok(Arc::new(GuiHandler {
context: context.clone(), context: context.clone(),
device: device.clone(), device: device.clone(),
queue: queue.clone(), queue: queue.clone(),
width: AtomicU32::new(render_core.width()), width: AtomicU32::new(context.width()),
height: AtomicU32::new(render_core.height()), height: AtomicU32::new(context.height()),
menu_button: { menu_button: {
let mut menu_button = gui_handler_create_info.menu_button; let mut menu_button = gui_handler_create_info.menu_button;
@ -244,9 +243,9 @@ impl GuiHandler {
ortho: RwLock::new(ortho( ortho: RwLock::new(ortho(
0.0, 0.0,
render_core.width() as f32, context.width() as f32,
0.0, 0.0,
render_core.height() as f32, context.height() as f32,
-1.0, -1.0,
1.0, 1.0,
)), )),
@ -260,11 +259,7 @@ impl GuiHandler {
current_hoverable: RwLock::new(None), current_hoverable: RwLock::new(None),
current_selectable: RwLock::new(None), current_selectable: RwLock::new(None),
current_writeable: RwLock::new(None), current_writeable: RwLock::new(None),
}); }))
render_core.add_post_processing_routine(gui_handler.clone());
Ok(gui_handler)
} }
pub fn device(&self) -> &Arc<Device> { pub fn device(&self) -> &Arc<Device> {
@ -1199,10 +1194,10 @@ impl GuiHandler {
}; };
match target_images { match target_images {
TargetMode::Single(images) => { TargetMode::Mono(images) => {
let framebuffers = create_framebuffer(device, images, render_pass)?; let framebuffers = create_framebuffer(device, images, render_pass)?;
Ok(TargetMode::Single(framebuffers)) Ok(TargetMode::Mono(framebuffers))
} }
TargetMode::Stereo(left_images, right_images) => { TargetMode::Stereo(left_images, right_images) => {
let left_framebuffers = create_framebuffer(device, left_images, render_pass)?; let left_framebuffers = create_framebuffer(device, left_images, render_pass)?;
@ -1216,11 +1211,11 @@ impl GuiHandler {
fn create_command_buffers( fn create_command_buffers(
device: &Arc<Device>, device: &Arc<Device>,
queue: &Arc<Mutex<Queue>>, queue: &Arc<Mutex<Queue>>,
render_core: &Box<dyn RenderCore>, context: &Arc<dyn ContextInterface>,
) -> Result<Vec<CommandBufferState>> { ) -> Result<Vec<CommandBufferState>> {
let mut command_buffers = Vec::with_capacity(render_core.image_count()); let mut command_buffers = Vec::with_capacity(context.image_count());
for _ in 0..render_core.image_count() { for _ in 0..context.image_count() {
command_buffers.push(CommandBufferState { command_buffers.push(CommandBufferState {
command_buffer: CommandBuffer::new_secondary() command_buffer: CommandBuffer::new_secondary()
.build(device.clone(), queue.clone())?, .build(device.clone(), queue.clone())?,
@ -1460,19 +1455,15 @@ impl GuiHandler {
} }
} }
impl PostProcess for GuiHandler { impl GuiHandler {
fn priority(&self) -> u32 { pub fn process(
50
}
fn process(
&self, &self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'_>,
indices: &TargetMode<usize>, indices: &TargetMode<usize>,
) -> Result<()> { ) -> Result<()> {
if self.needs_update.load(SeqCst) { if self.needs_update.load(SeqCst) {
match &self.command_buffers { match &self.command_buffers {
TargetMode::Single(command_buffers) => { TargetMode::Mono(command_buffers) => {
for state in command_buffers { for state in command_buffers {
state.valid.store(false, SeqCst); state.valid.store(false, SeqCst);
} }
@ -1507,9 +1498,9 @@ impl PostProcess for GuiHandler {
indices, indices,
) { ) {
( (
TargetMode::Single(command_buffers), TargetMode::Mono(command_buffers),
TargetMode::Single(framebuffers), TargetMode::Mono(framebuffers),
TargetMode::Single(index), TargetMode::Mono(index),
) => { ) => {
self.select_rendering(buffer_recorder, command_buffers, framebuffers, *index)?; self.select_rendering(buffer_recorder, command_buffers, framebuffers, *index)?;
} }
@ -1527,10 +1518,10 @@ impl PostProcess for GuiHandler {
Ok(()) Ok(())
} }
fn resize(&self, width: u32, height: u32) -> Result<()> { pub fn resize(&self, width: u32, height: u32) -> Result<()> {
*self.framebuffers.lock().unwrap() = Self::create_framebuffers( *self.framebuffers.lock().unwrap() = Self::create_framebuffers(
self.context.device(), self.context.device(),
&self.context.render_core().images(), &self.context.images(),
&self.render_pass, &self.render_pass,
)?; )?;

View file

@ -7,6 +7,10 @@ pub mod keyboard;
pub mod states; pub mod states;
pub mod tab_control; pub mod tab_control;
mod context_interface;
mod controller_button;
mod guidirection;
mod mousebutton;
pub mod prelude; pub mod prelude;
pub type CustomCallback<I, O> = dyn Fn(I) -> anyhow::Result<O> + Send + Sync; pub type CustomCallback<I, O> = dyn Fn(I) -> anyhow::Result<O> + Send + Sync;

10
src/mousebutton.rs Normal file
View file

@ -0,0 +1,10 @@
//! Mouse button abstraction
#[derive(PartialEq, Copy, Clone, Debug)]
pub enum MouseButton {
Left,
Middle,
Right,
Forward,
Backward,
}

View file

@ -1,7 +1,11 @@
pub use super::builder::{builder::GuiBuilder, snippet::GuiSnippet}; pub use super::builder::{builder::GuiBuilder, snippet::GuiSnippet};
pub use super::context_interface::{ContextInterface, TargetMode};
pub use super::controller_button::ControllerButton;
pub use super::elements::prelude::*; pub use super::elements::prelude::*;
pub use super::guidirection::GuiDirection;
pub use super::guihandler::prelude::*; pub use super::guihandler::prelude::*;
pub use super::keyboard::Keyboard; pub use super::keyboard::Keyboard;
pub use super::mousebutton::MouseButton;
pub use super::states::*; pub use super::states::*;
pub use super::tab_control::TabControl; pub use super::tab_control::TabControl;