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

a-star
mitchellhansen 4 years ago
parent a42d23e5f9
commit 369a305817

@ -31,3 +31,23 @@ So for a sprite, which is a generic texture and position/size combo
Images are similar, but instead of a "sprite" I made a computsprite because that's the only thing that uses them.
Now if I had to shove these into a component / a set of components... I could have a component of the vertex type even?
===== Sep 2020 =====
Lets think about this for a minute...
* We have components which are purely data...
* But can also have structs that impl functionality
* The data can be contained within traits. But it has to do all IO through the trait interface. ALL
* Problem, for example I have primitives like textured sprites, and also complex widgets which also have additional IO they they need. Like text input or buttons. I suppose This could all be made message based. So when the text input receives a focus, and then key presses it would update. When the enter key is pressed it could create a customer event for which another component is the listener...
* Maybe this is the way to go... Have some generic structure that has a render(params), notify(event), update(delta) -> VEvent
* So if I had a textbox sprite it could notify(key events) render
* We can split up components in order to have sharable sets of data for shared functionality. e.g rendering
[[paste]]
So that article more or less talked about what I was thinking with the ECS. But they didn't really go into the separation of components.

@ -0,0 +1,40 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2020-09-09T22:41:18-07:00
====== paste ======
Created Wednesday 09 September 2020
// 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
*/

File diff suppressed because one or more lines are too long

@ -6,31 +6,35 @@ 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,
// 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>;
}
/// Trait which may be inherited by objects that wish to receive events
pub trait Eventable<T> {
fn notify(&mut self, event: &TrEvent<T>) -> ();
}
// 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>>;
/// Trait which may be inherited by objects that wish to be updated
pub trait Updatable {
fn update(&mut self, delta_time: f32) -> ();
// 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>>;
}
/// Accumulator for Vectors of VertexTypes
#[derive(Default)]
pub struct CanvasFrame {
@ -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,

@ -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,

@ -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,7 +54,7 @@ impl CompuSprite {
}
impl Drawable for CompuSprite {
fn get(&self,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
@ -62,4 +63,12 @@ impl Drawable for CompuSprite {
) -> 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()
}
}

@ -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,7 +62,7 @@ impl Polygon {
}
}
impl Drawable for Polygon {
fn get(&self,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
@ -71,6 +72,13 @@ impl Drawable for Polygon {
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()
}
}

@ -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,7 +74,7 @@ impl Rect {
}
impl Drawable for Rect {
fn get(&self,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
@ -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()
}
}

@ -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,
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,7 +84,7 @@ impl Drawable for Slider {
vertices.extend_from_slice(
self.guide.iter()
.map(|x| x.get(window_size,
.map(|x| x.render(window_size,
position,
rotation,
size,
@ -95,7 +95,7 @@ impl Drawable for Slider {
);
vertices.extend_from_slice(
self.guide[0].get(window_size,
self.guide[0].render(window_size,
position,
rotation,
size,
@ -103,11 +103,13 @@ impl Drawable for Slider {
).as_slice());
vertices
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
impl<T> Eventable<T> for Slider {
fn notify(&mut self, event: &TrEvent<T>) -> () {
match event {
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()
}
}

@ -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,13 +78,26 @@ 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,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
@ -83,11 +112,13 @@ impl Drawable for Sprite {
self.texture_handle.clone())
]
}
fn update<T>(&self, delta_time: f32) -> Vec<TrUIEvent<T>> {
Vec::new()
}
impl<T> Eventable<T> for Sprite {
fn notify(&mut self, event: &TrEvent<T>) -> () {
match event {
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) -> () {}
}

@ -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,7 +138,7 @@ impl Text {
}
impl Drawable for Text {
fn get(&self,
fn render(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
@ -146,4 +147,12 @@ impl Drawable for Text {
) -> 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()
}
}

@ -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 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,
pub struct Render {
render_actor: Box<dyn Drawable + Sync + Send>,
}
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
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();
@ -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 {}
}
_ => {}
}

@ -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 {

Loading…
Cancel
Save