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 crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, Handle};
use vulkano::pipeline::vertex::Vertex; use vulkano::pipeline::vertex::Vertex;
use std::any::Any; use std::any::Any;
use crate::VertexTypeContainer; use crate::{VertexTypeContainer, Move, Geom};
use winit::event::Event; use winit::event::Event;
/// Trait which may be inherited by objects that wish to be drawn to the screen /// Trait which may be inherited by objects that wish to be drawn to the screen
pub trait Drawable { 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 /// Trait which may be inherited by objects that wish to receive events
@ -32,7 +38,6 @@ pub struct CanvasFrame {
} }
impl CanvasFrame { impl CanvasFrame {
pub fn new(window_size: (u32, u32)) -> CanvasFrame { pub fn new(window_size: (u32, u32)) -> CanvasFrame {
CanvasFrame { CanvasFrame {
map: vec![], map: vec![],
@ -42,14 +47,20 @@ impl CanvasFrame {
/// Push this drawable onto the back of the accumulator /// Push this drawable onto the back of the accumulator
pub fn add(&mut self, drawable: Vec<VertexTypeContainer>) { pub fn add(&mut self, drawable: Vec<VertexTypeContainer>) {
for i in drawable{ for i in drawable {
self.map.push(i); self.map.push(i);
} }
} }
/// Push this drawable onto the back of the accumulator /// Push this drawable onto the back of the accumulator
pub fn draw(&mut self, drawable: &dyn Drawable) { pub fn draw(&mut self, drawable: &dyn Drawable, mv: Move, geom: Geom) {
for i in drawable.get(self.window_size) { 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); self.map.push(i);
} }
} }

@ -4,6 +4,7 @@ use crate::canvas::managed::handles::{CompuKernelHandle};
use crate::drawables::compu_sprite::CompuSprite; use crate::drawables::compu_sprite::CompuSprite;
use crate::canvas::canvas_frame::Drawable; use crate::canvas::canvas_frame::Drawable;
use crate::util::vertex::VertexTypeContainer; use crate::util::vertex::VertexTypeContainer;
use crate::{Move, Geom};
#[derive(Default)] #[derive(Default)]
pub struct CompuFrame { pub struct CompuFrame {
@ -56,15 +57,22 @@ impl CompuFrame {
pub fn add_with_image_swap(&mut self, pub fn add_with_image_swap(&mut self,
buffer: Arc<CompuBufferHandle>, buffer: Arc<CompuBufferHandle>,
kernel: Arc<CompuKernelHandle>, kernel: Arc<CompuKernelHandle>,
sprite: &CompuSprite) { sprite: &CompuSprite,
mv: Move,
let compu_sprites = sprite.get(self.window_size); 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 compu_sprites.len() == 1 {
if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() { if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() {
self.swapped_to_image.push((buffer, b.clone(), kernel)) self.swapped_to_image.push((buffer, b.clone(), kernel))
}; };
} }
} }
} }

@ -53,7 +53,13 @@ impl CompuSprite {
} }
impl Drawable for 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()] vec![self.verts.clone()]
} }
} }

@ -61,7 +61,13 @@ impl Polygon {
} }
} }
impl Drawable for 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()] vec![self.verts.clone()]
} }

@ -73,7 +73,13 @@ impl Rect {
} }
impl Drawable for 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![ vec![
VertexTypeContainer::ColorType( VertexTypeContainer::ColorType(
Rect::generate_vertices(window_size, self.position, self.size, self.depth, self.color) 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::drawables::sprite::Sprite;
use crate::util::vertex::VertexTypeContainer; use crate::util::vertex::VertexTypeContainer;
#[derive(Debug, Clone)]
pub struct Slider { pub struct Slider {
handle: Rect, handle: Rect,
guide: Vec<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 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 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 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); 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 { impl Drawable for Slider {
fn get(&self, window_size: (u32, u32)) -> Vec<VertexTypeContainer> { fn get(&self,
let mut vertices = self.handle.get(window_size).clone(); 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( vertices.extend_from_slice(
self.guide.iter() self.guide.iter()
.map(|x| x.get(window_size)) .map(|x| x.get(window_size,
.flatten() position,
rotation,
size,
depth,
)).flatten()
.collect::<Vec<VertexTypeContainer>>() .collect::<Vec<VertexTypeContainer>>()
.as_slice() .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 vertices
} }
} }

@ -8,16 +8,17 @@ use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent};
/// ///
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Sprite { pub struct Sprite {
pub position: (f32, f32),
pub size: (f32, f32),
depth: f32,
texture_handle: Arc<CanvasTextureHandle>, texture_handle: Arc<CanvasTextureHandle>,
} }
/// Container class which implements drawable. /// Container class which implements drawable.
impl Sprite { 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 = ( let ss_position = (
position.0 / window_size.0 as f32 - 1.0, position.0 / window_size.0 as f32 - 1.0,
position.1 / window_size.1 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), pub fn new(texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
size: (f32, f32),
depth: u32,
texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
let normalized_depth = (depth as f32 / 255.0);
Sprite { Sprite {
position: position,
size: size,
depth: normalized_depth,
texture_handle: texture_handle.clone(), texture_handle: texture_handle.clone(),
} }
} }
} }
impl Drawable for Sprite { 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![ vec![
VertexTypeContainer::TextureType( 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()) self.texture_handle.clone())
] ]
} }
@ -91,7 +91,7 @@ impl<T> Eventable<T> for Sprite {
match button { match button {
MouseButton::Left => { MouseButton::Left => {
if *state == ElementState::Pressed { 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 { 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 { 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()] vec![self.verts.clone()]
} }
} }

@ -53,27 +53,31 @@ use specs::prelude::*;
use vulkano::swapchain::Surface; use vulkano::swapchain::Surface;
struct Draws(Sprite); struct Draws(Box<dyn Drawable + Sync + Send>, Box<dyn Eventable<TrEvent> + Sync + Send>);
impl Component for Draws { impl Component for Draws {
type Storage = VecStorage<Self>; type Storage = VecStorage<Self>;
} }
struct Vel { pub struct Move {
x: f32, vel_x: f32,
y: f32, vel_y: f32,
pos_x: f32,
pos_y: f32,
} }
impl Component for Vel { impl Component for Move {
type Storage = VecStorage<Self>; type Storage = VecStorage<Self>;
} }
struct Pos { pub struct Geom {
x: f32, size_x: f32,
y: f32 size_y: f32,
rotation: f32,
depth: f32,
} }
impl Component for Pos { impl Component for Geom {
type Storage = VecStorage<Self>; type Storage = VecStorage<Self>;
} }
@ -91,34 +95,37 @@ struct RenderSystem;
impl<'a> System<'a> for RenderSystem { impl<'a> System<'a> for RenderSystem {
type SystemData = ( type SystemData = (
WriteStorage<'a, Pos>, WriteStorage<'a, Move>,
WriteStorage<'a, Vel>, WriteStorage<'a, Geom>,
WriteStorage<'a, Draws>, WriteStorage<'a, Draws>,
Write<'a, PersistentState>, Write<'a, PersistentState>,
Write<'a, VkProcessor>, 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.canvas_frame = CanvasFrame::new(state.window_size);
state.compu_frame = CompuFrame::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_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1);
// compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); // compu_frame.add(compute_buffer.clone(), compute_kernel.clone());
for (mv, geom, draw) in (&mut mv, &mut geom, &mut draw).join() {
mv.pos_x += mv.vel_x * state.delta_time;
for (vel, pos, draw) in (&vel, &mut pos, &mut draw).join() { mv.pos_y += mv.vel_y * state.delta_time;
pos.x += vel.x * state.delta_time;
pos.y += vel.y * state.delta_time; let window_size = state.window_size.clone();
state.canvas_frame.add(draw.0.get(
draw.0.position = (pos.x, pos.y); window_size,
(mv.pos_x, mv.pos_y),
geom.rotation,
(geom.size_x, geom.size_y),
geom.depth,
));
} }
for draw_data in (&draw).join() { for draw_data in (&draw).join() {
let size = state.window_size.clone(); let size = state.window_size.clone();
state.canvas_frame.add(draw_data.0.get(size))
} }
vk_processor.run(&state.surface.clone().unwrap(), 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() { pub fn main() {
hprof::start_frame(); //hprof::start_frame();
//let g = hprof::enter("vulkan preload");
let q1 = hprof::enter("setup");
let instance = { let instance = {
let extensions = vulkano_win::required_extensions(); let extensions = vulkano_win::required_extensions();
@ -149,17 +174,12 @@ pub fn main() {
.build_vk_surface(&events_loop, instance.clone()).unwrap(); .build_vk_surface(&events_loop, instance.clone()).unwrap();
let mut processor = VkProcessor::new(instance.clone(), surface.clone()); let mut processor = VkProcessor::new(instance.clone(), surface.clone());
{
let g = hprof::enter("vulkan preload");
processor.create_swapchain(instance.clone(), surface.clone()); processor.create_swapchain(instance.clone(), surface.clone());
processor.preload_kernels(); processor.preload_kernels();
processor.preload_shaders(); processor.preload_shaders();
processor.preload_textures(); processor.preload_textures();
processor.preload_fonts(); processor.preload_fonts();
}
let q2 = hprof::enter("Game Objects");
let mut timer = Timer::new(); let mut timer = Timer::new();
let mut frame_future: Box<dyn GpuFuture> = 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_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_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 image_dimensions_u: (u32, u32) = image_data.1;
let compu_sprite1: CompuSprite = let compu_sprite1: CompuSprite =
CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f, CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f,
// Swap image to render the result to. Must match dimensions // Swap image to render the result to. Must match dimensions
processor.new_swap_image(image_dimensions_u)); processor.new_swap_image(image_dimensions_u));
// Need to
let compute_buffer: Arc<CompuBufferHandle> = let compute_buffer: Arc<CompuBufferHandle> =
processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4); 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(); processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap();
let sfml_handle: Arc<CanvasTextureHandle> = let sfml_handle: Arc<CanvasTextureHandle> =
processor.get_texture_handle(String::from("sfml.png")).unwrap(); 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(); let mut world = World::new();
world.register::<Pos>(); world.register::<Move>();
world.register::<Vel>(); world.register::<Geom>();
world.register::<Draws>(); world.register::<Draws>();
world.insert::<VkProcessor>(processor); world.insert::<VkProcessor>(processor);
world.insert::<PersistentState>(PersistentState { world.insert::<PersistentState>(PersistentState {
@ -225,31 +231,35 @@ pub fn main() {
compu_frame: CompuFrame::new((0, 0)), compu_frame: CompuFrame::new((0, 0)),
}); });
let thing = Box::new(Sprite::new(funky_handle.clone()));
// An entity may or may not contain some component. // An entity may or may not contain some component.
world.create_entity() world.create_entity()
.with(Vel { x: 0.0, y: 0.0 }) .with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 })
.with(Pos{ x: 0.0, y: 0.0 }) .with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 })
.with(Draws( .with(Draws(thing.clone(), thing.clone()))
Sprite::new(
(200.0, 200.0),
(100.0, 150.0), 10, funky_handle.clone())))
.build(); .build();
let mut dispatcher = DispatcherBuilder::new() world.create_entity()
// .with(SysA, "sys_a", &[]) .with(Move { vel_x: 0.0, vel_y: 0.0, pos_x: 100.0, pos_y: 400.0 })
.with(RenderSystem, "render_s", &[]).build(); .with(Geom { size_x: 100.0, size_y: 100.0, rotation: 0.0, depth: 1.0 })
.with(Draws(thing.clone(), thing))
.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);
let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000));
drop(q2); world.create_entity()
drop(q1); .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(); 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 is borrowed from the surface
events_loop.run(move |event, _, control_flow| { events_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll; *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 { match event {
Event::NewEvents(cause) => { Event::NewEvents(cause) => {
if cause == StartCause::Init { if cause == StartCause::Init {
world.write_resource::<PersistentState>() world.write_resource::<PersistentState>()
.window_size = surface.window().inner_size().into(); .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, .. } => { Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
*control_flow = ControlFlow::Exit *control_flow = ControlFlow::Exit
@ -334,7 +313,8 @@ pub fn main() {
Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => { Event::WindowEvent { event: WindowEvent::Resized(new_size), .. } => {
world.write_resource::<VkProcessor>() world.write_resource::<VkProcessor>()
.swapchain_recreate_needed = true; .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 {
event: WindowEvent::MouseInput { event: WindowEvent::MouseInput {
@ -368,6 +348,17 @@ pub fn main() {
} }
Event::MainEventsCleared => { 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 { // while (accumulator_time - step_size) >= step_size {
// accumulator_time -= step_size; // accumulator_time -= step_size;
@ -392,22 +383,12 @@ pub fn main() {
// } // }
}); });
drop(l);
hprof::end_frame(); // hprof::end_frame();
hprof::profiler().print_timing(); // 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