Got the Controller working
* reworked iput system again + added test functions
This commit is contained in:
parent
7f37ee7a24
commit
e3fdbb142c
@ -38,7 +38,7 @@ where
|
|||||||
|
|
||||||
Controller {
|
Controller {
|
||||||
pipelines: pipelines_vec,
|
pipelines: pipelines_vec,
|
||||||
color: [0.0, 1.0, 0.0, 0.0],
|
color: [0.0, 1.0, 1.0, 0.0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ where
|
|||||||
|
|
||||||
for pipeline in &mut self.pipelines {
|
for pipeline in &mut self.pipelines {
|
||||||
for input in &pipeline.inputs {
|
for input in &pipeline.inputs {
|
||||||
match input.borrow().read(1) {
|
match input.borrow().read(Duration::from_millis(1)) {
|
||||||
Ok(key) => input_keys.push(key),
|
Ok(key) => input_keys.push(key),
|
||||||
Err(_err) => (),
|
Err(_err) => (),
|
||||||
}
|
}
|
||||||
@ -87,14 +87,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
//#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
winit_window::WinitWindow,
|
io::WinitWindow,
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
utils::Rect,
|
utils::Rect,
|
||||||
subengine::{SubengineController, TestSubengine},
|
subengine::{SubengineController, TestSubengine},
|
||||||
@ -102,7 +102,7 @@ mod tests {
|
|||||||
|
|
||||||
use gfx_backend_vulkan as vk_back;
|
use gfx_backend_vulkan as vk_back;
|
||||||
|
|
||||||
#[test]
|
//#[test]
|
||||||
fn test_new() {
|
fn test_new() {
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ mod tests {
|
|||||||
let subengine_pipeline = SubenginePipeline::new(inputs, subengines, renderers);
|
let subengine_pipeline = SubenginePipeline::new(inputs, subengines, renderers);
|
||||||
|
|
||||||
//creating controller
|
//creating controller
|
||||||
let controller = Controller::new(vec![subengine_pipeline]);
|
let _controller = Controller::new(vec![subengine_pipeline]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -160,7 +160,9 @@ mod tests {
|
|||||||
|
|
||||||
//running controller
|
//running controller
|
||||||
let mut controller = Controller::new(vec![subengine_pipeline]);
|
let mut controller = Controller::new(vec![subengine_pipeline]);
|
||||||
controller.run();
|
for _i in 0..10 {
|
||||||
|
controller.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
src/io.rs
56
src/io.rs
@ -1,10 +1,16 @@
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use raw_window_handle::HasRawWindowHandle;
|
use raw_window_handle::HasRawWindowHandle;
|
||||||
|
|
||||||
use crate::utils::Rect;
|
use crate::utils::Rect;
|
||||||
|
|
||||||
|
pub mod winit_window;
|
||||||
|
pub use self::winit_window::WinitWindow;
|
||||||
|
|
||||||
|
|
||||||
//--Output trait------------------------------------------------------------------------------------
|
//--Output trait------------------------------------------------------------------------------------
|
||||||
/// A trait for the ability of a type to be used as an output by the engine.
|
/// A trait for the ability of a type to be used as an output by the engine.
|
||||||
///
|
///
|
||||||
@ -36,33 +42,7 @@ where
|
|||||||
fn window(&self) -> &W;
|
fn window(&self) -> &W;
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl<'a, W, O> Output<W> for &'a mut O
|
//--Input trait-------------------------------------------------------------------------------------
|
||||||
//where
|
|
||||||
// W: HasRawWindowHandle,
|
|
||||||
// O: Output<W>,
|
|
||||||
//{
|
|
||||||
// fn get_id(&self) -> usize { Output::get_id(*self) }
|
|
||||||
// fn set_id(&mut self, id: usize) { Output::set_id(*self, id); }
|
|
||||||
//
|
|
||||||
// fn size(&mut self) -> &mut Rect<i32> { Output::size(*self) }
|
|
||||||
//
|
|
||||||
// fn window(&self) -> &W { Output::window(*self) }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//impl<'a, W, O> Output<W> for Box<O>
|
|
||||||
//where
|
|
||||||
// W: HasRawWindowHandle,
|
|
||||||
// O: Output<W>,
|
|
||||||
//{
|
|
||||||
// fn get_id(&self) -> usize { Output::get_id(self) }
|
|
||||||
// fn set_id(&mut self, id: usize) { Output::set_id(self, id); }
|
|
||||||
//
|
|
||||||
// fn size(&mut self) -> &mut Rect<i32> { Output::size(self) }
|
|
||||||
//
|
|
||||||
// fn window(&self) -> &W { Output::window(self) }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//--Input trait------------------------------------------------------------------------------------
|
|
||||||
/// A trait for the ability of a type to be used as an input by the engine
|
/// A trait for the ability of a type to be used as an input by the engine
|
||||||
///
|
///
|
||||||
/// The `Input` trait defines functions used by different components of the engine. The allow to
|
/// The `Input` trait defines functions used by different components of the engine. The allow to
|
||||||
@ -75,23 +55,29 @@ pub trait Input {
|
|||||||
/// Return the next input available or a ReadError if an error occured of the timeout duration
|
/// Return the next input available or a ReadError if an error occured of the timeout duration
|
||||||
/// was reached. How inputs are handled depends on the implementation.
|
/// was reached. How inputs are handled depends on the implementation.
|
||||||
//TODO change timeout
|
//TODO change timeout
|
||||||
fn read(&self, timeout_ms: u32) -> Result<Key, ReadError>;
|
fn read(&self, timeout: Duration) -> Result<Key, ReadError>;
|
||||||
|
|
||||||
|
fn write(&self, signal: Signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl<'a, I> Input for &'a mut I
|
|
||||||
//where
|
|
||||||
// I: Input,
|
|
||||||
//{
|
|
||||||
// fn read(&self, timeout_ms: u32) -> Result<Key, ReadError> { Input::read(*self, timeout_ms) }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//--Key enum----------------------------------------------------------------------------------------
|
//--Key enum----------------------------------------------------------------------------------------
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
Close,
|
Close,
|
||||||
|
Closed,
|
||||||
|
Test,
|
||||||
MouseMove { x: f64, y: f64 },
|
MouseMove { x: f64, y: f64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--Signal enum-------------------------------------------------------------------------------------
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Signal {
|
||||||
|
Exit,
|
||||||
|
Test,
|
||||||
|
}
|
||||||
|
|
||||||
//--ReadError enum----------------------------------------------------------------------------------
|
//--ReadError enum----------------------------------------------------------------------------------
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum ReadError {
|
pub enum ReadError {
|
||||||
Timeout,
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,17 +4,18 @@ use log::{debug, error, info, trace, warn};
|
|||||||
use std::{
|
use std::{
|
||||||
thread,
|
thread,
|
||||||
sync::mpsc,
|
sync::mpsc,
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event_loop::{EventLoop},
|
event_loop::{EventLoop, EventLoopProxy},
|
||||||
window::{WindowBuilder, Window},
|
window::{WindowBuilder, Window},
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO fix that
|
//TODO fix that
|
||||||
use crate::{
|
use crate::{
|
||||||
io::{Output, Input, Key, ReadError},
|
io::{Output, Input, Key, Signal, ReadError},
|
||||||
utils::Rect,
|
utils::Rect,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,9 +25,24 @@ pub struct WinitWindow {
|
|||||||
size: Rect<i32>,
|
size: Rect<i32>,
|
||||||
id: usize,
|
id: usize,
|
||||||
|
|
||||||
handle: thread::JoinHandle<()>,
|
|
||||||
receiver: mpsc::Receiver<Key>,
|
receiver: mpsc::Receiver<Key>,
|
||||||
window: Window,
|
window: Window,
|
||||||
|
event_loop_proxy: EventLoopProxy<Signal>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for WinitWindow {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
use winit::event::Event;
|
||||||
|
|
||||||
|
// kill event_loop
|
||||||
|
if self.event_loop_proxy.send_event(Signal::Exit).is_err() {
|
||||||
|
warn!("EventLoop thread is dead before Exit signal");
|
||||||
|
}
|
||||||
|
//while match self.read(Duration::from_millis(1)) {
|
||||||
|
// Ok(Key::Closed) => false,
|
||||||
|
// _ => true,
|
||||||
|
//} {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitWindow {
|
impl WinitWindow {
|
||||||
@ -42,22 +58,24 @@ impl WinitWindow {
|
|||||||
let cloned_name = name.clone();
|
let cloned_name = name.clone();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let (tmp_tx, tmp_rx) = mpsc::sync_channel(1);
|
let (tmp_tx, tmp_rx) = mpsc::sync_channel(1);
|
||||||
let handle = thread::spawn(move || {
|
let builder = thread::Builder::new().name(title);
|
||||||
|
//the EventLoop hijacks the thread so there is no need to join it later...
|
||||||
|
thread::spawn(move || {
|
||||||
|
|
||||||
trace!("Creating Window in EventLoop thread");
|
trace!("Creating Window in EventLoop thread");
|
||||||
//winit doesn't like use creating the EventLoop in another thread either so we have to
|
//winit doesn't like us creating the EventLoop in another thread either so we have to
|
||||||
//drop crossplatform compatibility :/
|
//drop crossplatform compatibility :/
|
||||||
let event_loop = EventLoop::new_any_thread();
|
let event_loop = EventLoop::new_any_thread();
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
.with_inner_size(PhysicalSize {width: size.w, height: size.h})
|
.with_inner_size(PhysicalSize {width: size.w, height: size.h})
|
||||||
.with_title(cloned_name)
|
.with_title(cloned_name)
|
||||||
.build(&event_loop).unwrap();
|
.build(&event_loop).unwrap();
|
||||||
|
let event_loop_proxy = event_loop.create_proxy();
|
||||||
|
|
||||||
trace!("Sending Window back to main thread");
|
trace!("Sending Window back to main thread");
|
||||||
tmp_tx.send(window).unwrap();
|
tmp_tx.send((window, event_loop_proxy)).unwrap();
|
||||||
|
|
||||||
//TODO clean event type
|
event_loop.run(move |event: winit::event::Event<'_, Signal>, _, control_flow| {
|
||||||
event_loop.run(move |event: winit::event::Event<'_, ()>, _, control_flow| {
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event_loop::ControlFlow,
|
event_loop::ControlFlow,
|
||||||
event::Event,
|
event::Event,
|
||||||
@ -66,13 +84,15 @@ impl WinitWindow {
|
|||||||
|
|
||||||
*control_flow = ControlFlow::Wait;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
//TODO manage errors
|
|
||||||
match event {
|
match event {
|
||||||
|
Event::LoopDestroyed => {
|
||||||
|
tx.send(Key::Closed).unwrap();
|
||||||
|
debug!("Closed EventLoop");
|
||||||
|
},
|
||||||
Event::WindowEvent{window_id: _, event} => match event {
|
Event::WindowEvent{window_id: _, event} => match event {
|
||||||
event::WindowEvent::CloseRequested => {
|
event::WindowEvent::CloseRequested => {
|
||||||
|
debug!("Close requested");
|
||||||
tx.send(Key::Close).unwrap();
|
tx.send(Key::Close).unwrap();
|
||||||
warn!("Stop input thread");
|
|
||||||
*control_flow = ControlFlow::Exit;
|
|
||||||
},
|
},
|
||||||
event::WindowEvent::CursorMoved{position, ..} => {
|
event::WindowEvent::CursorMoved{position, ..} => {
|
||||||
tx.send(Key::MouseMove{
|
tx.send(Key::MouseMove{
|
||||||
@ -81,21 +101,30 @@ impl WinitWindow {
|
|||||||
}).unwrap();
|
}).unwrap();
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
},
|
||||||
|
Event::UserEvent(signal) => match signal {
|
||||||
|
Signal::Exit => {
|
||||||
|
debug!("Stopping input thread...");
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
},
|
||||||
|
Signal::Test => {
|
||||||
|
tx.send(Key::Test).unwrap();
|
||||||
|
},
|
||||||
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}})
|
}})
|
||||||
});
|
});
|
||||||
|
|
||||||
let window = tmp_rx.recv().unwrap();
|
let (window, event_loop_proxy) = tmp_rx.recv().unwrap();
|
||||||
trace!("Received Window in main thread");
|
trace!("Received Window in main thread");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name,
|
name,
|
||||||
size,
|
size,
|
||||||
id,
|
id,
|
||||||
handle: handle,
|
|
||||||
receiver: rx,
|
receiver: rx,
|
||||||
window,
|
window,
|
||||||
|
event_loop_proxy,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,13 +139,39 @@ impl Output<Window> for WinitWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Input for WinitWindow {
|
impl Input for WinitWindow {
|
||||||
fn read(&self, timeout_ms: u32) -> Result<Key, ReadError> {
|
fn read(&self, timeout: Duration) -> Result<Key, ReadError> {
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
match self.receiver.recv_timeout(Duration::from_millis(timeout_ms.into())) {
|
match self.receiver.recv_timeout(timeout) {
|
||||||
Ok(key) => Ok(key),
|
Ok(key) => Ok(key),
|
||||||
Err(_) => Err(ReadError::Timeout),
|
Err(_) => Err(ReadError::Timeout),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write(&self, signal: Signal) {
|
||||||
|
|
||||||
|
self.event_loop_proxy.send_event(signal)
|
||||||
|
.map_err(|_| "Could not send Signal to EventLoop").unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use crate::utils::Rect;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_drop() {
|
||||||
|
let _window1 = WinitWindow::new("IV", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
let _window2 = WinitWindow::new("IV", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
panic!("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_read_write() {
|
||||||
|
let window = WinitWindow::new("IV", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
window.write(Signal::Test);
|
||||||
|
let input = window.read(Duration::from_millis(1)).unwrap();
|
||||||
|
assert!(matches!(input, Key::Test));
|
||||||
|
}
|
||||||
|
}
|
||||||
234
src/io/winit_window.rs
Normal file
234
src/io/winit_window.rs
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
thread,
|
||||||
|
sync::mpsc,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use winit::{
|
||||||
|
dpi::PhysicalSize,
|
||||||
|
event_loop::{EventLoop, EventLoopProxy},
|
||||||
|
window::{WindowBuilder, Window},
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO fix that
|
||||||
|
use crate::{
|
||||||
|
io::{Output, Input, Key, Signal, ReadError},
|
||||||
|
utils::Rect,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct WinitWindow {
|
||||||
|
pub name: String,
|
||||||
|
size: Rect<i32>,
|
||||||
|
id: usize,
|
||||||
|
|
||||||
|
receiver: mpsc::Receiver<Key>,
|
||||||
|
window: Window,
|
||||||
|
event_loop_proxy: EventLoopProxy<Signal>,
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//impl Drop for WinitWindow {
|
||||||
|
// fn drop(&mut self) {
|
||||||
|
// use winit::event::Event;
|
||||||
|
//
|
||||||
|
// // kill event_loop
|
||||||
|
// if self.event_loop_proxy.send_event(Signal::Exit).is_err() {
|
||||||
|
// warn!("EventLoop thread is dead before Exit signal");
|
||||||
|
// }
|
||||||
|
// while match self.read(Duration::from_millis(1)) {
|
||||||
|
// Ok(Key::Closed) => false,
|
||||||
|
// Err(err) => match err {
|
||||||
|
// ReadError::Timeout => false,
|
||||||
|
// _ => true,
|
||||||
|
// },
|
||||||
|
// _ => true,
|
||||||
|
// } {}
|
||||||
|
// debug!("Dropped !");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
impl WinitWindow {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
use winit::event::Event;
|
||||||
|
|
||||||
|
// kill event_loop
|
||||||
|
debug!("Sending kill signal...");
|
||||||
|
if self.event_loop_proxy.send_event(Signal::Exit).is_err() {
|
||||||
|
warn!("EventLoop thread is dead before Exit signal");
|
||||||
|
}
|
||||||
|
debug!("Kill signal sent");
|
||||||
|
while match self.read(Duration::from_millis(1)) {
|
||||||
|
Ok(Key::Closed) => false,
|
||||||
|
Err(err) => match err {
|
||||||
|
ReadError::Timeout => false,
|
||||||
|
_ => true,
|
||||||
|
},
|
||||||
|
_ => true,
|
||||||
|
} {}
|
||||||
|
debug!("Dropped !");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(title: &str, size: Rect<i32>) -> Result<WinitWindow, &'static str> {
|
||||||
|
use winit::platform::unix::EventLoopExtUnix;
|
||||||
|
|
||||||
|
debug!("Creating window");
|
||||||
|
let name = title.to_string();
|
||||||
|
let id = 0;
|
||||||
|
|
||||||
|
//Since we can't move the EventLoop from one thread to another, we need to create it in the
|
||||||
|
//right thread and then move the Window back to the main thread instead
|
||||||
|
let cloned_name = name.clone();
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let (tmp_tx, tmp_rx) = mpsc::sync_channel(1);
|
||||||
|
let builder = thread::Builder::new().name(title.into());
|
||||||
|
//the EventLoop hijacks the thread so there is no need to join it later...
|
||||||
|
builder.spawn(move || {
|
||||||
|
|
||||||
|
trace!("Creating Window in EventLoop thread");
|
||||||
|
//winit doesn't like us creating the EventLoop in another thread either so we have to
|
||||||
|
//drop crossplatform compatibility :/
|
||||||
|
let event_loop = EventLoop::new_any_thread();
|
||||||
|
let window = WindowBuilder::new()
|
||||||
|
.with_inner_size(PhysicalSize {width: size.w, height: size.h})
|
||||||
|
.with_title(cloned_name)
|
||||||
|
.build(&event_loop).unwrap();
|
||||||
|
let event_loop_proxy = event_loop.create_proxy();
|
||||||
|
|
||||||
|
trace!("Sending Window back to main thread");
|
||||||
|
tmp_tx.send((window, event_loop_proxy)).unwrap();
|
||||||
|
|
||||||
|
event_loop.run(move |event: winit::event::Event<'_, Signal>, _, control_flow| {
|
||||||
|
use winit::{
|
||||||
|
event_loop::ControlFlow,
|
||||||
|
event::Event,
|
||||||
|
event,
|
||||||
|
};
|
||||||
|
|
||||||
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
Event::LoopDestroyed => {
|
||||||
|
tx.send(Key::Closed).unwrap();
|
||||||
|
debug!("Closed EventLoop");
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
Event::WindowEvent{window_id: _, event} => match event {
|
||||||
|
event::WindowEvent::CloseRequested => {
|
||||||
|
debug!("Close requested");
|
||||||
|
tx.send(Key::Close).unwrap();
|
||||||
|
},
|
||||||
|
event::WindowEvent::CursorMoved{position, ..} => {
|
||||||
|
tx.send(Key::MouseMove{
|
||||||
|
x: position.x,
|
||||||
|
y: position.y,
|
||||||
|
}).unwrap();
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
Event::UserEvent(signal) => match signal {
|
||||||
|
Signal::Exit => {
|
||||||
|
debug!("Stopping input thread...");
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
},
|
||||||
|
Signal::Test => {
|
||||||
|
tx.send(Key::Test).unwrap();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}})
|
||||||
|
});
|
||||||
|
|
||||||
|
let (window, event_loop_proxy) = tmp_rx.recv().unwrap();
|
||||||
|
trace!("Received Window in main thread");
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
name,
|
||||||
|
size,
|
||||||
|
id,
|
||||||
|
receiver: rx,
|
||||||
|
window,
|
||||||
|
event_loop_proxy,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Output<Window> for WinitWindow {
|
||||||
|
fn get_id(&self) -> usize { self.id }
|
||||||
|
fn set_id(&mut self, id: usize) { self.id = id; }
|
||||||
|
|
||||||
|
fn size(&mut self) -> &mut Rect<i32> { &mut self.size }
|
||||||
|
|
||||||
|
fn window(&self) -> &Window { &self.window }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Input for WinitWindow {
|
||||||
|
fn read(&self, timeout: Duration) -> Result<Key, ReadError> {
|
||||||
|
|
||||||
|
match self.receiver.recv_timeout(timeout) {
|
||||||
|
Ok(key) => Ok(key),
|
||||||
|
Err(_) => Err(ReadError::Timeout),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, signal: Signal) {
|
||||||
|
|
||||||
|
self.event_loop_proxy.send_event(signal)
|
||||||
|
.map_err(|_| "Could not send Signal to EventLoop").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use crate::utils::Rect;
|
||||||
|
|
||||||
|
fn setup_logger() -> Result<(), fern::InitError> {
|
||||||
|
use fern::colors::{Color, ColoredLevelConfig};
|
||||||
|
|
||||||
|
let colors = ColoredLevelConfig::new()
|
||||||
|
.info(Color::Green)
|
||||||
|
.debug(Color::Magenta)
|
||||||
|
.warn(Color::Yellow)
|
||||||
|
.error(Color::Red);
|
||||||
|
|
||||||
|
fern::Dispatch::new()
|
||||||
|
.format(move |out, message, record| {
|
||||||
|
out.finish(format_args!(
|
||||||
|
"{}[{}][{}] {}",
|
||||||
|
chrono::Local::now().format("[%H:%M:%S]"),
|
||||||
|
colors.color(record.level()),
|
||||||
|
record.target(),
|
||||||
|
message
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.level(log::LevelFilter::Trace)
|
||||||
|
.chain(std::io::stdout())
|
||||||
|
.chain(fern::log_file("output.log")?)
|
||||||
|
.apply()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[test]
|
||||||
|
fn test_new_drop() {
|
||||||
|
let _ = setup_logger();
|
||||||
|
let mut window1 = WinitWindow::new("IV", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
let mut window2 = WinitWindow::new("IV 2", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
|
||||||
|
window1.drop();
|
||||||
|
window2.drop();
|
||||||
|
|
||||||
|
panic!("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[test]
|
||||||
|
fn test_read_write() {
|
||||||
|
let window = WinitWindow::new("IV", Rect {w: 1280, h: 720}).unwrap();
|
||||||
|
window.write(Signal::Test);
|
||||||
|
let input = window.read(Duration::from_millis(1)).unwrap();
|
||||||
|
assert!(matches!(input, Key::Test));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,9 +18,6 @@ use controller::Controller;
|
|||||||
pub mod utils;
|
pub mod utils;
|
||||||
//use utils::Rect;
|
//use utils::Rect;
|
||||||
|
|
||||||
mod winit_window;
|
|
||||||
//use winit_window::WinitWindow;
|
|
||||||
|
|
||||||
mod renderer;
|
mod renderer;
|
||||||
//use renderer::Renderer;
|
//use renderer::Renderer;
|
||||||
|
|
||||||
@ -63,7 +60,7 @@ pub fn run() -> Result<(), &'static str> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
winit_window::WinitWindow,
|
io::WinitWindow,
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
utils::Rect,
|
utils::Rect,
|
||||||
subengine::{SubengineController, TestSubengine},
|
subengine::{SubengineController, TestSubengine},
|
||||||
@ -112,7 +109,7 @@ pub fn run() -> Result<(), &'static str> {
|
|||||||
//let controller = Controller::new(renderers, &windows, &windows, engine_pipelines);
|
//let controller = Controller::new(renderers, &windows, &windows, engine_pipelines);
|
||||||
//controller.run();
|
//controller.run();
|
||||||
|
|
||||||
Ok(())
|
//Ok(())
|
||||||
//let local_state = LocalState::default();
|
//let local_state = LocalState::default();
|
||||||
|
|
||||||
// let color = [0.5, 0.0, 0.0, 1.0];
|
// let color = [0.5, 0.0, 0.0, 1.0];
|
||||||
|
|||||||
@ -197,6 +197,8 @@ where
|
|||||||
}},
|
}},
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
}};
|
}};
|
||||||
|
//println!("Frame nb : {}", self.frames.len());
|
||||||
|
//frames number diminish sometimes at resize...
|
||||||
let mut frame = self.frames.pop_back().unwrap();
|
let mut frame = self.frames.pop_back().unwrap();
|
||||||
|
|
||||||
trace!("Creating Framebuffer...");
|
trace!("Creating Framebuffer...");
|
||||||
@ -211,19 +213,16 @@ where
|
|||||||
.unwrap() //TODO improve that
|
.unwrap() //TODO improve that
|
||||||
};
|
};
|
||||||
|
|
||||||
frame.link_swapchain_image(image, framebuffer);
|
frame.link_swapchain_image(gpu, image, framebuffer);
|
||||||
|
|
||||||
Ok(frame)
|
Ok(frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn present_frame(&mut self, mut frame: Frame<B>, gpu: &mut Gpu<B>)
|
pub fn present_frame(&mut self, mut frame: Frame<B>, gpu: &mut Gpu<B>)
|
||||||
-> Result<(), &'static str> {
|
-> Result<(), &'static str> {
|
||||||
use gfx_hal::{
|
use gfx_hal::queue::CommandQueue;
|
||||||
queue::CommandQueue,
|
|
||||||
device::Device,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (image, framebuffer) = frame
|
let image = frame
|
||||||
.unlink_swapchain_image()
|
.unlink_swapchain_image()
|
||||||
.unwrap(); //TODO improve that
|
.unwrap(); //TODO improve that
|
||||||
|
|
||||||
@ -236,11 +235,6 @@ where
|
|||||||
|
|
||||||
self.frames.push_front(frame);
|
self.frames.push_front(frame);
|
||||||
|
|
||||||
trace!("Destroying Framebuffer...");
|
|
||||||
unsafe {
|
|
||||||
gpu.device().destroy_framebuffer(framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,22 +98,28 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_swapchain_image(&mut self,
|
pub fn link_swapchain_image(&mut self,
|
||||||
|
gpu: &Gpu<B>,
|
||||||
image: <B::Surface as PresentationSurface<B>>::SwapchainImage,
|
image: <B::Surface as PresentationSurface<B>>::SwapchainImage,
|
||||||
framebuffer: B::Framebuffer) {
|
framebuffer: B::Framebuffer) {
|
||||||
|
use gfx_hal::device::Device;
|
||||||
|
|
||||||
|
match self.framebuffer.replace(framebuffer) {
|
||||||
|
Some(old_framebuffer) => {
|
||||||
|
trace!("Destroying Framebuffer...");
|
||||||
|
unsafe { gpu.device().destroy_framebuffer(old_framebuffer) };
|
||||||
|
},
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
|
||||||
self.image_view = Some(image);
|
self.image_view = Some(image);
|
||||||
self.framebuffer = Some(framebuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unlink_swapchain_image(&mut self)
|
pub fn unlink_swapchain_image(&mut self)
|
||||||
-> Result<(<B::Surface as PresentationSurface<B>>::SwapchainImage,
|
-> Result<<B::Surface as PresentationSurface<B>>::SwapchainImage, &'static str> {
|
||||||
B::Framebuffer), &'static str> {
|
|
||||||
|
|
||||||
match (self.image_view.take(), self.framebuffer.take()) {
|
self.image_view
|
||||||
(Some(image_view), Some(framebuffer)) => Some((image_view, framebuffer)),
|
.take()
|
||||||
_ => None,
|
.ok_or("Can not unlink non-linked Frame !")
|
||||||
}
|
|
||||||
.ok_or("Can not unlink non-linked Frame !")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,18 +107,18 @@ enum SubengineResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--Tests-------------------------------------------------------------------------------------------
|
//--Tests-------------------------------------------------------------------------------------------
|
||||||
#[cfg(test)]
|
//#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::subengine::TestSubengine;
|
use crate::subengine::TestSubengine;
|
||||||
|
|
||||||
#[test]
|
//#[test]
|
||||||
fn test_new_drop() {
|
fn test_new_drop() {
|
||||||
let (test_subengine, _test_rx) = TestSubengine::new("run");
|
let (test_subengine, _test_rx) = TestSubengine::new("run");
|
||||||
let subengine_controller = SubengineController::new(test_subengine);
|
let _subengine_controller = SubengineController::new(test_subengine);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
//#[test]
|
||||||
fn test_exec() {
|
fn test_exec() {
|
||||||
let (test_subengine, test_rx) = TestSubengine::new("run");
|
let (test_subengine, test_rx) = TestSubengine::new("run");
|
||||||
let subengine_controller = SubengineController::new(test_subengine);
|
let subengine_controller = SubengineController::new(test_subengine);
|
||||||
@ -128,7 +128,7 @@ mod tests {
|
|||||||
assert_eq!(response, "run");
|
assert_eq!(response, "run");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
//#[test]
|
||||||
fn test_wait_for_exec() {
|
fn test_wait_for_exec() {
|
||||||
let (test_subengine, _test_rx) = TestSubengine::new("run");
|
let (test_subengine, _test_rx) = TestSubengine::new("run");
|
||||||
let subengine_controller = SubengineController::new(test_subengine);
|
let subengine_controller = SubengineController::new(test_subengine);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user