use super::*;
impl Engine {
pub fn new_handle(config: EngineConfig) -> EngineHandle {
EngineHandle::new(config, None, None, None, None)
}
pub async fn run(config: EngineConfig, handler: TickHandlerRc) -> EngineHandle {
let mut handle: EngineHandle = Engine::new_handle(config);
match handle.get_config().get_render().get_backend() {
RenderBackendType::Canvas2D => {
handle.init_canvas();
}
RenderBackendType::WebGpu => {
let _: Result<WebGpuRenderer, WebGpuInitError> = handle.init_webgpu().await;
}
RenderBackendType::WebGl => {
let _: Result<WebGlRenderer, WebGlInitError> = handle.init_webgl();
}
}
handle.start(handler);
handle
}
pub fn default_config() -> EngineConfig {
EngineConfig::default()
}
pub fn canvas_renderer(config: &RenderConfig) -> Option<CanvasRenderer> {
CanvasRenderer::from_selector(
config.get_canvas_selector(),
config.get_width(),
config.get_height(),
)
}
pub async fn webgpu_renderer(config: &RenderConfig) -> Result<WebGpuRenderer, WebGpuInitError> {
WebGpuRenderer::init(config).await
}
pub fn webgl_renderer(config: &RenderConfig) -> Result<WebGlRenderer, WebGlInitError> {
WebGlRenderer::init(config)
}
}
impl EngineHandle {
pub fn init_canvas(&mut self) -> bool {
let render_config: &RenderConfig = &self.get_config().get_render();
let renderer: Option<CanvasRenderer> = CanvasRenderer::from_selector(
render_config.get_canvas_selector(),
render_config.get_width(),
render_config.get_height(),
);
match renderer {
Some(r) => {
self.set_canvas_renderer(Some(r));
self.set_webgpu_renderer(None);
self.set_webgl_renderer(None);
true
}
None => {
self.set_canvas_renderer(None);
self.set_webgpu_renderer(None);
self.set_webgl_renderer(None);
false
}
}
}
pub async fn init_webgpu(&mut self) -> Result<WebGpuRenderer, WebGpuInitError> {
let render_config: &RenderConfig = &self.get_config().get_render();
let renderer: WebGpuRenderer = WebGpuRenderer::init(render_config).await?;
self.set_webgpu_renderer(Some(renderer.clone()));
self.set_canvas_renderer(None);
self.set_webgl_renderer(None);
Ok(renderer)
}
pub fn init_webgl(&mut self) -> Result<WebGlRenderer, WebGlInitError> {
let render_config: &RenderConfig = &self.get_config().get_render();
let renderer: WebGlRenderer = WebGlRenderer::init(render_config)?;
self.set_webgl_renderer(Some(renderer.clone()));
self.set_canvas_renderer(None);
self.set_webgpu_renderer(None);
Ok(renderer)
}
pub fn register_input(&mut self) -> Option<InputStateCell> {
if let Some(existing) = self.try_get_input_cell() {
return Some(existing.clone());
}
let window_value: Window = window().expect("no global window exists");
let document_value: Document = window_value.document().expect("should have a document");
let render_config: &RenderConfig = &self.get_config().get_render();
let canvas_selector: String = render_config.get_canvas_selector();
let element: Element = document_value
.query_selector(canvas_selector.as_ref())
.ok()
.flatten()?;
let target: EventTarget = element.into();
let cell: InputStateCell = Input::attach(
Rc::new(EngineCell::new(InputState::default())),
&window_value,
&target,
);
self.set_input_cell(Some(cell.clone()));
Some(cell)
}
pub fn start(&mut self, handler: TickHandlerRc) {
let scheduler_config: SchedulerConfig = self.get_config().get_scheduler();
self.set_scheduler_handle(Some(SchedulerHandle::start(scheduler_config, handler)));
}
pub fn stop(&self) {
if let Some(handle) = self.try_get_scheduler_handle().as_ref() {
handle.stop();
}
}
pub fn is_running(&self) -> bool {
self.try_get_scheduler_handle()
.as_ref()
.is_some_and(|handle: &SchedulerHandle| handle.is_running())
}
}