makepad_wasm_bridge/
wasm_types.rs

1use crate::from_wasm::*;
2use crate::to_wasm::*;
3use crate::{LiveId,live_id};
4use makepad_derive_wasm_bridge::*;
5pub struct WasmDataU8(Vec<u8>);
6
7impl WasmDataU8 {
8    pub fn new_and_release_ownership(capacity: usize) -> u32 {
9        let mut v = Vec::<u8>::new();
10        v.reserve_exact(capacity);
11        let mut v = std::mem::ManuallyDrop::new(v);
12        let ptr = v.as_mut_ptr();
13        let cap = v.capacity();
14        if cap != capacity {panic!()};
15        ptr as u32
16    }
17    
18    pub fn take_ownership(ptr:u32, len:u32, cap:u32)->Self{
19        unsafe {
20            Self(Vec::from_raw_parts(ptr as *mut u8, len as usize, cap as usize))
21        }
22    }
23    
24    pub fn from_vec_u8(v:Vec<u8>)->Self{
25        Self(v)
26    }
27    
28    pub fn into_vec_u8(self)->Vec<u8>{
29        self.0
30    }
31}
32
33impl ToWasm for WasmDataU8 {
34    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
35        
36        let ptr = inp.read_u32();
37        let len = inp.read_u32() as usize;
38        unsafe {
39            Self (Vec::from_raw_parts(ptr as *mut u8, len, len))
40        }
41    }
42    
43    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
44        out.push_ln(slot, &format!("this.push_data_u8({});", prop));
45    }
46    
47    fn u32_size() -> usize {2}
48}
49
50impl FromWasm for WasmDataU8 {
51    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
52        out.push_ln(slot, &format!("{} = {{ptr:app.u32[this.u32_offset++],len:app.u32[this.u32_offset++],capacity:app.u32[this.u32_offset++]}};", prop));
53    }
54    
55    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
56        let mut v = std::mem::ManuallyDrop::new(self.0);
57        out.push_u32(v.as_mut_ptr() as u32);
58        out.push_u32(v.len() as u32);
59        out.push_u32(v.capacity() as u32);
60    }
61}
62/*
63impl FromWasm for WasmDataU8 {
64    fn write_from_wasm(&self, out: &mut FromWasmMsg) {
65        let swap = Vec::new();
66        
67        let mut v = std::mem::ManuallyDrop::new(v);
68        let ptr = v.as_mut_ptr();
69        let cap = v.capacity();
70        
71        out.push_u32()
72        let ptr = inp.read_u32();
73        let len = inp.read_u32() as usize;
74        unsafe {
75            Self (Vec::from_raw_parts(ptr as *mut u8, len, len))
76        }
77    }
78    
79    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
80        out.push_ln(slot, &format!("this.push_data_u8({});", prop));
81    }
82    
83    fn u32_size() -> usize {2}
84}*/
85
86pub struct WasmPtrF32(u32);
87
88impl WasmPtrF32 {
89    pub fn new(ptr: *const f32) -> Self {
90        Self (ptr as u32)
91    }
92}
93
94impl FromWasm for WasmPtrF32 {
95    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
96        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
97    }
98    
99    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
100        out.push_u32(self.0)
101    }
102}
103
104
105#[derive(FromWasm)]
106pub struct WasmDataF32 {
107    pub ptr: WasmPtrF32,
108    pub len: usize
109}
110
111impl WasmDataF32 {
112    pub fn new(data:&[f32]) -> Self {
113        if !data.is_empty(){
114            Self{ptr:WasmPtrF32::new(data.as_ptr()), len:data.len()}
115        }
116        else{
117            Self{ptr:WasmPtrF32::new(std::ptr::null::<f32>()), len:0}
118        }
119    }
120}
121
122#[derive(FromWasm)]
123pub struct WasmDataU32 {
124    pub ptr: WasmPtrU32,
125    pub len: usize
126}
127
128impl WasmDataU32 {
129    pub fn new(data:&[u32]) -> Self {
130        if !data.is_empty(){
131            Self{ptr:WasmPtrU32::new(data.as_ptr()), len:data.len()}
132        }
133        else{
134            Self{ptr:WasmPtrU32::new(std::ptr::null::<u32>()), len:0}
135        }
136    }
137}
138
139
140pub struct WasmPtrU32(u32);
141
142impl WasmPtrU32 {
143    pub fn new(ptr: *const u32) -> Self {
144        Self (ptr as u32)
145    }
146}
147
148impl FromWasm for WasmPtrU32 {
149    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
150        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
151    }
152    
153    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
154        out.push_u32(self.0)
155    }
156}
157
158
159
160
161
162impl FromWasm for String {
163    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
164        out.push_ln(slot, &format!("{} = this.read_str();", prop));
165    }
166    
167    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
168        out.push_str(&self);
169    }
170}
171
172impl FromWasm for &str {
173    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
174        out.push_ln(slot, &format!("{} = this.read_str();", prop));
175    }
176    
177    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
178        out.push_str(self);
179    }
180}
181
182impl ToWasm for String {
183    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
184        inp.read_string()
185    }
186    
187    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
188        out.push_ln(slot, &format!("this.push_str({});", prop));
189    }
190    
191    fn u32_size() -> usize {1}
192}
193
194
195
196impl FromWasm for bool {
197    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
198        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++]!==0?true:false;", prop));
199    }
200    
201    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
202        out.push_u32(if self {1} else {0})
203    }
204}
205
206impl ToWasm for bool {
207    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
208        inp.read_u32() != 0
209    }
210    
211    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
212        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
213    }
214    fn u32_size() -> usize {1}
215}
216
217
218impl FromWasm for usize {
219    
220    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
221        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
222    }
223    
224    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
225        out.push_u32(self as u32)
226    }
227}
228
229impl ToWasm for usize {
230    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
231        inp.read_u32() as usize
232    }
233    
234    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
235        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
236    }
237    fn u32_size() -> usize {1}
238}
239
240
241
242impl FromWasm for u32 {
243    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
244        out.push_ln(slot, &format!("{} = app.u32[this.u32_offset++];", prop));
245    }
246    
247    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
248        out.push_u32(self)
249    }
250}
251
252impl ToWasm for u32 {
253    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
254        inp.read_u32()
255    }
256    
257    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
258        out.push_ln(slot, &format!("app.u32[this.u32_offset++] = {};", prop));
259    }
260    fn u32_size() -> usize {1}
261}
262
263
264
265
266impl FromWasm for f32 {
267    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
268        out.push_ln(slot, &format!("{} = app.f32[this.u32_offset++];", prop));
269    }
270    
271    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
272        out.push_f32(self)
273    }
274}
275
276impl ToWasm for f32 {
277    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
278        inp.read_f32()
279    }
280    
281    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
282        out.push_ln(slot, &format!("app.f32[this.u32_offset++] = {};", prop));
283    }
284    fn u32_size() -> usize {1}
285}
286
287
288
289
290impl FromWasm for f64 {
291    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
292        out.push_ln(slot, "this.u32_offset += this.u32_offset&1;");
293        out.push_ln(slot, &format!("{} = app.f64[this.u32_offset>>1];", prop));
294        out.push_ln(slot, "this.u32_offset += 2;");
295    }
296    
297    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
298        out.push_f64(self)
299    }
300}
301
302impl ToWasm for f64 {
303    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
304        inp.read_f64()
305    }
306    
307    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
308        out.push_ln(slot, "this.u32_offset += this.u32_offset&1;");
309        out.push_ln(slot, &format!("app.f64[this.u32_offset>>1] = {};", prop));
310        out.push_ln(slot, "this.u32_offset += 2;");
311    }
312    
313    fn u32_size() -> usize {3}
314}
315
316
317
318
319
320impl<T, const N: usize> FromWasm for [T; N] where T: FromWasm {
321    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
322        for item in self {
323            item.from_wasm_inner(out);
324        }
325    }
326    
327    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
328        out.push_ln(slot, &format!("if({0} === undefined) {0} = [];", prop));
329        out.push_ln(slot, &format!("let t{} = {};", temp, prop));
330        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < {1}; i{0}++){{", temp, N));
331        let new_temp = out.alloc_temp();
332        T::from_wasm_js_body(out, slot, is_recur, &format!("t{0}[i{0}]", temp), new_temp);
333        out.push_ln(slot, "}");
334    }
335}
336
337impl<T, const N: usize> ToWasm for [T; N] where T: ToWasm {
338    fn u32_size() -> usize {T::u32_size() * N}
339    
340    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
341        unsafe {
342            let mut to = std::mem::MaybeUninit::<[T; N]>::uninit();
343            let top: *mut T = &mut to as *mut _ as *mut T;
344            for i in 0..N {
345                top.add(i).write(ToWasm::read_to_wasm(inp));
346            }
347            to.assume_init()
348        }
349    }
350    
351    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
352        out.push_ln(slot, &format!("let t{} = {}", temp, prop));
353        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < {1}; i{0}++){{", temp, N));
354        let new_temp = out.alloc_temp();
355        T::to_wasm_js_body(out, slot, is_recur, &format!("t{0}[i{0}]", temp), new_temp);
356        out.push_ln(slot, "}");
357    }
358}
359
360impl<T> FromWasm for Vec<T> where T: FromWasm {
361    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
362        out.push_u32(self.len() as u32);
363        for item in self {
364            item.from_wasm_inner(out);
365        }
366    }
367    
368    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
369        out.push_ln(slot, &format!("let t{} = {} = [];", temp, prop));
370        out.push_ln(slot, &format!("t{}.length = app.u32[this.u32_offset++];", temp));
371        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < t{0}.length; i{0}++){{", temp));
372        let new_temp = out.alloc_temp();
373        T::from_wasm_js_body(out, slot, true, &format!("t{0}[i{0}]", temp), new_temp);
374        out.push_ln(slot, "}");
375    }
376}
377
378impl<T> ToWasm for Vec<T> where T: ToWasm {
379    fn u32_size() -> usize {1}
380    
381    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
382        let len = inp.read_u32();
383        let mut ret = Vec::new();
384        for _ in 0..len {
385            ret.push(ToWasm::read_to_wasm(inp));
386        }
387        ret
388    }
389    
390    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
391        let item_size = T::u32_size();
392        
393        out.push_ln(slot, &format!("let t{} = {};", temp, prop));
394        out.push_ln(slot, &format!("if(Array.isArray(t{})){{", temp));
395        out.push_ln(slot, &format!("app.u32[this.u32_offset ++] = t{}.length;", temp));
396        out.push_ln(slot, &format!("this.reserve_u32({} * t{}.length);", item_size, temp));
397        out.push_ln(slot, &format!("for(let i{0} = 0; i{0} < t{0}.length; i{0}++){{", temp));
398        let new_temp = out.alloc_temp();
399        T::to_wasm_js_body(out, slot, true, &format!("t{0}[i{0}]", temp), new_temp);
400        out.push_ln(slot, "}} else {");
401        out.push_ln(slot, "   app.u32[this.u32_offset ++] = 0;");
402        out.push_ln(slot, "}");
403        
404    }
405}
406
407impl<T> FromWasm for Box<T> where T: FromWasm {
408    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
409        (*self).from_wasm_inner(out);
410    }
411    
412    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, _temp: usize) {
413        let new_temp = out.alloc_temp();
414        T::from_wasm_js_body(out, slot, true, prop, new_temp);
415    }
416}
417
418impl<T> ToWasm for Box<T> where T: ToWasm {
419    fn u32_size() -> usize {0}
420    
421    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
422        Self::new(ToWasm::read_to_wasm(inp))
423
424    }
425    
426    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, _is_recur: bool, prop: &str, temp: usize) {
427        let item_size = T::u32_size();
428        out.push_ln(slot, &format!("this.reserve_u32({});", item_size));
429        T::to_wasm_js_body(out, slot, true, prop, temp);
430    }
431}
432
433impl<T> FromWasm for Option<T> where T: FromWasm {
434    fn from_wasm_inner(self, out: &mut FromWasmMsg) {
435        if let Some(val) = self {
436            out.push_u32(1);
437            val.from_wasm_inner(out);
438        }
439        else {
440            out.push_u32(0);
441        }
442    }
443    
444    fn from_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, _temp: usize) {
445        out.push_ln(slot, "if(app.u32[this.u32_offset++] !== 0){");
446        let new_temp = out.alloc_temp();
447        T::from_wasm_js_body(out, slot, is_recur, prop, new_temp);
448        out.push_ln(slot, "} else {");
449        out.push_ln(slot, &format!("{} = undefined;", prop));
450        out.push_ln(slot, "}");
451    }
452}
453
454impl<T> ToWasm for Option<T> where T: ToWasm {
455    fn u32_size() -> usize {1 + T::u32_size()}
456    
457    fn read_to_wasm(inp: &mut ToWasmMsgRef) -> Self {
458        if inp.read_u32() == 0 {
459            None
460        }
461        else {
462            Some(ToWasm::read_to_wasm(inp))
463        }
464    }
465    
466    fn to_wasm_js_body(out: &mut WasmJSOutput, slot: usize, is_recur: bool, prop: &str, temp: usize) {
467        out.push_ln(slot, &format!("if({0} === undefined){{", prop));
468        out.push_ln(slot, "app.u32[this.u32_offset ++] = 0;");
469        out.push_ln(slot, "} else {");
470        out.push_ln(slot, "app.u32[this.u32_offset ++] = 1;");
471        T::to_wasm_js_body(out, slot, is_recur, prop, temp);
472        out.push_ln(slot, "}");
473    }
474}
475
476