this is a week or so worth of brainstorming. Looking at pulling everything sprite related into it's own little struct. And also doing a message everything arch

This commit is contained in:
2020-09-14 21:27:00 -07:00
parent a42d23e5f9
commit 369a305817
13 changed files with 242 additions and 188 deletions

View File

@@ -6,30 +6,34 @@ use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, Handle};
use vulkano::pipeline::vertex::Vertex;
use std::any::Any;
use crate::{VertexTypeContainer, Move, Geom};
use crate::{VertexTypeContainer};
use winit::event::Event;
use crate::util::tr_event::TrEvent;
use crate::util::tr_event::{TrEvent, TrUIEvent};
use crate::drawables::sprite::{Velocity, Geometry};
/// Trait which may be inherited by objects that wish to be drawn to the screen
pub trait Drawable {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
// Render expects the implementer to create custom render logic based on interior data within
// the struct. This data as of right now, will *only* be mutatable via events & update
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer>;
// Update simply passes the delta time. The implementor doesn't necessarily need to use delta_time
// or even add anything other than a Vec::new() to the function.
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>>;
// Notify is where custom events created in other parts of the system will be ingested. It
// might be a good idea in the future to have some of pre-function-call filtering so we
// don't have as many notifies that just immediately reject.
fn notify<Y, T>(&self, tr_event : Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>>;
}
/// Trait which may be inherited by objects that wish to receive events
pub trait Eventable<T> {
fn notify(&mut self, event: &TrEvent<T>) -> ();
}
/// Trait which may be inherited by objects that wish to be updated
pub trait Updatable {
fn update(&mut self, delta_time: f32) -> ();
}
/// Accumulator for Vectors of VertexTypes
#[derive(Default)]
@@ -54,8 +58,8 @@ impl CanvasFrame {
}
/// Push this drawable onto the back of the accumulator
pub fn draw(&mut self, drawable: &dyn Drawable, mv: Move, geom: Geom) {
for i in drawable.get(
pub fn draw(&mut self, drawable: &dyn Drawable, mv: Velocity, geom: Geometry) {
for i in drawable.render(
self.window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,

View File

@@ -4,7 +4,7 @@ use crate::canvas::managed::handles::{CompuKernelHandle};
use crate::drawables::compu_sprite::CompuSprite;
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::VertexTypeContainer;
use crate::{Move, Geom};
use crate::drawables::sprite::{Velocity, Geometry};
#[derive(Default)]
pub struct CompuFrame {
@@ -58,10 +58,10 @@ impl CompuFrame {
buffer: Arc<CompuBufferHandle>,
kernel: Arc<CompuKernelHandle>,
sprite: &CompuSprite,
mv: Move,
geom: Geom,
mv: Velocity,
geom: Geometry,
) {
let compu_sprites = sprite.get(
let compu_sprites = sprite.render(
self.window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,

View File

@@ -2,6 +2,7 @@ use std::sync::Arc;
use crate::canvas::managed::handles::{CanvasImageHandle, CanvasTextureHandle};
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::{VertexTypeContainer, ImageVertex3D};
use crate::util::tr_event::{TrUIEvent, TrEvent};
pub struct CompuSprite {
@@ -53,13 +54,21 @@ impl CompuSprite {
}
impl Drawable for CompuSprite {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
Vec::new()
}
}

View File

@@ -4,6 +4,7 @@ use crate::canvas::managed::handles::{CanvasFontHandle, CanvasImageHandle, Canva
use crate::canvas::canvas_frame::{Drawable};
use crate::util::vertex::{VertexTypeContainer, TextureVertex3D, Vertex3D, ColorVertex3D};
use crate::drawables::sprite::Sprite;
use crate::util::tr_event::{TrUIEvent, TrEvent};
/// Convex multi verticy polygon
#[derive(Debug, Clone)]
@@ -61,16 +62,23 @@ impl Polygon {
}
}
impl Drawable for Polygon {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
Vec::new()
}
}

View File

@@ -1,5 +1,6 @@
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::{VertexTypeContainer, ColorVertex3D};
use crate::util::tr_event::{TrUIEvent, TrEvent};
///
#[derive(Debug, Clone)]
@@ -73,12 +74,12 @@ impl Rect {
}
impl Drawable for Rect {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![
VertexTypeContainer::ColorType(
@@ -86,4 +87,12 @@ impl Drawable for Rect {
)
]
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
Vec::new()
}
}

View File

@@ -2,11 +2,11 @@ use std::collections::HashSet;
use winit::event::{Event, ElementState, MouseButton};
use crate::canvas::canvas_frame::{Drawable, Eventable};
use crate::canvas::canvas_frame::{Drawable};
use crate::drawables::rect::Rect;
use crate::drawables::sprite::Sprite;
use crate::util::vertex::VertexTypeContainer;
use crate::util::tr_event::{TrEvent, TrWindowEvent};
use crate::util::tr_event::{TrEvent, TrWindowEvent, TrUIEvent};
#[derive(Debug, Clone)]
pub struct Slider {
@@ -67,14 +67,14 @@ impl Slider {
}
impl Drawable for Slider {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
let mut vertices = self.handle.get(
let mut vertices = self.handle.render(
window_size,
position,
rotation,
@@ -84,30 +84,32 @@ impl Drawable for Slider {
vertices.extend_from_slice(
self.guide.iter()
.map(|x| x.get(window_size,
position,
rotation,
size,
depth,
.map(|x| x.render(window_size,
position,
rotation,
size,
depth,
)).flatten()
.collect::<Vec<VertexTypeContainer>>()
.as_slice()
);
vertices.extend_from_slice(
self.guide[0].get(window_size,
position,
rotation,
size,
depth,
self.guide[0].render(window_size,
position,
rotation,
size,
depth,
).as_slice());
vertices
}
}
impl<T> Eventable<T> for Slider {
fn notify(&mut self, event: &TrEvent<T>) -> () {
match event {
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
match tr_event {
TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
@@ -124,6 +126,6 @@ impl<T> Eventable<T> for Slider {
}
_ => {}
}
Vec::new()
}
}

View File

@@ -1,15 +1,31 @@
use std::sync::Arc;
use crate::canvas::*;
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasImageHandle, CanvasTextureHandle, Handle};
use crate::canvas::canvas_frame::{Drawable, Eventable, Updatable};
use crate::canvas::canvas_frame::{Drawable};
use crate::util::vertex::{VertexTypeContainer, TextureVertex3D, Vertex3D};
use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent};
use crate::util::tr_event::{TrEvent, TrWindowEvent};
use crate::util::tr_event::{TrEvent, TrWindowEvent, TrUIEvent};
pub struct Geometry {
pos_x: f32,
pos_y: f32,
size_x: f32,
size_y: f32,
rotation: f32,
depth: f32,
}
pub struct Velocity {
vel_x: f32,
vel_y: f32,
vel_r: f32,
}
///
#[derive(Debug, Clone)]
pub struct Sprite {
texture_handle: Arc<CanvasTextureHandle>,
geometry: Geometry,
velocity: Velocity,
}
/// Container class which implements drawable.
@@ -62,18 +78,31 @@ impl Sprite {
pub fn new(texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
Sprite {
texture_handle: texture_handle.clone(),
geometry: Geometry {
pos_x: 0.0,
pos_y: 0.0,
size_x: 0.0,
size_y: 0.0,
rotation: 0.0,
depth: 0.0
},
velocity: Velocity {
vel_x: 0.0,
vel_y: 0.0,
vel_r: 0.0
}
}
}
}
impl Drawable for Sprite {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
let normalized_depth = (depth / 255.0);
@@ -83,11 +112,13 @@ impl Drawable for Sprite {
self.texture_handle.clone())
]
}
}
impl<T> Eventable<T> for Sprite {
fn notify(&mut self, event: &TrEvent<T>) -> () {
match event {
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
match tr_event {
TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
match button {
MouseButton::Left => {
@@ -100,9 +131,6 @@ impl<T> Eventable<T> for Sprite {
}
_ => {}
}
Vec::new()
}
}
impl Updatable for Sprite {
fn update(&mut self, delta_time: f32) -> () {}
}

View File

@@ -1,5 +1,6 @@
use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::{VertexTypeContainer, ColorVertex3D};
use crate::util::tr_event::{TrUIEvent, TrEvent};
///
#[derive(Debug, Clone)]
@@ -137,13 +138,21 @@ impl Text {
}
impl Drawable for Text {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
fn notify<Y, T>(&self, tr_event: Vec<TrEvent<Y>>, ui_events: Vec<TrUIEvent<T>>) -> Vec<TrUIEvent<T>> {
Vec::new()
}
}

View File

@@ -25,7 +25,7 @@ use winit::event_loop::{ControlFlow, EventLoop, EventLoopProxy};
use winit::platform::unix::WindowBuilderExtUnix;
use winit::window::{WindowBuilder, Window};
use crate::canvas::canvas_frame::{CanvasFrame, Drawable, Eventable, Updatable};
use crate::canvas::canvas_frame::{CanvasFrame, Drawable};
use crate::canvas::canvas_state::CanvasState;
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasTextureHandle, Handle};
use canvas::compu_frame::CompuFrame;
@@ -46,41 +46,16 @@ pub mod vkprocessor;
pub mod drawables;
pub mod canvas;
extern crate specs;
use specs::prelude::*;
use vulkano::swapchain::Surface;
//struct Draws(Box<dyn Drawable + Sync + Send>, Box<dyn Eventable<TrEventExtension> + Sync + Send>);
struct SSprite(Box<dyn Drawable + Sync + Send>);
impl Component for SSprite {
type Storage = VecStorage<Self>;
pub struct Render {
render_actor: Box<dyn Drawable + Sync + Send>,
}
pub struct Move {
vel_x: f32,
vel_y: f32,
}
impl Component for Move {
type Storage = VecStorage<Self>;
}
pub struct Geom {
pos_x: f32,
pos_y: f32,
size_x: f32,
size_y: f32,
rotation: f32,
depth: f32,
}
impl Component for Geom {
impl Component for Render {
type Storage = VecStorage<Self>;
}
@@ -93,65 +68,23 @@ struct PersistentState {
compu_frame: CompuFrame,
}
// If I were to have multiple systems
/*
One for rendering
One for updating
One for eventing
Rendering is easy enough. It needs all the components necessary in order
to generate the vertices. This includes the position, size, and vertex generator
Updating can probably be multiple types, I imagine something that implemented an Updatable
trait could then be used.
So the big problem here is that I have two traits that I want to expose, BUT
I have to put the concrete value in both containers... I don't think this is something
that specs will like since it wants to be the only owner. No use in RefCell'ing it
because that's just stupid
What if I turn this on it's head and really embrace the systems. So for example I could have
the User system. Ooof this is a big question actually...
// Components that want to be updated
Move
// want to be drawn
Drawable
Geom
Notifyable
*/
struct RenderSystem;
impl<'a> System<'a> for RenderSystem {
type SystemData = (
WriteStorage<'a, Move>, // its velocity
WriteStorage<'a, Geom>, // its size, position & rotation
WriteStorage<'a, SSprite>, // generates the vertices
Write<'a, PersistentState>, // delta_time, window size, etc.
Write<'a, VkProcessor>, // Renderer
WriteStorage<'a, Render>, // generates the vertices
Write<'a, PersistentState>, // delta_time, window size, etc.
Write<'a, VkProcessor>, // Renderer
);
fn run(&mut self, (mut mv, mut geom, mut draw, mut state, mut vk_processor): Self::SystemData) {
fn run(&mut self, (mut mv, mut draw, mut state, mut vk_processor): Self::SystemData) {
state.canvas_frame = CanvasFrame::new(state.window_size);
state.compu_frame = CompuFrame::new(state.window_size);
// compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1);
// compu_frame.add(compute_buffer.clone(), compute_kernel.clone());
for (mv, geom, draw) in (&mut mv, &mut geom, &mut draw).join() {
for (mv, geom, draw) in (&mut mv, &mut draw).join() {
geom.pos_x += mv.vel_x * state.delta_time;
geom.pos_y += mv.vel_y * state.delta_time;
@@ -180,18 +113,18 @@ struct EventSystem;
impl<'a> System<'a> for EventSystem {
type SystemData = (
WriteStorage<'a, SSprite>,
WriteStorage<'a, Render>,
Write<'a, PersistentState>,
Write<'a, VkProcessor>,
Write<'a, Vec<TrEvent<TrEventExtension>>>
);
fn run(&mut self, (mut draw, mut state, mut vk_processor, event_stack): Self::SystemData) {
for draw_data in (&mut draw).join() {
for event in event_stack.iter() {
draw_data.1.notify(event)
}
}
// for draw_data in (&mut draw).join() {
// for event in event_stack.iter() {
// draw_data.0.notify(event)
// }
// }
}
}
@@ -263,9 +196,7 @@ pub fn main() {
processor.get_texture_handle(String::from("sfml.png")).unwrap();
let mut world = World::new();
world.register::<Move>();
world.register::<Geom>();
world.register::<SSprite>();
world.register::<Render>();
world.insert::<VkProcessor>(processor);
world.insert::<Vec<TrEvent<TrEventExtension>>>(Vec::new());
world.insert::<PersistentState>(PersistentState {
@@ -281,23 +212,13 @@ pub fn main() {
// An entity may or may not contain some component.
let t = world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0})
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing.clone(), thing.clone()))
.build();
world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing.clone(), thing))
.with(Render{ render_actor: thing })// just a drawable
.build();
let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000));
world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0, pos_x: 100.0, pos_y: 400.0 })
.with(SSprite(thing2.clone(), thing2))
.with(Render{ render_actor: thing2 })// just a drawable
.build();
@@ -352,7 +273,7 @@ pub fn main() {
world.write_resource::<PersistentState>()
.window_size = surface.window().inner_size().into();
} else {
// println!("{}", world.write_resource::<Vec<TrEvent<TrEventExtension>>>().len());
// println!("{}", world.write_resource::<Vec<TrEvent<TrEventExtension>>>().len());
world.write_resource::<Vec<TrEvent<TrEventExtension>>>().clear();
}
}
@@ -362,8 +283,7 @@ pub fn main() {
Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
match button {
MouseButton::Left => {
if state == ElementState::Pressed {
}
if state == ElementState::Pressed {}
}
_ => {}
}

View File

@@ -5,6 +5,11 @@ use winit::dpi::{PhysicalPosition, PhysicalSize};
use gilrs::Event as GilEvent;
use vulkano::pipeline::shader::GeometryShaderExecutionMode::TrianglesWithAdjacency;
#[derive(Clone)]
pub enum TrUIEvent<T> {
UIEvent(T)
}
#[derive(Clone)]
pub enum TrEventExtension {