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:
bors[bot] 2018-12-10 20:15:51 +00:00
commit 8c4ba1792a
3 changed files with 69 additions and 0 deletions

View File

@ -299,6 +299,7 @@ It's a handy alternative to subscriptions.
Implemented: Implemented:
* `IntervalService` * `IntervalService`
* `RenderService`
* `TimeoutService` * `TimeoutService`
* `StorageService` * `StorageService`
* `DialogService` * `DialogService`

View File

@ -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;

66
src/services/render.rs Normal file
View File

@ -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();
}
}
}