Skip to content

Commit

Permalink
Use extern C now function that can be bound in JS
Browse files Browse the repository at this point in the history
  • Loading branch information
tversteeg committed May 15, 2020
1 parent c36b5cb commit 9b733bb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ as long as you are not targeting wasm32. This allows for portable code that will
### The feature `now`.
By enabling the feature `now` the function `instant::now()` will be exported and will either:

* Call `performance.now()` when compiling for a WASM platform with the features **stdweb** or **wasm-bindgen** enabled.
* Call `performance.now()` when compiling for a WASM platform with the features **stdweb** or **wasm-bindgen** enabled, or using a custom javascript function.
* Call `time::precise_time_s() * 1000.0` otherwise.

The result is expressed in milliseconds.
Expand Down Expand Up @@ -99,3 +99,26 @@ fn my_function() {
let now_milliseconds = instant::now(); // In milliseconds.
}
```

### Using the feature `now` without `stdweb` or `wasm-bindgen`.
_Cargo.toml_:
```toml
[dependencies]
instant = { version = "0.", features = [ "now" ] }
```

_lib.rs_:
```rust
fn my_function() {
// Will use the 'now' javascript implementation.
let now_instant = instant::Instant::new();
let now_milliseconds = instant::now(); // In milliseconds.
}
```

_javascript WASM bindings file_:
```js
function now() {
return Date.now() / 1000.0;
}
```
30 changes: 6 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,23 @@
#[macro_use]
extern crate stdweb;

#[cfg(any(
not(any(target_arch = "wasm32", target_arch = "asmjs")),
not(any(feature = "stdweb", feature = "wasm-bindgen"))
))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "asmjs")))]
pub use crate::native::Instant;

#[cfg(all(
any(target_arch = "wasm32", target_arch = "asmjs"),
any(feature = "stdweb", feature = "wasm-bindgen")
))]
#[cfg(any(target_arch = "wasm32", target_arch = "asmjs"))]
pub use crate::wasm::Instant;

#[cfg(any(
not(any(target_arch = "wasm32", target_arch = "asmjs")),
not(any(feature = "stdweb", feature = "wasm-bindgen"))
))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "asmjs")))]
#[cfg(feature = "now")]
pub use crate::native::now;

#[cfg(all(
any(target_arch = "wasm32", target_arch = "asmjs"),
any(feature = "stdweb", feature = "wasm-bindgen")
))]
#[cfg(any(target_arch = "wasm32", target_arch = "asmjs"))]
#[cfg(feature = "now")]
pub use crate::wasm::now;

pub use std::time::Duration;

#[cfg(any(
not(any(target_arch = "wasm32", target_arch = "asmjs")),
not(any(feature = "stdweb", feature = "wasm-bindgen"))
))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "asmjs")))]
mod native;
#[cfg(all(
any(target_arch = "wasm32", target_arch = "asmjs"),
any(feature = "stdweb", feature = "wasm-bindgen")
))]
#[cfg(any(target_arch = "wasm32", target_arch = "asmjs"))]
mod wasm;
19 changes: 16 additions & 3 deletions src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,23 @@ pub fn now() -> f64 {

#[cfg(feature = "wasm-bindgen")]
pub fn now() -> f64 {
use wasm_bindgen_rs::JsCast;
use wasm_bindgen_rs::prelude::*;
use wasm_bindgen_rs::JsCast;
js_sys::Reflect::get(&js_sys::global(), &JsValue::from_str("performance"))
.expect("failed to get performance from global object")
.unchecked_into::<web_sys::Performance>()
.now()
.unchecked_into::<web_sys::Performance>()
.now()
}

// The JS now function is in a module so it won't have to be renamed
#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))]
mod js {
extern "C" {
pub fn now() -> f64;
}
}
// Make the unsafe extern function "safe" so it can be called like the other 'now' functions
#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))]
pub fn now() -> f64 {
unsafe { js::now() }
}

0 comments on commit 9b733bb

Please sign in to comment.