#![allow(missing_docs)]
pub mod io;
pub mod memory_pool;
pub mod net;
pub mod runtime;
pub mod window;
use std::sync::Arc;
use crate::memory_pool::BufferPool;
pub struct Context {
runtime: tokio::runtime::Runtime,
buffer_pool: BufferPool,
}
impl Context {
pub fn new() -> Self {
let runtime = tokio::runtime::Builder::new_multi_thread()
.worker_threads(4)
.thread_name("iris-worker")
.enable_all()
.build()
.expect("Failed to create Tokio runtime");
Self {
runtime,
buffer_pool: BufferPool::default(),
}
}
pub fn buffer_pool(&self) -> &BufferPool {
&self.buffer_pool
}
pub fn handle(&self) -> &tokio::runtime::Handle {
self.runtime.handle()
}
pub fn spawn<F>(&self, future: F) -> tokio::task::JoinHandle<F::Output>
where
F: std::future::Future + Send + 'static,
F::Output: Send + 'static,
{
self.runtime.spawn(future)
}
pub fn block_on<F>(&self, future: F) -> F::Output
where
F: std::future::Future,
{
self.runtime.block_on(future)
}
}
impl Default for Context {
fn default() -> Self {
Self::new()
}
}
#[cfg(not(target_arch = "wasm32"))]
pub trait Application: 'static {
fn initialize(&mut self, ctx: &Context, event_loop: &winit::event_loop::ActiveEventLoop);
fn window_event(
&mut self,
ctx: &Context,
event_loop: &winit::event_loop::ActiveEventLoop,
window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
);
#[allow(unused_variables)]
fn device_event(
&mut self,
ctx: &Context,
event_loop: &winit::event_loop::ActiveEventLoop,
device_id: winit::event::DeviceId,
event: winit::event::DeviceEvent,
) {
}
#[allow(unused_variables)]
fn update(&mut self, ctx: &Context, event_loop: &winit::event_loop::ActiveEventLoop) {}
#[allow(unused_variables)]
fn exiting(&mut self, ctx: &Context) {}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn run_app<A: Application>(app: A) -> Result<(), Box<dyn std::error::Error>> {
use winit::application::ApplicationHandler;
use winit::event::{DeviceEvent, StartCause, WindowEvent};
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
struct WinitApp<A> {
ctx: Arc<Context>,
app: A,
}
impl<A: Application> ApplicationHandler for WinitApp<A> {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.app.initialize(&self.ctx, event_loop);
}
fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
window_id: winit::window::WindowId,
event: WindowEvent,
) {
self.app
.window_event(&self.ctx, event_loop, window_id, event);
}
fn device_event(
&mut self,
event_loop: &ActiveEventLoop,
device_id: winit::event::DeviceId,
event: DeviceEvent,
) {
self.app
.device_event(&self.ctx, event_loop, device_id, event);
}
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
self.app.update(&self.ctx, event_loop);
}
fn new_events(&mut self, _event_loop: &ActiveEventLoop, _cause: StartCause) {}
fn suspended(&mut self, _event_loop: &ActiveEventLoop) {}
fn exiting(&mut self, _event_loop: &ActiveEventLoop) {
self.app.exiting(&self.ctx);
}
}
let ctx = Arc::new(Context::new());
let event_loop = EventLoop::new()?;
event_loop.set_control_flow(ControlFlow::Poll);
let mut winit_app = WinitApp { ctx, app };
event_loop.run_app(&mut winit_app)?;
Ok(())
}
pub fn init() {
println!("iris-core initialized");
}