Skip to content

Commit 1236dfe

Browse files
authored
Adds Rect Deno Resouces (#4)
* arc mutex app state * kompletter rückbau * create react with resource id * create & append ops * update rect * std_lib * op_remove_rect * renamend op_remove_rect_from_window * renamed gpu mod to graphics * updating rects from js * lil cleanup * wip
1 parent 0f1b161 commit 1236dfe

File tree

6 files changed

+196
-68
lines changed

6 files changed

+196
-68
lines changed

src/app.rs

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,43 @@ use std::sync::Mutex;
44
use winit::application::ApplicationHandler;
55
use winit::event::WindowEvent;
66
use winit::event_loop::ActiveEventLoop;
7+
use winit::event_loop::EventLoopProxy;
78
use winit::window::Window;
89
use winit::window::WindowId;
910

10-
use crate::gpu::Gpu;
11-
use crate::gpu::Instance;
11+
use crate::graphics::Gpu;
12+
use crate::graphics::Instance;
13+
use crate::graphics::Rect;
1214

13-
#[derive(Debug, Clone, Copy)]
14-
pub enum JsEvents {
15-
AddRect(u32, u32, u32, u32),
15+
#[derive(Debug)]
16+
pub enum Js {
17+
RectsUpdated,
1618
}
1719

18-
#[derive(Copy, Clone, Debug)]
19-
pub struct Rect(u32, u32, u32, u32);
20-
2120
#[derive(Debug, Clone)]
2221
pub struct AppState {
23-
rects: Vec<Rect>,
22+
pub rects: Arc<Mutex<Vec<Arc<Mutex<Rect>>>>>,
23+
pub event_loop: Arc<Mutex<EventLoopProxy<Js>>>,
24+
}
25+
26+
impl AppState {
27+
pub fn new(event_loop: Arc<Mutex<EventLoopProxy<Js>>>) -> Self {
28+
Self {
29+
rects: Arc::new(Mutex::new(Vec::new())),
30+
event_loop,
31+
}
32+
}
2433
}
2534

2635
pub struct App<'window> {
2736
window: Option<Arc<Window>>,
2837
gpu: Option<Gpu<'window>>,
29-
state: Arc<Mutex<AppState>>,
38+
pub state: Arc<Mutex<AppState>>,
3039
}
3140

3241
impl App<'_> {
33-
pub fn new() -> Self {
34-
let state = Arc::new(Mutex::new(AppState { rects: Vec::new() }));
42+
pub fn new(event_loop: Arc<Mutex<EventLoopProxy<Js>>>) -> Self {
43+
let state = Arc::new(Mutex::new(AppState::new(event_loop)));
3544

3645
Self {
3746
window: None,
@@ -40,50 +49,52 @@ impl App<'_> {
4049
}
4150
}
4251

43-
pub fn add_rect(&mut self, x: u32, y: u32, w: u32, h: u32) {
44-
self.state.lock().unwrap().rects.push(Rect(x, y, w, h));
45-
self.sync_gpu_instance_buffer();
46-
47-
if let Some(window) = self.window.as_ref() {
48-
window.request_redraw();
49-
}
50-
}
51-
5252
fn rects_to_instances(&self) -> Vec<Instance> {
5353
self.state
5454
.lock()
5555
.unwrap()
5656
.rects
57+
.lock()
58+
.unwrap()
5759
.iter()
58-
.map(|r| Instance::new(r.0 as f32, r.1 as f32, r.2 as f32, r.3 as f32))
60+
.map(|r| {
61+
let rect = r.lock().unwrap();
62+
Instance::new(rect.0 as f32, rect.1 as f32, rect.2 as f32, rect.3 as f32)
63+
})
5964
.collect()
6065
}
61-
62-
fn sync_gpu_instance_buffer(&mut self) {
63-
let instances = self.rects_to_instances();
64-
if let Some(gpu) = self.gpu.as_mut() {
65-
gpu.update_instance_buffer(&instances);
66-
}
67-
}
6866
}
6967

70-
impl<'window> ApplicationHandler<JsEvents> for App<'window> {
68+
impl<'window> ApplicationHandler<Js> for App<'window> {
7169
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
7270
if self.window.is_none() {
7371
let window = Arc::new(
7472
event_loop
75-
.create_window(Window::default_attributes().with_title("wgpu winit example"))
73+
.create_window(
74+
Window::default_attributes()
75+
.with_position(winit::dpi::PhysicalPosition::new(100, 200))
76+
.with_title("wgpu winit example"),
77+
)
7678
.expect("create window err."),
7779
);
7880

7981
self.window = Some(window.clone());
80-
self.gpu = Some(Gpu::new(window.clone(), self.rects_to_instances()));
82+
self.gpu = Some(Gpu::new(window.clone()));
8183
}
8284
}
8385

84-
fn user_event(&mut self, _event_loop: &ActiveEventLoop, event: JsEvents) {
85-
let JsEvents::AddRect(x, y, w, h) = event;
86-
self.add_rect(x, y, w, h);
86+
fn user_event(&mut self, _event_loop: &ActiveEventLoop, event: Js) {
87+
match event {
88+
Js::RectsUpdated => {
89+
let instances = self.rects_to_instances();
90+
if let Some(gpu) = self.gpu.as_mut() {
91+
gpu.update_instance_buffer(&instances);
92+
}
93+
if let Some(window) = self.window.as_ref() {
94+
window.request_redraw();
95+
}
96+
}
97+
}
8798
}
8899

89100
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {

src/deno.rs

Lines changed: 109 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,141 @@
1-
use std::borrow::Cow;
21
use std::env::current_dir;
32
use std::rc::Rc;
43
use std::sync::Arc;
54
use std::sync::Mutex;
65
use std::thread;
76

87
use deno_core::error::AnyError;
8+
use deno_core::extension;
99
use deno_core::op2;
1010
use deno_core::resolve_path;
11-
use deno_core::Extension;
1211
use deno_core::FsModuleLoader;
1312
use deno_core::JsRuntime;
14-
use deno_core::OpDecl;
1513
use deno_core::OpState;
14+
use deno_core::Resource;
1615
use deno_core::RuntimeOptions;
1716

18-
use winit::event_loop::EventLoopProxy;
17+
use crate::app::AppState;
18+
use crate::app::Js;
19+
use crate::graphics::Rect;
1920

20-
use crate::JsEvents;
21+
struct RectResource(Arc<Mutex<Rect>>);
22+
impl Resource for RectResource {}
2123

2224
#[op2(fast)]
23-
fn op_add_rect(
25+
fn op_create_rect(
2426
state: &mut OpState,
2527
x: u32,
2628
y: u32,
2729
w: u32,
2830
h: u32,
31+
) -> Result<u32, deno_error::JsErrorBox> {
32+
let rect = Arc::new(Mutex::new(Rect(x, y, w, h)));
33+
34+
let resource_table = &mut state.resource_table;
35+
let rid = resource_table.add(RectResource(rect.clone()));
36+
37+
Ok(rid)
38+
}
39+
40+
#[op2(fast)]
41+
fn op_append_rect_to_window(state: &mut OpState, rid: u32) -> Result<(), deno_error::JsErrorBox> {
42+
let resource_table = &mut state.resource_table;
43+
let rect_resource = resource_table.get::<RectResource>(rid).unwrap();
44+
let rect = rect_resource.0.clone();
45+
46+
state
47+
.borrow::<Arc<Mutex<AppState>>>()
48+
.lock()
49+
.unwrap()
50+
.rects
51+
.lock()
52+
.unwrap()
53+
.push(rect.clone());
54+
55+
state
56+
.borrow::<Arc<Mutex<AppState>>>()
57+
.lock()
58+
.unwrap()
59+
.event_loop
60+
.lock()
61+
.unwrap()
62+
.send_event(Js::RectsUpdated)
63+
.unwrap();
64+
65+
Ok(())
66+
}
67+
68+
#[op2(fast)]
69+
fn op_update_rect(
70+
state: &mut OpState,
71+
rid: u32,
72+
x: u32,
73+
y: u32,
74+
w: u32,
75+
h: u32,
2976
) -> Result<(), deno_error::JsErrorBox> {
77+
let resource_table = &mut state.resource_table;
78+
let rect_resource = resource_table.get::<RectResource>(rid).unwrap();
79+
let rect = rect_resource.0.clone();
80+
81+
let mut rect = rect.lock().unwrap();
82+
rect.0 = x;
83+
rect.1 = y;
84+
rect.2 = w;
85+
rect.3 = h;
86+
87+
state
88+
.borrow::<Arc<Mutex<AppState>>>()
89+
.lock()
90+
.unwrap()
91+
.event_loop
92+
.lock()
93+
.unwrap()
94+
.send_event(Js::RectsUpdated)
95+
.unwrap();
96+
97+
Ok(())
98+
}
99+
100+
#[op2(fast)]
101+
fn op_remove_rect_from_window(state: &mut OpState, rid: u32) -> Result<(), deno_error::JsErrorBox> {
102+
let resource_table = &mut state.resource_table;
103+
let rect_resource = resource_table.take::<RectResource>(rid).unwrap();
104+
let rect = rect_resource.0.clone();
105+
30106
state
31-
.borrow::<Arc<Mutex<EventLoopProxy<JsEvents>>>>()
32-
.clone()
107+
.borrow::<Arc<Mutex<AppState>>>()
108+
.lock()
109+
.unwrap()
110+
.rects
33111
.lock()
34112
.unwrap()
35-
.send_event(JsEvents::AddRect(x, y, w, h))
113+
.retain(|item| !Arc::ptr_eq(item, &rect));
114+
115+
state
116+
.borrow::<Arc<Mutex<AppState>>>()
117+
.lock()
118+
.unwrap()
119+
.event_loop
120+
.lock()
121+
.unwrap()
122+
.send_event(Js::RectsUpdated)
36123
.unwrap();
37124

38125
Ok(())
39126
}
40127

41-
pub fn run_script(event_loop_proxy: Arc<Mutex<EventLoopProxy<JsEvents>>>, path: &str) {
42-
let proxy = event_loop_proxy.clone();
128+
extension!(
129+
rects,
130+
ops = [
131+
op_create_rect,
132+
op_append_rect_to_window,
133+
op_update_rect,
134+
op_remove_rect_from_window,
135+
]
136+
);
137+
138+
pub fn run_script(app_state: Arc<Mutex<AppState>>, path: &str) {
43139
let path = path.to_string();
44140

45141
let _handle = thread::spawn(move || {
@@ -49,20 +145,13 @@ pub fn run_script(event_loop_proxy: Arc<Mutex<EventLoopProxy<JsEvents>>>, path:
49145
.unwrap();
50146

51147
if let Err(error) = tokio_runtime.block_on(async {
52-
const DECL: OpDecl = op_add_rect();
53-
let ext = Extension {
54-
name: "add_rect_ext",
55-
ops: Cow::Borrowed(&[DECL]),
56-
..Default::default()
57-
};
58-
59148
let mut js_runtime = JsRuntime::new(RuntimeOptions {
60-
extensions: vec![ext],
149+
extensions: vec![rects::init_ops_and_esm()],
61150
module_loader: Some(Rc::new(FsModuleLoader)),
62151
..Default::default()
63152
});
64153

65-
js_runtime.op_state().borrow_mut().put(proxy);
154+
js_runtime.op_state().borrow_mut().put(app_state);
66155

67156
let main_module = resolve_path(&path, &current_dir().unwrap()).unwrap();
68157
let mod_id = js_runtime.load_main_es_module(&main_module).await?;

src/gpu.rs renamed to src/graphics.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use wgpu::MemoryHints::Performance;
99
use wgpu::ShaderSource;
1010
use winit::window::Window;
1111

12+
#[derive(Copy, Clone, Debug)]
13+
pub struct Rect(pub u32, pub u32, pub u32, pub u32);
14+
1215
#[repr(C)]
1316
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
1417
pub struct Instance {
@@ -40,11 +43,11 @@ pub struct Gpu<'window> {
4043
}
4144

4245
impl<'window> Gpu<'window> {
43-
pub fn new(window: Arc<Window>, instances: Vec<Instance>) -> Gpu<'window> {
44-
pollster::block_on(Gpu::new_async(window, instances))
46+
pub fn new(window: Arc<Window>) -> Gpu<'window> {
47+
pollster::block_on(Gpu::new_async(window))
4548
}
4649

47-
pub async fn new_async(window: Arc<Window>, instances: Vec<Instance>) -> Gpu<'window> {
50+
pub async fn new_async(window: Arc<Window>) -> Gpu<'window> {
4851
/*
4952
* window
5053
*/
@@ -130,11 +133,14 @@ impl<'window> Gpu<'window> {
130133
* instances
131134
*/
132135

136+
let instances: Vec<Instance> = Vec::new();
137+
133138
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
134139
label: Some("Instance Buffer"),
135140
contents: cast_slice(&instances),
136141
usage: wgpu::BufferUsages::VERTEX,
137142
});
143+
138144
let instance_count = instances.len() as u32;
139145

140146
/*

src/main.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1-
for (let i = 0; i < 10; i++) {
2-
Deno.core.ops.op_add_rect(100 + i * 100, 100 + i * 70, 250, 250);
3-
}
1+
import { console, setTimeout, setInterval } from "./std.js";
2+
3+
const create_rect = Deno.core.ops.op_create_rect;
4+
const update_rect = Deno.core.ops.op_update_rect;
5+
const append_rect_to_window = Deno.core.ops.op_append_rect_to_window;
6+
const op_remove_rect = Deno.core.ops.op_remove_rect;
7+
8+
const id = create_rect(100, 100, 200, 200);
9+
append_rect_to_window(id);
10+
11+
console.log(`Added rect with id: ${id}`);
12+
13+
setTimeout(() => {
14+
update_rect(id, 100, 100, 600, 600);
15+
}, 500);

src/main.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ use winit::error::EventLoopError;
55
use winit::event_loop::EventLoop;
66

77
use crate::app::App;
8-
use crate::app::JsEvents;
8+
use crate::app::Js;
99
use crate::deno::run_script;
1010

1111
mod app;
1212
mod deno;
13-
mod gpu;
13+
mod graphics;
1414

1515
fn main() -> Result<(), EventLoopError> {
16-
let mut app = App::new();
16+
let event_loop = EventLoop::<Js>::with_user_event().build()?;
17+
let event_loop_proxy = Arc::new(Mutex::new(event_loop.create_proxy()));
18+
let mut app = App::new(event_loop_proxy);
1719

18-
let event_loop = EventLoop::<JsEvents>::with_user_event().build()?;
19-
let proxy = Arc::new(Mutex::new(event_loop.create_proxy()));
20-
21-
run_script(proxy, "src/main.js");
20+
run_script(app.state.clone(), "src/main.js");
2221

2322
event_loop.run_app(&mut app)
2423
}

0 commit comments

Comments
 (0)