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]
|
||||
quick-xml = "0.31.0"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
serde_json = { version = "1.0.114" }
|
||||
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
||||
paste = "1.0.14"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::prelude::*;
|
||||
use anyhow::{Context, Result};
|
||||
use assetpath::AssetPath;
|
||||
use serde_json::from_str;
|
||||
use utilities::prelude::*;
|
||||
|
||||
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()) {
|
||||
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 serde::{Deserialize, Serialize};
|
||||
use utilities::color::Color;
|
||||
use vulkan_rs::prelude::*;
|
||||
|
||||
use self::generator::Generator;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum ElementBorderThickness {
|
||||
Pixel(u32),
|
||||
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 {
|
||||
background_color: Color,
|
||||
border_color: Color,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::prelude::*;
|
||||
use crate::{guihandler::gui::displayable::DisplayableType, prelude::*};
|
||||
use anyhow::Result;
|
||||
use assetpath::AssetPath;
|
||||
use utilities::prelude::*;
|
||||
|
@ -8,10 +8,11 @@ use std::sync::{
|
|||
Arc,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FillTypeInfo {
|
||||
Image(AssetPath),
|
||||
Color(Color),
|
||||
Element(ElementDescriptor),
|
||||
}
|
||||
|
||||
impl From<Color> for FillTypeInfo {
|
||||
|
@ -52,6 +53,9 @@ pub(crate) enum InnerFillType {
|
|||
impl InnerFillType {
|
||||
pub(crate) fn new(framable: Arc<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
|
||||
match fill_type_info {
|
||||
FillTypeInfo::Element(descriptor) => Ok(InnerFillType::Image(Displayable::new(
|
||||
framable, descriptor,
|
||||
)?)),
|
||||
FillTypeInfo::Image(path) => {
|
||||
Ok(InnerFillType::Image(Displayable::new(framable, path)?))
|
||||
}
|
||||
|
@ -149,7 +153,16 @@ impl PartialEq<FillTypeInfo> for FillType {
|
|||
fn eq(&self, info: &FillTypeInfo) -> bool {
|
||||
match (&self.inner, info) {
|
||||
(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)) => {
|
||||
inner_color.color() == *info_color
|
||||
|
|
|
@ -15,15 +15,33 @@ use std::sync::{
|
|||
{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
|
||||
pub struct Displayable {
|
||||
framable: Arc<Framable>,
|
||||
|
||||
descriptor_set: RwLock<Arc<DescriptorSet>>,
|
||||
descriptor_set: Arc<DescriptorSet>,
|
||||
|
||||
buffer: Arc<Buffer<TexturedVertex>>,
|
||||
|
||||
path: AssetPath,
|
||||
displayable_type: RwLock<DisplayableType>,
|
||||
|
||||
ui_layer: AtomicI32,
|
||||
|
||||
|
@ -45,8 +63,20 @@ impl Displayable {
|
|||
///
|
||||
/// * `framable` is a `Arc<Framable>` instance
|
||||
/// * `name` is the name for a png
|
||||
pub fn new(framable: Arc<Framable>, name: AssetPath) -> Result<Arc<Self>> {
|
||||
let descriptor_set = framable.gui_handler().image_descriptor(name.clone())?;
|
||||
pub fn new(
|
||||
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()
|
||||
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||
|
@ -56,10 +86,10 @@ impl Displayable {
|
|||
|
||||
let displayable = Arc::new(Displayable {
|
||||
framable,
|
||||
descriptor_set: RwLock::new(descriptor_set),
|
||||
descriptor_set,
|
||||
buffer,
|
||||
|
||||
path: name,
|
||||
displayable_type: RwLock::new(displayable_type),
|
||||
|
||||
ui_layer: AtomicI32::new(0),
|
||||
|
||||
|
@ -107,8 +137,8 @@ impl Displayable {
|
|||
.delete_displayable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &AssetPath {
|
||||
&self.path
|
||||
pub fn inner_type(&self) -> DisplayableType {
|
||||
self.displayable_type.read().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||||
|
@ -125,10 +155,37 @@ impl Displayable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `name` is the name of the texture in `gui/` without `.png` suffix
|
||||
pub fn set_image(&self, name: AssetPath) -> Result<()> {
|
||||
let descriptor_set = self.framable.gui_handler().image_descriptor(name)?;
|
||||
pub fn set_image(&self, displayable_type: impl Into<DisplayableType>) -> Result<()> {
|
||||
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(())
|
||||
}
|
||||
|
@ -140,7 +197,7 @@ impl Displayable {
|
|||
|
||||
/// Returns the internal vulkan descriptor set
|
||||
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) {
|
||||
|
|
|
@ -83,13 +83,6 @@ struct GuiSeparator {
|
|||
pipeline: Arc<Pipeline>,
|
||||
}
|
||||
|
||||
struct DisplayableTexture {
|
||||
_descriptor_pool: Arc<DescriptorPool>,
|
||||
_descriptor_set: Arc<DescriptorSet>,
|
||||
|
||||
_texture: Arc<Image>,
|
||||
}
|
||||
|
||||
impl_reprc!(
|
||||
struct ColorBuffer {
|
||||
#[assume_reprc]
|
||||
|
@ -227,9 +220,11 @@ pub struct GuiHandler {
|
|||
text_color_layout: Arc<DescriptorSetLayout>,
|
||||
|
||||
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>>,
|
||||
|
||||
element_creator: Mutex<ElementCreator>,
|
||||
|
||||
ortho: RwLock<cgmath::Matrix4<f32>>,
|
||||
|
||||
icon_descriptor_layout: Arc<DescriptorSetLayout>,
|
||||
|
@ -377,6 +372,8 @@ impl GuiHandler {
|
|||
internal_textures: RwLock::new(HashMap::new()),
|
||||
internal_colors: RwLock::new(HashMap::new()),
|
||||
|
||||
element_creator: Mutex::new(ElementCreator::new(device.clone(), queue.clone())?),
|
||||
|
||||
icon_descriptor_layout,
|
||||
|
||||
needs_update: AtomicBool::new(true),
|
||||
|
@ -499,44 +496,45 @@ impl GuiHandler {
|
|||
._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() {
|
||||
path.set_prefix(&self.resource_base_path.full_path());
|
||||
}
|
||||
|
||||
if self.internal_textures.read().unwrap().contains_key(&path) {
|
||||
Ok(self.internal_textures.read().unwrap()[&path]
|
||||
._descriptor_set
|
||||
.clone())
|
||||
Ok(self.internal_textures.read().unwrap()[&path].clone())
|
||||
} else {
|
||||
let texture = Image::from_file(path.clone())?
|
||||
.format(VK_FORMAT_R8G8B8A8_UNORM)
|
||||
.attach_sampler(Sampler::nearest_sampler().build(&self.device)?)
|
||||
.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
|
||||
.write()
|
||||
.unwrap()
|
||||
.insert(path.clone(), displayable_texture);
|
||||
.insert(path.clone(), texture.clone());
|
||||
|
||||
Ok(self.internal_textures.read().unwrap()[&path]
|
||||
._descriptor_set
|
||||
.clone())
|
||||
Ok(texture.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue