Extend parser with generator feature
This commit is contained in:
parent
cfd079b370
commit
5f63f4115e
6 changed files with 137 additions and 49 deletions
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quick-xml = "0.31.0"
|
quick-xml = "0.31.0"
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
|
serde_json = { version = "1.0.114" }
|
||||||
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
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.14"
|
paste = "1.0.14"
|
||||||
|
|
|
@ -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 serde_json::from_str;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
|
||||||
use quick_xml::{events::Event, Reader};
|
use quick_xml::{events::Event, Reader};
|
||||||
|
@ -514,7 +515,10 @@ pub fn cow_to_fill_type<'a>(cow: Cow<'a, [u8]>) -> FillTypeInfo {
|
||||||
|
|
||||||
match Color::try_from(text.as_str()) {
|
match Color::try_from(text.as_str()) {
|
||||||
Ok(color) => FillTypeInfo::Color(color),
|
Ok(color) => FillTypeInfo::Color(color),
|
||||||
Err(_) => FillTypeInfo::Image(AssetPath::from(text)),
|
Err(_) => match from_str(text.as_str()) {
|
||||||
|
Ok(descriptor) => FillTypeInfo::Element(descriptor),
|
||||||
|
Err(_) => FillTypeInfo::Image(AssetPath::from(text)),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,13 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use utilities::color::Color;
|
use utilities::color::Color;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
use self::generator::Generator;
|
use self::generator::Generator;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
pub enum ElementBorderThickness {
|
pub enum ElementBorderThickness {
|
||||||
Pixel(u32),
|
Pixel(u32),
|
||||||
Ratio(f32),
|
Ratio(f32),
|
||||||
|
@ -30,7 +31,21 @@ impl From<f32> for ElementBorderThickness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
impl PartialEq for ElementBorderThickness {
|
||||||
|
fn eq(&self, other: &ElementBorderThickness) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
(ElementBorderThickness::Pixel(m), ElementBorderThickness::Pixel(o)) => m == o,
|
||||||
|
(ElementBorderThickness::Ratio(m), ElementBorderThickness::Ratio(o)) => m == o,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The serialized string looks like:
|
||||||
|
///
|
||||||
|
/// {"background_color":"White","border_color":"Black","border_thickness":{"Pixel":5}}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ElementDescriptor {
|
pub struct ElementDescriptor {
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
border_color: Color,
|
border_color: Color,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::prelude::*;
|
use crate::{guihandler::gui::displayable::DisplayableType, prelude::*};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use assetpath::AssetPath;
|
use assetpath::AssetPath;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
|
@ -8,10 +8,11 @@ use std::sync::{
|
||||||
Arc,
|
Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum FillTypeInfo {
|
pub enum FillTypeInfo {
|
||||||
Image(AssetPath),
|
Image(AssetPath),
|
||||||
Color(Color),
|
Color(Color),
|
||||||
|
Element(ElementDescriptor),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color> for FillTypeInfo {
|
impl From<Color> for FillTypeInfo {
|
||||||
|
@ -52,6 +53,9 @@ pub(crate) enum InnerFillType {
|
||||||
impl InnerFillType {
|
impl InnerFillType {
|
||||||
pub(crate) fn new(framable: Arc<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
|
pub(crate) fn new(framable: Arc<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
|
||||||
match fill_type_info {
|
match fill_type_info {
|
||||||
|
FillTypeInfo::Element(descriptor) => Ok(InnerFillType::Image(Displayable::new(
|
||||||
|
framable, descriptor,
|
||||||
|
)?)),
|
||||||
FillTypeInfo::Image(path) => {
|
FillTypeInfo::Image(path) => {
|
||||||
Ok(InnerFillType::Image(Displayable::new(framable, path)?))
|
Ok(InnerFillType::Image(Displayable::new(framable, path)?))
|
||||||
}
|
}
|
||||||
|
@ -149,7 +153,16 @@ impl PartialEq<FillTypeInfo> for FillType {
|
||||||
fn eq(&self, info: &FillTypeInfo) -> bool {
|
fn eq(&self, info: &FillTypeInfo) -> bool {
|
||||||
match (&self.inner, info) {
|
match (&self.inner, info) {
|
||||||
(InnerFillType::Image(inner_image), FillTypeInfo::Image(info_image)) => {
|
(InnerFillType::Image(inner_image), FillTypeInfo::Image(info_image)) => {
|
||||||
inner_image.path() == info_image
|
match inner_image.inner_type() {
|
||||||
|
DisplayableType::Path(path) => path == *info_image,
|
||||||
|
DisplayableType::Descriptor(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(InnerFillType::Image(inner_image), FillTypeInfo::Element(info_descriptor)) => {
|
||||||
|
match inner_image.inner_type() {
|
||||||
|
DisplayableType::Path(_) => false,
|
||||||
|
DisplayableType::Descriptor(descriptor) => descriptor == *info_descriptor,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(InnerFillType::Color(inner_color), FillTypeInfo::Color(info_color)) => {
|
(InnerFillType::Color(inner_color), FillTypeInfo::Color(info_color)) => {
|
||||||
inner_color.color() == *info_color
|
inner_color.color() == *info_color
|
||||||
|
|
|
@ -15,15 +15,33 @@ use std::sync::{
|
||||||
{Arc, RwLock},
|
{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum DisplayableType {
|
||||||
|
Path(AssetPath),
|
||||||
|
Descriptor(ElementDescriptor),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AssetPath> for DisplayableType {
|
||||||
|
fn from(value: AssetPath) -> Self {
|
||||||
|
Self::Path(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ElementDescriptor> for DisplayableType {
|
||||||
|
fn from(value: ElementDescriptor) -> Self {
|
||||||
|
Self::Descriptor(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `Displayable` gives the ability to display a texture as background image for an item
|
/// `Displayable` gives the ability to display a texture as background image for an item
|
||||||
pub struct Displayable {
|
pub struct Displayable {
|
||||||
framable: Arc<Framable>,
|
framable: Arc<Framable>,
|
||||||
|
|
||||||
descriptor_set: RwLock<Arc<DescriptorSet>>,
|
descriptor_set: Arc<DescriptorSet>,
|
||||||
|
|
||||||
buffer: Arc<Buffer<TexturedVertex>>,
|
buffer: Arc<Buffer<TexturedVertex>>,
|
||||||
|
|
||||||
path: AssetPath,
|
displayable_type: RwLock<DisplayableType>,
|
||||||
|
|
||||||
ui_layer: AtomicI32,
|
ui_layer: AtomicI32,
|
||||||
|
|
||||||
|
@ -45,8 +63,20 @@ impl Displayable {
|
||||||
///
|
///
|
||||||
/// * `framable` is a `Arc<Framable>` instance
|
/// * `framable` is a `Arc<Framable>` instance
|
||||||
/// * `name` is the name for a png
|
/// * `name` is the name for a png
|
||||||
pub fn new(framable: Arc<Framable>, name: AssetPath) -> Result<Arc<Self>> {
|
pub fn new(
|
||||||
let descriptor_set = framable.gui_handler().image_descriptor(name.clone())?;
|
framable: Arc<Framable>,
|
||||||
|
displayable_type: impl Into<DisplayableType>,
|
||||||
|
) -> Result<Arc<Self>> {
|
||||||
|
let descriptor_set = framable.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())?;
|
||||||
|
descriptor_set.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
|
||||||
|
}
|
||||||
|
|
||||||
let buffer = Buffer::builder()
|
let buffer = Buffer::builder()
|
||||||
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||||
|
@ -56,10 +86,10 @@ impl Displayable {
|
||||||
|
|
||||||
let displayable = Arc::new(Displayable {
|
let displayable = Arc::new(Displayable {
|
||||||
framable,
|
framable,
|
||||||
descriptor_set: RwLock::new(descriptor_set),
|
descriptor_set,
|
||||||
buffer,
|
buffer,
|
||||||
|
|
||||||
path: name,
|
displayable_type: RwLock::new(displayable_type),
|
||||||
|
|
||||||
ui_layer: AtomicI32::new(0),
|
ui_layer: AtomicI32::new(0),
|
||||||
|
|
||||||
|
@ -107,8 +137,8 @@ impl Displayable {
|
||||||
.delete_displayable(self.ui_layer.load(SeqCst), self)
|
.delete_displayable(self.ui_layer.load(SeqCst), self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path(&self) -> &AssetPath {
|
pub fn inner_type(&self) -> DisplayableType {
|
||||||
&self.path
|
self.displayable_type.read().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ui_layer(&self, ui_layer: i32) {
|
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||||||
|
@ -125,10 +155,37 @@ impl Displayable {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `name` is the name of the texture in `gui/` without `.png` suffix
|
/// * `name` is the name of the texture in `gui/` without `.png` suffix
|
||||||
pub fn set_image(&self, name: AssetPath) -> Result<()> {
|
pub fn set_image(&self, displayable_type: impl Into<DisplayableType>) -> Result<()> {
|
||||||
let descriptor_set = self.framable.gui_handler().image_descriptor(name)?;
|
let displayable_type = displayable_type.into();
|
||||||
|
|
||||||
*self.descriptor_set.write().unwrap() = descriptor_set;
|
let texture = match displayable_type.clone() {
|
||||||
|
DisplayableType::Path(path) => Some(
|
||||||
|
self.framable
|
||||||
|
.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)?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(texture) = texture {
|
||||||
|
self.descriptor_set
|
||||||
|
.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
*self.displayable_type.write().unwrap() = displayable_type;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -140,7 +197,7 @@ impl Displayable {
|
||||||
|
|
||||||
/// Returns the internal vulkan descriptor set
|
/// Returns the internal vulkan descriptor set
|
||||||
pub fn descriptor_set(&self) -> Arc<DescriptorSet> {
|
pub fn descriptor_set(&self) -> Arc<DescriptorSet> {
|
||||||
self.descriptor_set.read().unwrap().clone()
|
self.descriptor_set.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_left_factor(&self, factor: f32) {
|
pub fn set_left_factor(&self, factor: f32) {
|
||||||
|
|
|
@ -83,13 +83,6 @@ struct GuiSeparator {
|
||||||
pipeline: Arc<Pipeline>,
|
pipeline: Arc<Pipeline>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DisplayableTexture {
|
|
||||||
_descriptor_pool: Arc<DescriptorPool>,
|
|
||||||
_descriptor_set: Arc<DescriptorSet>,
|
|
||||||
|
|
||||||
_texture: Arc<Image>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_reprc!(
|
impl_reprc!(
|
||||||
struct ColorBuffer {
|
struct ColorBuffer {
|
||||||
#[assume_reprc]
|
#[assume_reprc]
|
||||||
|
@ -227,9 +220,11 @@ pub struct GuiHandler {
|
||||||
text_color_layout: Arc<DescriptorSetLayout>,
|
text_color_layout: Arc<DescriptorSetLayout>,
|
||||||
|
|
||||||
internal_icons: RwLock<HashMap<AssetPath, Weak<Image>>>,
|
internal_icons: RwLock<HashMap<AssetPath, Weak<Image>>>,
|
||||||
internal_textures: RwLock<HashMap<AssetPath, DisplayableTexture>>,
|
internal_textures: RwLock<HashMap<AssetPath, Arc<Image>>>,
|
||||||
internal_colors: RwLock<HashMap<Color, TextableColor>>,
|
internal_colors: RwLock<HashMap<Color, TextableColor>>,
|
||||||
|
|
||||||
|
element_creator: Mutex<ElementCreator>,
|
||||||
|
|
||||||
ortho: RwLock<cgmath::Matrix4<f32>>,
|
ortho: RwLock<cgmath::Matrix4<f32>>,
|
||||||
|
|
||||||
icon_descriptor_layout: Arc<DescriptorSetLayout>,
|
icon_descriptor_layout: Arc<DescriptorSetLayout>,
|
||||||
|
@ -377,6 +372,8 @@ impl GuiHandler {
|
||||||
internal_textures: RwLock::new(HashMap::new()),
|
internal_textures: RwLock::new(HashMap::new()),
|
||||||
internal_colors: RwLock::new(HashMap::new()),
|
internal_colors: RwLock::new(HashMap::new()),
|
||||||
|
|
||||||
|
element_creator: Mutex::new(ElementCreator::new(device.clone(), queue.clone())?),
|
||||||
|
|
||||||
icon_descriptor_layout,
|
icon_descriptor_layout,
|
||||||
|
|
||||||
needs_update: AtomicBool::new(true),
|
needs_update: AtomicBool::new(true),
|
||||||
|
@ -499,44 +496,45 @@ impl GuiHandler {
|
||||||
._descriptor_layout
|
._descriptor_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn image_descriptor(&self, mut path: AssetPath) -> Result<Arc<DescriptorSet>> {
|
pub(crate) fn displayable_image_from_descriptor(
|
||||||
|
&self,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
descriptor: ElementDescriptor,
|
||||||
|
) -> Result<Arc<Image>> {
|
||||||
|
self.element_creator
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get(width, height, descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn image_descriptor_set(&self) -> Result<Arc<DescriptorSet>> {
|
||||||
|
let desc_pool = DescriptorPool::builder()
|
||||||
|
.set_layout(self.text_desc_layout().clone())
|
||||||
|
.build(self.device.clone())?;
|
||||||
|
|
||||||
|
DescriptorPool::prepare_set(&desc_pool).allocate()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn displayable_image_from_path(&self, mut path: AssetPath) -> Result<Arc<Image>> {
|
||||||
if !path.has_prefix() {
|
if !path.has_prefix() {
|
||||||
path.set_prefix(&self.resource_base_path.full_path());
|
path.set_prefix(&self.resource_base_path.full_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.internal_textures.read().unwrap().contains_key(&path) {
|
if self.internal_textures.read().unwrap().contains_key(&path) {
|
||||||
Ok(self.internal_textures.read().unwrap()[&path]
|
Ok(self.internal_textures.read().unwrap()[&path].clone())
|
||||||
._descriptor_set
|
|
||||||
.clone())
|
|
||||||
} else {
|
} else {
|
||||||
let texture = Image::from_file(path.clone())?
|
let texture = Image::from_file(path.clone())?
|
||||||
.format(VK_FORMAT_R8G8B8A8_UNORM)
|
.format(VK_FORMAT_R8G8B8A8_UNORM)
|
||||||
.attach_sampler(Sampler::nearest_sampler().build(&self.device)?)
|
.attach_sampler(Sampler::nearest_sampler().build(&self.device)?)
|
||||||
.build(&self.device, &self.queue)?;
|
.build(&self.device, &self.queue)?;
|
||||||
|
|
||||||
let desc_pool = DescriptorPool::builder()
|
|
||||||
.set_layout(self.text_desc_layout().clone())
|
|
||||||
.build(self.device.clone())?;
|
|
||||||
|
|
||||||
let descriptor_set = DescriptorPool::prepare_set(&desc_pool).allocate()?;
|
|
||||||
|
|
||||||
descriptor_set.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
|
|
||||||
|
|
||||||
let displayable_texture = DisplayableTexture {
|
|
||||||
_descriptor_pool: desc_pool,
|
|
||||||
_descriptor_set: descriptor_set,
|
|
||||||
|
|
||||||
_texture: texture,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.internal_textures
|
self.internal_textures
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(path.clone(), displayable_texture);
|
.insert(path.clone(), texture.clone());
|
||||||
|
|
||||||
Ok(self.internal_textures.read().unwrap()[&path]
|
Ok(texture.clone())
|
||||||
._descriptor_set
|
|
||||||
.clone())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue