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}
62pub 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