mirror of https://github.com/yewstack/yew
Merge #441
441: add render service r=DenisKolodin a=edvorg Greetings! This PR adds a render service that provide functionality to request animation frames in a convenient way. I copied it from here https://github.com/edvorg/rustmith , it's hugely based on timeout service. Could you please consider accepting it into main project? Co-authored-by: Eduard Knyshov <edvorg@gmail.com>
This commit is contained in:
commit
8c4ba1792a
|
@ -299,6 +299,7 @@ It's a handy alternative to subscriptions.
|
|||
|
||||
Implemented:
|
||||
* `IntervalService`
|
||||
* `RenderService`
|
||||
* `TimeoutService`
|
||||
* `StorageService`
|
||||
* `DialogService`
|
||||
|
|
|
@ -7,6 +7,7 @@ pub mod console;
|
|||
pub mod dialog;
|
||||
pub mod fetch;
|
||||
pub mod interval;
|
||||
pub mod render;
|
||||
pub mod storage;
|
||||
pub mod timeout;
|
||||
pub mod websocket;
|
||||
|
@ -15,6 +16,7 @@ pub use self::console::ConsoleService;
|
|||
pub use self::dialog::DialogService;
|
||||
pub use self::fetch::FetchService;
|
||||
pub use self::interval::IntervalService;
|
||||
pub use self::render::RenderService;
|
||||
pub use self::storage::StorageService;
|
||||
pub use self::timeout::TimeoutService;
|
||||
pub use self::websocket::WebSocketService;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//! This module contains the implementation of a service to
|
||||
//! request frame rendering
|
||||
|
||||
use stdweb::Value;
|
||||
use stdweb::unstable::TryInto;
|
||||
use services::Task;
|
||||
use callback::Callback;
|
||||
|
||||
/// A handle to cancel a render task.
|
||||
pub struct RenderTask(Option<Value>);
|
||||
|
||||
/// A service to request animation frames.
|
||||
#[derive(Default)]
|
||||
pub struct RenderService {}
|
||||
|
||||
impl RenderService {
|
||||
/// Create a new service instance
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
/// Request animation frame. Callback will be notified when frame should be rendered.
|
||||
pub fn request_animation_frame(&mut self, callback: Callback<f64>) -> RenderTask {
|
||||
let callback = move |v| {
|
||||
let time: f64 = match v {
|
||||
Value::Number(n) => n.try_into().unwrap(),
|
||||
_ => 0.0
|
||||
};
|
||||
callback.emit(time);
|
||||
};
|
||||
let handle = js! {
|
||||
var callback = @{callback};
|
||||
var action = function(time) {
|
||||
callback(time);
|
||||
callback.drop();
|
||||
};
|
||||
return {
|
||||
render_id: requestAnimationFrame(action),
|
||||
callback: callback,
|
||||
};
|
||||
};
|
||||
RenderTask(Some(handle))
|
||||
}
|
||||
}
|
||||
|
||||
impl Task for RenderTask {
|
||||
fn is_active(&self) -> bool {
|
||||
self.0.is_some()
|
||||
}
|
||||
fn cancel(&mut self) {
|
||||
let handle = self.0.take().expect("tried to cancel render twice");
|
||||
js! { @(no_return)
|
||||
var handle = @{handle};
|
||||
cancelAnimationFrame(handle.timeout_id);
|
||||
handle.callback.drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RenderTask {
|
||||
fn drop(&mut self) {
|
||||
if self.is_active() {
|
||||
self.cancel();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue