mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Send Event to breakout main
This commit is contained in:
parent
5de57ef30a
commit
999dbfd9d1
5 changed files with 131 additions and 77 deletions
|
@ -5,7 +5,9 @@ app "breakout"
|
||||||
|
|
||||||
program = { render }
|
program = { render }
|
||||||
|
|
||||||
render = \state ->
|
render = \event ->
|
||||||
|
when event is
|
||||||
|
Resize size ->
|
||||||
numRows = 4
|
numRows = 4
|
||||||
numCols = 8
|
numCols = 8
|
||||||
numBlocks = numRows * numCols
|
numBlocks = numRows * numCols
|
||||||
|
@ -29,7 +31,7 @@ render = \state ->
|
||||||
|
|
||||||
{ row, col, color }
|
{ row, col, color }
|
||||||
|
|
||||||
blockWidth = state.width / numCols |> Result.withDefault 0
|
blockWidth = size.width / numCols |> Result.withDefault 0
|
||||||
blockHeight = 80
|
blockHeight = 80
|
||||||
|
|
||||||
rects =
|
rects =
|
||||||
|
@ -41,11 +43,14 @@ render = \state ->
|
||||||
|
|
||||||
paddle =
|
paddle =
|
||||||
color = { r: 0.8, g: 0.8, b: 0.8, a: 1.0 }
|
color = { r: 0.8, g: 0.8, b: 0.8, a: 1.0 }
|
||||||
width = state.width * 0.25
|
width = size.width * 0.25
|
||||||
height = blockHeight
|
height = blockHeight
|
||||||
left = (state.width * 0.5) - (width * 0.5)
|
left = (size.width * 0.5) - (width * 0.5)
|
||||||
top = state.height - (height * 2)
|
top = size.height - (height * 2)
|
||||||
|
|
||||||
Rect { left, top, width, height, color }
|
Rect { left, top, width, height, color }
|
||||||
|
|
||||||
List.append rects paddle
|
List.append rects paddle
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
[ Text "TODO handle other events than Resize!" ]
|
||||||
|
|
|
@ -9,8 +9,8 @@ Rgba : { r : F32, g : F32, b : F32, a : F32 }
|
||||||
|
|
||||||
Elem : [ Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text Str ]
|
Elem : [ Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text Str ]
|
||||||
|
|
||||||
State : { width : F32, height : F32 }
|
Event : [ Resize { width : F32, height : F32 }, KeyDown U32, KeyUp U32 ]
|
||||||
|
|
||||||
# TODO allow changing the window title - maybe via a Task, since that shouldn't happen all the time
|
# TODO allow changing the window title - maybe via a Task, since that shouldn't happen all the time
|
||||||
programForHost : { render : (State -> List Elem) as Render }
|
programForHost : { render : (Event -> List Elem) as Render }
|
||||||
programForHost = program
|
programForHost = program
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
text::build_glyph_brush,
|
text::build_glyph_brush,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
roc::{self, RocElem, RocElemTag},
|
roc::{self, Bounds, RocElem, RocElemTag, RocEvent},
|
||||||
};
|
};
|
||||||
use cgmath::{Vector2, Vector4};
|
use cgmath::{Vector2, Vector4};
|
||||||
use glyph_brush::{GlyphCruncher, OwnedSection};
|
use glyph_brush::{GlyphCruncher, OwnedSection};
|
||||||
|
@ -23,7 +23,7 @@ use wgpu_glyph::GlyphBrush;
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event,
|
event,
|
||||||
event::{Event, ModifiersState},
|
event::{ElementState, Event, ModifiersState},
|
||||||
event_loop::ControlFlow,
|
event_loop::ControlFlow,
|
||||||
platform::run_return::EventLoopExtRunReturn,
|
platform::run_return::EventLoopExtRunReturn,
|
||||||
};
|
};
|
||||||
|
@ -36,17 +36,17 @@ use winit::{
|
||||||
|
|
||||||
const TIME_BETWEEN_RENDERS: Duration = Duration::new(0, 1000 / 60);
|
const TIME_BETWEEN_RENDERS: Duration = Duration::new(0, 1000 / 60);
|
||||||
|
|
||||||
pub fn run_event_loop(title: &str, state: roc::State) -> Result<(), Box<dyn Error>> {
|
pub fn run_event_loop(title: &str, window_bounds: Bounds) -> Result<(), Box<dyn Error>> {
|
||||||
// Open window and create a surface
|
// Open window and create a surface
|
||||||
let mut event_loop = winit::event_loop::EventLoop::new();
|
let mut event_loop = winit::event_loop::EventLoop::new();
|
||||||
|
|
||||||
let window = winit::window::WindowBuilder::new()
|
let window = winit::window::WindowBuilder::new()
|
||||||
.with_inner_size(PhysicalSize::new(state.width, state.height))
|
.with_inner_size(PhysicalSize::new(window_bounds.width, window_bounds.height))
|
||||||
.with_title(title)
|
.with_title(title)
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut elems = roc::app_render(state);
|
let mut elems = roc::app_render(RocEvent::resize(window_bounds));
|
||||||
|
|
||||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||||
|
|
||||||
|
@ -150,10 +150,10 @@ pub fn run_event_loop(title: &str, state: roc::State) -> Result<(), Box<dyn Erro
|
||||||
&cmd_queue,
|
&cmd_queue,
|
||||||
);
|
);
|
||||||
|
|
||||||
elems = roc::app_render(roc::State {
|
elems = roc::app_render(RocEvent::resize(Bounds {
|
||||||
height: size.height as f32,
|
height: size.height as f32,
|
||||||
width: size.width as f32,
|
width: size.width as f32,
|
||||||
});
|
}));
|
||||||
|
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
|
@ -171,27 +171,14 @@ pub fn run_event_loop(title: &str, state: roc::State) -> Result<(), Box<dyn Erro
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
use event::ElementState::*;
|
let roc_event = match input_state {
|
||||||
use event::VirtualKeyCode::*;
|
ElementState::Pressed => RocEvent::key_down(keycode),
|
||||||
|
ElementState::Released => RocEvent::key_up(keycode),
|
||||||
match keycode {
|
|
||||||
Left => match input_state {
|
|
||||||
Pressed => println!("Left pressed!"),
|
|
||||||
Released => println!("Left released!"),
|
|
||||||
},
|
|
||||||
Right => match input_state {
|
|
||||||
Pressed => println!("Right pressed!"),
|
|
||||||
Released => println!("Right released!"),
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
println!("Other!");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
elems = roc::app_render(roc::State {
|
elems = roc::app_render(roc_event);
|
||||||
height: size.height as f32,
|
|
||||||
width: size.width as f32,
|
window.request_redraw();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
//Modifiers Changed
|
//Modifiers Changed
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -318,12 +305,6 @@ fn begin_render_pass<'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
|
||||||
pub struct Bounds {
|
|
||||||
pub height: f32,
|
|
||||||
pub width: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Drawable {
|
struct Drawable {
|
||||||
pos: Vector2<f32>,
|
pos: Vector2<f32>,
|
||||||
|
|
|
@ -4,12 +4,12 @@ mod roc;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_main() -> i32 {
|
pub extern "C" fn rust_main() -> i32 {
|
||||||
let state = roc::State {
|
let bounds = roc::Bounds {
|
||||||
width: 1900.0,
|
width: 1900.0,
|
||||||
height: 1000.0,
|
height: 1000.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
gui::run_event_loop("RocOut!", state).expect("Error running event loop");
|
gui::run_event_loop("RocOut!", bounds).expect("Error running event loop");
|
||||||
|
|
||||||
// Exit code
|
// Exit code
|
||||||
0
|
0
|
||||||
|
|
|
@ -7,13 +7,14 @@ use std::ffi::CStr;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
use winit::event::VirtualKeyCode;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "roc__programForHost_1_exposed_generic"]
|
#[link_name = "roc__programForHost_1_exposed_generic"]
|
||||||
fn roc_program() -> ();
|
fn roc_program() -> ();
|
||||||
|
|
||||||
#[link_name = "roc__programForHost_1_Render_caller"]
|
#[link_name = "roc__programForHost_1_Render_caller"]
|
||||||
fn call_Render(state: *const State, closure_data: *const u8, output: *mut RocList<RocElem>);
|
fn call_Render(event: *const RocEvent, closure_data: *const u8, output: *mut RocList<RocElem>);
|
||||||
|
|
||||||
#[link_name = "roc__programForHost_size"]
|
#[link_name = "roc__programForHost_size"]
|
||||||
fn roc_program_size() -> i64;
|
fn roc_program_size() -> i64;
|
||||||
|
@ -23,11 +24,71 @@ extern "C" {
|
||||||
fn size_Render() -> i64;
|
fn size_Render() -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct State {
|
pub union RocEventEntry {
|
||||||
pub height: f32,
|
pub key_down: winit::event::VirtualKeyCode,
|
||||||
pub width: f32,
|
pub key_up: winit::event::VirtualKeyCode,
|
||||||
|
pub resize: Bounds,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[allow(unused)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum RocEventTag {
|
||||||
|
KeyDown = 0,
|
||||||
|
KeyUp = 1,
|
||||||
|
Resize = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[cfg(target_pointer_width = "64")] // on a 64-bit system, the tag fits in this pointer's spare 3 bits
|
||||||
|
pub struct RocEvent {
|
||||||
|
entry: RocEventEntry,
|
||||||
|
tag: RocEventTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for RocEvent {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
use RocEventTag::*;
|
||||||
|
|
||||||
|
match self.tag() {
|
||||||
|
KeyDown => unsafe { self.entry().key_down }.fmt(f),
|
||||||
|
KeyUp => unsafe { self.entry().key_up }.fmt(f),
|
||||||
|
Resize => unsafe { self.entry().resize }.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RocEvent {
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
pub fn tag(&self) -> RocEventTag {
|
||||||
|
self.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entry(&self) -> &RocEventEntry {
|
||||||
|
&self.entry
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(size: Bounds) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: RocEventTag::Resize,
|
||||||
|
entry: RocEventEntry { resize: size },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_down(keycode: VirtualKeyCode) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: RocEventTag::KeyDown,
|
||||||
|
entry: RocEventEntry { key_down: keycode },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_up(keycode: VirtualKeyCode) -> Self {
|
||||||
|
Self {
|
||||||
|
tag: RocEventTag::KeyUp,
|
||||||
|
entry: RocEventEntry { key_up: keycode },
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -193,7 +254,7 @@ pub struct ButtonStyles {
|
||||||
pub text_color: Rgba,
|
pub text_color: Rgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app_render(state: State) -> RocList<RocElem> {
|
pub fn app_render(state: RocEvent) -> RocList<RocElem> {
|
||||||
let size = unsafe { roc_program_size() } as usize;
|
let size = unsafe { roc_program_size() } as usize;
|
||||||
let layout = Layout::array::<u8>(size).unwrap();
|
let layout = Layout::array::<u8>(size).unwrap();
|
||||||
|
|
||||||
|
@ -212,10 +273,17 @@ pub fn app_render(state: State) -> RocList<RocElem> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn call_the_closure(state: State, closure_data_ptr: *const u8) -> RocList<RocElem> {
|
unsafe fn call_the_closure(event: RocEvent, closure_data_ptr: *const u8) -> RocList<RocElem> {
|
||||||
let mut output = MaybeUninit::uninit();
|
let mut output = MaybeUninit::uninit();
|
||||||
|
|
||||||
call_Render(&state, closure_data_ptr as *const u8, output.as_mut_ptr());
|
call_Render(&event, closure_data_ptr as *const u8, output.as_mut_ptr());
|
||||||
|
|
||||||
output.assume_init()
|
output.assume_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Bounds {
|
||||||
|
pub height: f32,
|
||||||
|
pub width: f32,
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue