|
1 | 1 | usecrate::{convert, vm_class::AccessibleVM, wasm_builtins::window}; |
2 | 2 | use futures::{future,Future}; |
3 | 3 | use js_sys::Promise; |
4 | | -use rustpython_vm::obj::objstr; |
| 4 | +use rustpython_vm::obj::{objint,objstr}; |
5 | 5 | use rustpython_vm::pyobject::{PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol}; |
6 | 6 | use rustpython_vm::VirtualMachine; |
7 | 7 | use wasm_bindgen::{prelude::*,JsCast}; |
@@ -125,11 +125,68 @@ fn browser_fetch(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { |
125 | 125 | Ok(vm.get_none()) |
126 | 126 | } |
127 | 127 |
|
| 128 | +fnbrowser_request_animation_frame(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{ |
| 129 | +arg_check!(vm, args, required =[(func,Some(vm.ctx.function_type()))]); |
| 130 | + |
| 131 | +use std::{cell::RefCell, rc::Rc}; |
| 132 | + |
| 133 | +// this basic setup for request_animation_frame taken from: |
| 134 | +// https://rustwasm.github.io/wasm-bindgen/examples/request-animation-frame.html |
| 135 | + |
| 136 | +let f =Rc::new(RefCell::new(None)); |
| 137 | +let g = f.clone(); |
| 138 | + |
| 139 | +let func = func.clone(); |
| 140 | + |
| 141 | +let acc_vm =AccessibleVM::from_vm(vm); |
| 142 | + |
| 143 | +*g.borrow_mut() =Some(Closure::wrap(Box::new(move |time:f64|{ |
| 144 | +let vm =&mut acc_vm |
| 145 | +.upgrade() |
| 146 | +.expect("that the vm is valid from inside of request_animation_frame"); |
| 147 | +let func = func.clone(); |
| 148 | +let args =PyFuncArgs{ |
| 149 | +args:vec![vm.ctx.new_float(time)], |
| 150 | +kwargs:vec![], |
| 151 | +}; |
| 152 | +let _ = vm.invoke(func, args); |
| 153 | + |
| 154 | +let closure = f.borrow_mut().take(); |
| 155 | +drop(closure); |
| 156 | +})asBox<Fn(f64)>)); |
| 157 | + |
| 158 | +let id =window() |
| 159 | +.request_animation_frame(&js_sys::Function::from( |
| 160 | + g.borrow().as_ref().unwrap().as_ref().clone(), |
| 161 | +)) |
| 162 | +.map_err(|err| convert::js_py_typeerror(vm, err))?; |
| 163 | + |
| 164 | +Ok(vm.ctx.new_int(id)) |
| 165 | +} |
| 166 | + |
| 167 | +fnbrowser_cancel_animation_frame(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{ |
| 168 | +arg_check!(vm, args, required =[(id,Some(vm.ctx.int_type()))]); |
| 169 | + |
| 170 | +// fine because |
| 171 | +let id = objint::get_value(id) |
| 172 | +.to_string() |
| 173 | +.parse() |
| 174 | +.expect("bigint.to_string() to be parsable as i32"); |
| 175 | + |
| 176 | +window() |
| 177 | +.cancel_animation_frame(id) |
| 178 | +.map_err(|err| convert::js_py_typeerror(vm, err))?; |
| 179 | + |
| 180 | +Ok(vm.get_none()) |
| 181 | +} |
| 182 | + |
128 | 183 | constBROWSER_NAME:&str ="browser"; |
129 | 184 |
|
130 | 185 | pubfnmk_module(ctx:&PyContext) ->PyObjectRef{ |
131 | 186 | py_module!(ctx,BROWSER_NAME,{ |
132 | | -"fetch" => ctx.new_rustfunc(browser_fetch) |
| 187 | +"fetch" => ctx.new_rustfunc(browser_fetch), |
| 188 | +"request_animation_frame" => ctx.new_rustfunc(browser_request_animation_frame), |
| 189 | +"cancel_animation_frame" => ctx.new_rustfunc(browser_cancel_animation_frame), |
133 | 190 | }) |
134 | 191 | } |
135 | 192 |
|
|