use crate::util::vertex_3d::Vertex3D; use std::sync::Arc; use std::collections::HashMap; use std::hash::Hash; use crate::canvas::*; use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef; use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, Handle}; use crate::canvas::managed::shader::text_shader::GlyphInstance; use vulkano::pipeline::vertex::Vertex; use std::any::Any; // I don't think this is going to work without getting into Box'ing pub trait DrawableTest, H: Handle + DynHash> { fn get_vertices(&self) -> VTypes; fn get_handle(&self) -> H; } pub mod dynhash { use std::any::Any; use std::hash::{Hash, Hasher}; pub trait DynEq: Any { fn dyn_eq(&self, other: &dyn DynEq) -> bool; fn as_any(&self) -> &dyn Any; } pub trait DynHash: DynEq { fn dyn_hash(&self, hasher: &mut dyn Hasher); fn as_dyn_eq(&self) -> &dyn DynEq; } impl DynEq for H { fn dyn_eq(&self, other: &dyn DynEq) -> bool { if let Some(other) = other.as_any().downcast_ref::() { self == other } else { false } } fn as_any(&self) -> &dyn Any { self } } impl DynHash for H { fn dyn_hash(&self, mut hasher: &mut dyn Hasher) { H::hash(self, &mut hasher) } fn as_dyn_eq(&self) -> &dyn DynEq { self } } impl PartialEq for dyn DynHash { fn eq(&self, other: &dyn DynHash) -> bool { self.dyn_eq(other.as_dyn_eq()) } } impl Eq for dyn DynHash {} impl Hash for dyn DynHash { fn hash(&self, hasher: &mut H) { self.dyn_hash(hasher) } } } use crate::canvas::canvas_frame::dynhash::DynHash; use crate::VertexTypes; // CanvasFrameTest will be drawn to by objects implementing DrawableTest pub struct CanvasFrameTest { pub map: HashMap, VTypes>, } impl CanvasFrameTest { pub fn draw(&mut self, drawable: VTypes) { self.map.insert(Box::new(10), drawable); } } pub trait Drawable { fn get_vertices(&self) -> Vec<(f32, f32, f32)>; fn get_color(&self) -> (f32, f32, f32, f32); fn get_ti_coords(&self) -> Vec<(f32, f32)>; fn get_texture_handle(&self) -> Option>; fn get_image_handle(&self) -> Option>; // fn get_text_handle(&self) -> Option>; // These needs to return a vector of raw-ass data in addition to the definition for this data fn collect(&self) -> Vec { let color = self.get_color(); // self.get_vertices().iter().zip(self.get_ti_coords().iter()).map(|(a, b)| // Vertex3D { // v_position: [a.0, a.1, a.2], // color: [color.0, color.1, color.2, color.3], // ti_position: [b.0, b.1], // }).collect() // TODO vec![RuntimeVertexDef::from_primitive(0)] } } pub trait VertexDefinitionAndData {} pub struct CanvasFrame { pub colored_drawables: Vec, pub textured_drawables: HashMap, Vec>>, pub image_drawables: HashMap, Vec>>, pub text_drawables: HashMap, Vec>, } impl CanvasFrame { /// Creates a bare canvas frame with empty accumulators a pub fn new() -> CanvasFrame { CanvasFrame { colored_drawables: vec![], textured_drawables: Default::default(), image_drawables: Default::default(), text_drawables: Default::default(), } } // TODO: Fix this for text and fonts /// Accumulates the drawables collected Vertex2D's pub fn draw(&mut self, drawable: &dyn Drawable) { match drawable.get_texture_handle() { Some(handle) => { self.textured_drawables .entry(handle.clone()) .or_insert(Vec::new()) .push(drawable.collect()); } None => { match drawable.get_image_handle() { Some(handle) => { self.image_drawables .entry(handle.clone()) .or_insert(Vec::new()) .push(drawable.collect()); } None => { self.colored_drawables.extend(drawable.collect()); } } } } } }