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:
|
Implemented:
|
||||||
* `IntervalService`
|
* `IntervalService`
|
||||||
|
* `RenderService`
|
||||||
* `TimeoutService`
|
* `TimeoutService`
|
||||||
* `StorageService`
|
* `StorageService`
|
||||||
* `DialogService`
|
* `DialogService`
|
||||||
|
|
|
@ -7,6 +7,7 @@ pub mod console;
|
||||||
pub mod dialog;
|
pub mod dialog;
|
||||||
pub mod fetch;
|
pub mod fetch;
|
||||||
pub mod interval;
|
pub mod interval;
|
||||||
|
pub mod render;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod timeout;
|
pub mod timeout;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
@ -15,6 +16,7 @@ pub use self::console::ConsoleService;
|
||||||
pub use self::dialog::DialogService;
|
pub use self::dialog::DialogService;
|
||||||
pub use self::fetch::FetchService;
|
pub use self::fetch::FetchService;
|
||||||
pub use self::interval::IntervalService;
|
pub use self::interval::IntervalService;
|
||||||
|
pub use self::render::RenderService;
|
||||||
pub use self::storage::StorageService;
|
pub use self::storage::StorageService;
|
||||||
pub use self::timeout::TimeoutService;
|
pub use self::timeout::TimeoutService;
|
||||||
pub use self::websocket::WebSocketService;
|
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