diff --git a/src/graphics_context.rs b/src/graphics_context.rs index 5951be5..c3a9f1e 100644 --- a/src/graphics_context.rs +++ b/src/graphics_context.rs @@ -1,6 +1,6 @@ -struct Context{ - device:wgpu::Device, - queue:wgpu::Queue, +struct Context<'a>{ + device:&'a wgpu::Device, + queue:&'a wgpu::Queue, } impl Context{ diff --git a/src/main.rs b/src/main.rs index 237658f..e6ef0b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,7 +61,7 @@ fn load_file(path: std::path::PathBuf)->Option{ } } -fn default_models()->model::IndexedModelInstances{ +pub fn default_models()->model::IndexedModelInstances{ let mut indexed_models = Vec::new(); indexed_models.append(&mut model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/teslacyberv3.0.obj")[..]).unwrap(),glam::Vec4::ONE)); indexed_models.push(primitives::unit_sphere()); @@ -119,8 +119,6 @@ fn default_models()->model::IndexedModelInstances{ fn main(){ let title=format!("Strafe Client v{}",env!("CARGO_PKG_VERSION")).as_str(); - let context=setup_context::setup(title); - let run=run::RunState::init();//new - run.replace_models(&context,default_models()); - context.start(run); + let context=setup::setup(title); + context.start();//creates and runs a run context } diff --git a/src/physics_context.rs b/src/physics_context.rs index 0fe379b..1ea9c0d 100644 --- a/src/physics_context.rs +++ b/src/physics_context.rs @@ -21,6 +21,15 @@ pub enum InputInstruction { } pub struct Context{ + //Ideally the graphics thread worker description is: + /* + WorkerDescription{ + input:Immediate, + output:Realtime(PoolOrdering::Ordered(3)), + } + */ + //up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order + graphics_thread:crate::worker::INWorker, } impl Context{ pub fn new(user_settings:&crate::settings::UserSettings,indexed_model_instances:&crate::model::IndexedModelInstances){ diff --git a/src/run.rs b/src/run.rs index 18150e2..bf12876 100644 --- a/src/run.rs +++ b/src/run.rs @@ -1,85 +1,78 @@ use crate::physics::PhysicsInstruction; -use crate::render_thread::InputInstruction; -use crate::instruction::{TimedInstruction, InstructionConsumer}; +use crate::physics_context::InputInstruction; +use crate::instruction::TimedInstruction; pub enum RunInstruction{ Resize(winit::dpi::PhysicalSize), WindowEvent(winit::event::WindowEvent), DeviceEvent(winit::event::DeviceEvent), + RequestRedraw, Render, } -pub struct RunState{ - manual_mouse_lock:bool, - mouse:std::sync::Arc>, - user_settings:crate::settings::UserSettings, - //Ideally the graphics thread worker description is: - /* - WorkerDescription{ - input:Immediate, - output:Realtime(PoolOrdering::Ordered(3)), - } - */ - //up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order - graphics_thread:crate::worker::INWorker, +//holds thread handles to dispatch to +struct RunContext{ physics_thread:crate::worker::QNWorker>, } -impl RunState { - fn init() -> Self { +pub struct RunContextSetup{ + manual_mouse_lock:bool, + mouse:crate::physics::MouseState,//std::sync::Arc> + user_settings:crate::settings::UserSettings, + window:winit::window::Window, + physics:crate::physics::PhysicsState, + graphics:crate::graphics::GraphicsState, +} + +impl RunContextSetup { + pub fn new(context:&crate::setup::SetupContext,window:winit::window::Window)->Self{ //wee let user_settings=crate::settings::read_user_settings(); - let mut graphics=GraphicsState::new(); + let args:Vec=std::env::args().collect(); + let indexed_model_instances=if args.len()==2{ + crate::load_file(std::path::PathBuf::from(&args[1])) + }else{ + None + }.unwrap_or(crate::default_models()); + let mut graphics=crate::graphics::GraphicsState::new(&context.device,&context.queue); graphics.load_user_settings(&user_settings); + graphics.generate_models(&context.device,&context.queue,indexed_model_instances); - //how to multithread - - //1. build + let mut physics=crate::physics::PhysicsState::default(); + physics.load_user_settings(&user_settings); physics.generate_models(&indexed_model_instances); - //2. move - let physics_thread=physics.into_worker(); - - //3. forget - - let mut state=Self{ + Self{ manual_mouse_lock:false, - mouse:physics::MouseState::default(), + mouse:crate::physics::MouseState::default(), user_settings, + window, graphics, - physics_thread, - }; - state.generate_model_graphics(&device,&queue,indexed_model_instances); - - let args:Vec=std::env::args().collect(); - if args.len()==2{ - let indexed_model_instances=load_file(std::path::PathBuf::from(&args[1])); - state.render_thread=RenderThread::new(user_settings,indexed_model_instances); + physics, } - - return state; } fn window_event(&mut self, time:crate::integer::Time, event: winit::event::WindowEvent) { match event { winit::event::WindowEvent::DroppedFile(path)=>{ + let sender=self.sender.clone();//mpsc std::thread::spawn(move ||{ - let indexed_model_instances=load_file(path); - self.render_thread.send(Instruction::Die(indexed_model_instances)); + let indexed_model_instances=crate::load_file(path); + sender.send(Instruction::Die(indexed_model_instances)); }); }, winit::event::WindowEvent::Focused(state)=>{ //pause unpause //recalculate pressed keys on focus }, - winit::event::WindowEvent::KeyboardInput { - input:winit::event::KeyboardInput{state, virtual_keycode,..}, + winit::event::WindowEvent::KeyboardInput{ + input:winit::event::KeyboardInput{state,virtual_keycode,..}, .. }=>{ - let s=match state { - winit::event::ElementState::Pressed => true, - winit::event::ElementState::Released => false, + let s=match state{ + winit::event::ElementState::Pressed=>true, + winit::event::ElementState::Released=>false, }; match virtual_keycode{ Some(winit::event::VirtualKeyCode::Tab)=>{ @@ -192,13 +185,16 @@ impl RunState { } } - pub fn into_worker(self,mut setup_context:crate::setup_context::SetupContext)->crate::worker::QNWorker>{ + pub fn into_worker(self,mut setup_context:crate::setup_context::SetupContext,)->crate::worker::QNWorker>{ //create child context let physics_context=crate::physics_context::Context::new(indexed_models,&setup_context);//this needs all the context for graphics_context too let physics_thread=physics_context.into_worker(); // crate::worker::QNWorker::new(move |ins:TimedInstruction|{ match ins.instruction{ + RunInstruction::RequestRedraw=>{ + self.window.request_redraw(); + } RunInstruction::WindowEvent(window_event)=>{ self.window_event(ins.time,window_event); }, diff --git a/src/setup.rs b/src/setup.rs index ac5fadc..3de933c 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -208,7 +208,7 @@ pub fn setup(title:&str)->SetupContextSetup{ } } -struct SetupContextSetup{ +pub struct SetupContextSetup{ window:winit::window::Window, event_loop:winit::event_loop::EventLoop<()>, partial_context:SetupContextPartial4, @@ -224,12 +224,13 @@ impl SetupContextSetup{ self.partial_context.configure_surface(&size), ) } - pub fn start(self,mut run:crate::run::RunState){ + pub fn start(self){ let (window,event_loop,setup_context)=self.into_split(); //dedicated thread to ping request redraw back and resize the window doesn't seem logical - //physics and graphics render thread + let run=crate::run::RunContextSetup::new(&setup_context,window); + //the thread that spawns the physics thread let run_thread=run.into_worker(setup_context); println!("Entering render loop..."); @@ -243,7 +244,7 @@ impl SetupContextSetup{ // }; match event{ winit::event::Event::AboutToWait=>{ - window.request_redraw(); + run_thread.send(TimedInstruction{time,instruction:RunInstruction::RequestRedraw}); } winit::event::Event::WindowEvent { event: @@ -271,12 +272,12 @@ impl SetupContextSetup{ |winit::event::WindowEvent::CloseRequested=>{ elwt.exit(); } - _=>{ - run_thread.send(TimedInstruction{time,instruction:RunInstruction::WindowEvent(event)}); - } winit::event::WindowEvent::RedrawRequested=>{ run_thread.send(TimedInstruction{time,instruction:RunInstruction::Render}); } + _=>{ + run_thread.send(TimedInstruction{time,instruction:RunInstruction::WindowEvent(event)}); + } }, winit::event::Event::DeviceEvent{ event,