1#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
2
3#[cfg(test)]
4pub mod tests;
5
6pub mod sys;
7pub mod shader;
8pub mod component;
9pub mod utils;
10pub mod entity;
11pub mod scene;
12pub mod assets;
13pub mod system;
14#[cfg(feature = "yew-support")]
15pub mod yew_ext;
16
17pub use shader::*;
18pub use component::*;
19pub use utils::*;
20pub use entity::*;
21pub use scene::*;
22pub use assets::*;
23pub use system::*;
24#[cfg(feature = "yew-support")]
25
26#[cfg(feature = "init")]
30pub async fn init_aframe() -> Result<(), InitError>
31{
32 const LINK: &'static str = "https://aframe.io/releases/1.6.0/aframe.min.js";
33
34 use wasm_bindgen::prelude::*;
35 use std::sync::{Arc, Mutex};
36 use async_lock::Barrier;
37 use futures::executor::block_on;
38
39 let result: Arc<Mutex<Result<(), InitError>>> = Arc::new(Mutex::new(Err(InitError)));
40 let barrier = Arc::new(Barrier::new(2));
41
42 let result_outer = result.clone();
43 let barrier_inner = barrier.clone();
44
45 let document = web_sys::window()
47 .and_then(|win| win.document())
48 .ok_or(InitError)?;
49 let head = document.head()
50 .ok_or(InitError)?;
51 let script_element = document.create_element("script")
52 .map_err(|_| InitError)?;
53 let script_element = script_element.dyn_into::<web_sys::HtmlElement>()
54 .map_err(|_| InitError)?;
55 head.append_child(&script_element)
56 .map_err(|_| InitError)?;
57 let closure =
58 {
59 Closure::once(Box::new(move ||
60 {
61 *result.lock().unwrap() = Ok(());
62 drop(result);
63 block_on(barrier_inner.wait());
64 }) as Box<dyn FnOnce()>)
65 };
66 script_element.set_onload(Some(closure.as_ref().unchecked_ref()));
67 closure.forget();
68 script_element.set_attribute("src", LINK)
69 .map_err(|_| InitError)?;
70
71 barrier.wait().await;
72 Arc::try_unwrap(result_outer)
73 .map_err(|_| InitError)
74 .and_then(|mutex| mutex.into_inner().map_err(|_| InitError))
75 .and_then(|result| result)
76}
77
78#[cfg(feature = "init")]
79#[derive(Debug, Clone, Copy)]
80pub struct InitError;
81
82#[cfg(feature = "init")]
83impl std::fmt::Display for InitError
84{
85 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result
86 {
87 write!(f, "Failed to initialize")
88 }
89}
90
91#[cfg(feature = "init")]
92impl std::error::Error for InitError
93{
94 fn description(&self) -> &str
95 {
96 "Failed to initialize"
97 }
98}