event system needs some thinkin

a-star
mitchellhansen 4 years ago
parent 9eed836083
commit 2e33c9c75e

@ -6,12 +6,18 @@ 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;
use crate::{VertexTypeContainer, Move, Geom};
use winit::event::Event;
/// 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)) -> Vec<VertexTypeContainer>;
fn get(&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
@ -32,7 +38,6 @@ pub struct CanvasFrame {
}
impl CanvasFrame {
pub fn new(window_size: (u32, u32)) -> CanvasFrame {
CanvasFrame {
map: vec![],
@ -42,14 +47,20 @@ impl CanvasFrame {
/// Push this drawable onto the back of the accumulator
pub fn add(&mut self, drawable: Vec<VertexTypeContainer>) {
for i in drawable{
for i in drawable {
self.map.push(i);
}
}
/// Push this drawable onto the back of the accumulator
pub fn draw(&mut self, drawable: &dyn Drawable) {
for i in drawable.get(self.window_size) {
pub fn draw(&mut self, drawable: &dyn Drawable, mv: Move, geom: Geom) {
for i in drawable.get(
self.window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,
(geom.size_x, geom.size_y),
geom.depth
) {
self.map.push(i);
}
}

@ -4,6 +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};
#[derive(Default)]
pub struct CompuFrame {
@ -56,15 +57,22 @@ impl CompuFrame {
pub fn add_with_image_swap(&mut self,
buffer: Arc<CompuBufferHandle>,
kernel: Arc<CompuKernelHandle>,
sprite: &CompuSprite) {
let compu_sprites = sprite.get(self.window_size);
sprite: &CompuSprite,
mv: Move,
geom: Geom,
) {
let compu_sprites = sprite.get(
self.window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,
(geom.size_x, geom.size_y),
geom.depth,
);
if compu_sprites.len() == 1 {
if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() {
self.swapped_to_image.push((buffer, b.clone(), kernel))
};
}
}
}

@ -53,7 +53,13 @@ impl CompuSprite {
}
impl Drawable for CompuSprite {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
}

@ -61,7 +61,13 @@ impl Polygon {
}
}
impl Drawable for Polygon {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}

@ -73,7 +73,13 @@ impl Rect {
}
impl Drawable for Rect {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![
VertexTypeContainer::ColorType(
Rect::generate_vertices(window_size, self.position, self.size, self.depth, self.color)

@ -7,6 +7,7 @@ use crate::drawables::rect::Rect;
use crate::drawables::sprite::Sprite;
use crate::util::vertex::VertexTypeContainer;
#[derive(Debug, Clone)]
pub struct Slider {
handle: Rect,
guide: Vec<Rect>,
@ -28,7 +29,7 @@ impl Slider {
let left_guide_bar = Rect::new((position.0, position.1), (2.0, size.1), 1, red);
let right_guide_bar = Rect::new((position.0 + size.0, position.1), (2.0, size.1), 1, blue);
let line = Rect::new((position.0, position.1 - (size.1 / 2.0) ), (size.0, 2.0), 1, green);
let line = Rect::new((position.0, position.1 - (size.1 / 2.0)), (size.0, 2.0), 1, green);
let scale = value as f32 / u16::max_value() as f32;
let handle = Rect::new((position.0 + (size.0 * scale), position.1), (15.0, size.1), 1, rg);
@ -45,18 +46,40 @@ impl Slider {
}
impl Drawable for Slider {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
let mut vertices = self.handle.get(window_size).clone();
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
let mut vertices = self.handle.get(
window_size,
position,
rotation,
size,
depth,
).clone();
vertices.extend_from_slice(
self.guide.iter()
.map(|x| x.get(window_size))
.flatten()
.map(|x| x.get(window_size,
position,
rotation,
size,
depth,
)).flatten()
.collect::<Vec<VertexTypeContainer>>()
.as_slice()
);
vertices.extend_from_slice(self.guide[0].get(window_size).as_slice());
vertices.extend_from_slice(
self.guide[0].get(window_size,
position,
rotation,
size,
depth,
).as_slice());
vertices
}
}

@ -8,16 +8,17 @@ use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent};
///
#[derive(Debug, Clone)]
pub struct Sprite {
pub position: (f32, f32),
pub size: (f32, f32),
depth: f32,
texture_handle: Arc<CanvasTextureHandle>,
}
/// Container class which implements drawable.
impl Sprite {
fn generate_verts(window_size: (u32, u32), position: (f32, f32), size: (f32, f32), depth: f32) -> Vec<TextureVertex3D> {
fn generate_verts(
window_size: (u32, u32),
position: (f32, f32),
size: (f32, f32),
depth: f32,
) -> Vec<TextureVertex3D> {
let ss_position = (
position.0 / window_size.0 as f32 - 1.0,
position.1 / window_size.1 as f32 - 1.0
@ -57,28 +58,27 @@ impl Sprite {
}
///
pub fn new(position: (f32, f32),
size: (f32, f32),
depth: u32,
texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
let normalized_depth = (depth as f32 / 255.0);
pub fn new(texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
Sprite {
position: position,
size: size,
depth: normalized_depth,
texture_handle: texture_handle.clone(),
}
}
}
impl Drawable for Sprite {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
let normalized_depth = (depth / 255.0);
vec![
VertexTypeContainer::TextureType(
Sprite::generate_verts(window_size, self.position, self.size, self.depth),
Sprite::generate_verts(window_size, position, size, normalized_depth),
self.texture_handle.clone())
]
}
@ -91,7 +91,7 @@ impl<T> Eventable<T> for Sprite {
match button {
MouseButton::Left => {
if *state == ElementState::Pressed {
self.position = (self.position.0, self.position.1 + 0.1);
}
}
_ => {}
@ -103,7 +103,5 @@ impl<T> Eventable<T> for Sprite {
}
impl Updatable for Sprite {
fn update(&mut self, delta_time: f32) -> () {
}
fn update(&mut self, delta_time: f32) -> () {}
}

@ -137,7 +137,13 @@ impl Text {
}
impl Drawable for Text {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> {
fn get(&self,
window_size: (u32, u32),
position: (f32, f32),
rotation: f32,
size: (f32, f32),
depth: f32,
) -> Vec<VertexTypeContainer> {
vec![self.verts.clone()]
}
}

@ -53,27 +53,31 @@ use specs::prelude::*;
use vulkano::swapchain::Surface;
struct Draws(Sprite);
struct Draws(Box<dyn Drawable + Sync + Send>, Box<dyn Eventable<TrEvent> + Sync + Send>);
impl Component for Draws {
type Storage = VecStorage<Self>;
}
struct Vel {
x: f32,
y: f32,
pub struct Move {
vel_x: f32,
vel_y: f32,
pos_x: f32,
pos_y: f32,
}
impl Component for Vel {
impl Component for Move {
type Storage = VecStorage<Self>;
}
struct Pos {
x: f32,
y: f32
pub struct Geom {
size_x: f32,
size_y: f32,
rotation: f32,
depth: f32,
}
impl Component for Pos {
impl Component for Geom {
type Storage = VecStorage<Self>;
}
@ -91,34 +95,37 @@ struct RenderSystem;
impl<'a> System<'a> for RenderSystem {
type SystemData = (
WriteStorage<'a, Pos>,
WriteStorage<'a, Vel>,
WriteStorage<'a, Move>,
WriteStorage<'a, Geom>,
WriteStorage<'a, Draws>,
Write<'a, PersistentState>,
Write<'a, VkProcessor>,
);
fn run(&mut self, (mut pos, vel, mut draw, mut state, mut vk_processor): Self::SystemData) {
fn run(&mut self, (mut mv, mut geom, 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 (vel, pos, draw) in (&vel, &mut pos, &mut draw).join() {
pos.x += vel.x * state.delta_time;
pos.y += vel.y * state.delta_time;
draw.0.position = (pos.x, pos.y);
for (mv, geom, draw) in (&mut mv, &mut geom, &mut draw).join() {
mv.pos_x += mv.vel_x * state.delta_time;
mv.pos_y += mv.vel_y * state.delta_time;
let window_size = state.window_size.clone();
state.canvas_frame.add(draw.0.get(
window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,
(geom.size_x, geom.size_y),
geom.depth,
));
}
for draw_data in (&draw).join() {
let size = state.window_size.clone();
state.canvas_frame.add(draw_data.0.get(size))
}
vk_processor.run(&state.surface.clone().unwrap(),
@ -128,10 +135,28 @@ impl<'a> System<'a> for RenderSystem {
}
struct EventSystem;
impl<'a> System<'a> for EventSystem {
type SystemData = (
WriteStorage<'a, Draws>,
Write<'a, PersistentState>,
Write<'a, VkProcessor>,
);
fn run(&mut self, (mut draw, mut state, mut vk_processor): Self::SystemData) {
for draw_data in (&draw).join() {
draw_data.1.notify()
}
}
}
pub fn main() {
hprof::start_frame();
//hprof::start_frame();
//let g = hprof::enter("vulkan preload");
let q1 = hprof::enter("setup");
let instance = {
let extensions = vulkano_win::required_extensions();
@ -149,17 +174,12 @@ pub fn main() {
.build_vk_surface(&events_loop, instance.clone()).unwrap();
let mut processor = VkProcessor::new(instance.clone(), surface.clone());
processor.create_swapchain(instance.clone(), surface.clone());
processor.preload_kernels();
processor.preload_shaders();
processor.preload_textures();
processor.preload_fonts();
{
let g = hprof::enter("vulkan preload");
processor.create_swapchain(instance.clone(), surface.clone());
processor.preload_kernels();
processor.preload_shaders();
processor.preload_textures();
processor.preload_fonts();
}
let q2 = hprof::enter("Game Objects");
let mut timer = Timer::new();
let mut frame_future: Box<dyn GpuFuture> =
@ -175,12 +195,13 @@ pub fn main() {
let image_data = load_raw(String::from("ford2.jpg"));
let image_dimensions_f: (f32, f32) = ((image_data.1).clone().0 as f32, (image_data.1).clone().1 as f32);
let image_dimensions_u: (u32, u32) = image_data.1;
let compu_sprite1: CompuSprite =
CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f,
// Swap image to render the result to. Must match dimensions
processor.new_swap_image(image_dimensions_u));
// Need to
let compute_buffer: Arc<CompuBufferHandle> =
processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4);
@ -196,25 +217,10 @@ pub fn main() {
processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap();
let sfml_handle: Arc<CanvasTextureHandle> =
processor.get_texture_handle(String::from("sfml.png")).unwrap();
//let font_handle : Arc<CanvasFontHandle> =
// processor.get_font_handle(String::from("sansation.ttf")).unwrap();
// So I would have to go full in on the ECS in order to do rendering...
// That would probably look like a canvasFrame and compuFrame component which would
// be added to the world.
// Though canvasFrame and compuFrame have to share the command_buffer
// which means I should just keep the vk processor lol
// The `World` is our
// container for components
// and other resources.
let mut world = World::new();
world.register::<Pos>();
world.register::<Vel>();
world.register::<Move>();
world.register::<Geom>();
world.register::<Draws>();
world.insert::<VkProcessor>(processor);
world.insert::<PersistentState>(PersistentState {
@ -225,31 +231,35 @@ pub fn main() {
compu_frame: CompuFrame::new((0, 0)),
});
let thing = Box::new(Sprite::new(funky_handle.clone()));
// An entity may or may not contain some component.
world.create_entity()
.with(Vel { x: 0.0, y: 0.0 })
.with(Pos{ x: 0.0, y: 0.0 })
.with(Draws(
Sprite::new(
(200.0, 200.0),
(100.0, 150.0), 10, funky_handle.clone())))
.with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 })
.with(Draws(thing.clone(), thing.clone()))
.build();
let mut dispatcher = DispatcherBuilder::new()
// .with(SysA, "sys_a", &[])
.with(RenderSystem, "render_s", &[]).build();
let sfml_sprite = Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone());
let slider = Slider::new((300.0, 50.0), (550.0, 100.0), 30000);
world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 })
.with(Draws(thing.clone(), thing))
.build();
let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000));
drop(q2);
drop(q1);
world.create_entity()
.with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 })
.with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 })
.with(Draws(thing2.clone(), thing2))
.build();
let l = hprof::enter("Loop");
// call the run method for the following systems & deps
let mut dispatcher = DispatcherBuilder::new()
// .with(SysA, "sys_a", &[])
.with(RenderSystem, "render_s", &[]).build();
let event_loop_proxy = events_loop.create_proxy();
@ -286,47 +296,16 @@ pub fn main() {
});
// What would the component for a sprite be...
// Drawable with the vertex format in one rendering system
// position + velocity could then be two more in one system
// maybe some sort of input system
//
// let mut big_container = vec![
// Box::new(Slider::new((0.1, 0.1), (0.9, 0.9), 5000)),
// Box::new(Sprite::new((0.0, -0.5), (0.5, 0.5), 1, sfml_handle.clone())),
// ];
//container.push(Sprite::new((0.1)));
// Events loop is borrowed from the surface
events_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
// for eventable in &mut big_container {
// eventable.notify(&event);
// }
//
// for drawable in &mut big_container {
// canvas_frame.draw(&drawable);
// }
match event {
Event::NewEvents(cause) => {
if cause == StartCause::Init {
world.write_resource::<PersistentState>()
.window_size = surface.window().inner_size().into();
}
elapsed_time = timer.elap_time();
delta_time = elapsed_time - current_time;
current_time = elapsed_time;
if delta_time > 0.02 {
delta_time = 0.02;
}
accumulator_time += delta_time;
// This dispatches all the systems in parallel (but blocking).
world.write_resource::<PersistentState>().delta_time = delta_time;
dispatcher.dispatch(&mut world);
}
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
*control_flow = ControlFlow::Exit
@ -334,7 +313,8 @@ pub fn main() {
Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => {
world.write_resource::<VkProcessor>()
.swapchain_recreate_needed = true;
let size = (new_size.width, new_size.height);
world.write_resource::<PersistentState>()
.window_size = (new_size.width, new_size.height);
}
Event::WindowEvent {
event: WindowEvent::MouseInput {
@ -368,6 +348,17 @@ pub fn main() {
}
Event::MainEventsCleared => {
elapsed_time = timer.elap_time();
delta_time = elapsed_time - current_time;
current_time = elapsed_time;
if delta_time > 0.02 {
delta_time = 0.02;
}
accumulator_time += delta_time;
// This dispatches all the systems in parallel (but blocking).
world.write_resource::<PersistentState>().delta_time = delta_time;
dispatcher.dispatch(&mut world);
// while (accumulator_time - step_size) >= step_size {
// accumulator_time -= step_size;
@ -392,22 +383,12 @@ pub fn main() {
// }
});
drop(l);
hprof::end_frame();
hprof::profiler().print_timing();
// hprof::end_frame();
// hprof::profiler().print_timing();
}
pub fn click_test(event_loop_proxy: EventLoopProxy<TrEvent>, canvas_state: &CanvasState) {
// for i in canvas_state. {
// event_loop_proxy.send_event(TrEvent::MouseClickEvent {
// position: (0.0, 0.0),
// button: MouseButton::Left,
// }).ok();
// }
}

Loading…
Cancel
Save