Compare commits
1 commit
70b03e10ef
...
589a2d1b65
Author | SHA1 | Date | |
---|---|---|---|
589a2d1b65 |
15 changed files with 296 additions and 366 deletions
|
@ -58,18 +58,18 @@ impl Context {
|
||||||
&mut self.sound_handler
|
&mut self.sound_handler
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn events<'a, F>(&mut self, world: &World, mut f: F) -> Result<bool>
|
pub fn next_frame<'a, C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_>) -> Result<()> + Send + Sync + 'a,
|
C: ResourceTrait + Send + Sync + 'static,
|
||||||
|
F: FnMut(&mut World, &mut C, Event<'_>) -> Result<()> + Send + Sync + 'a,
|
||||||
{
|
{
|
||||||
let render_core = self.render_core.clone();
|
let render_core = self.render_core.clone();
|
||||||
|
let consumer = world.resources.get_mut_unchecked::<C>();
|
||||||
|
let w = unsafe { remove_life_time_mut(world) };
|
||||||
|
|
||||||
match self.presentation.poll_events(
|
match self.presentation.poll_events(
|
||||||
|event| f(event),
|
|event| f(w, consumer, event),
|
||||||
|w, h| {
|
|w, h| render_core.write().unwrap().resize(world, w, h),
|
||||||
render_core.write().unwrap().resize(world, w, h);
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
if !res {
|
if !res {
|
||||||
|
@ -84,28 +84,13 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.render_core_mut().next_frame(world)? {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_frame(&self, world: &World) -> Result<()> {
|
|
||||||
self.render_core_mut().begin_frame(world)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render<F>(&self, render: F) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(
|
|
||||||
&mut CommandBufferRecorder<'_>,
|
|
||||||
&TargetMode<Vec<Arc<Image>>>,
|
|
||||||
&TargetMode<usize>,
|
|
||||||
) -> Result<()>,
|
|
||||||
{
|
|
||||||
self.render_core_mut().render(render)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn end_frame(&self, world: &World) -> Result<()> {
|
|
||||||
self.render_core_mut().end_frame(world)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_core(&self) -> impl Deref<Target = RenderCore> + '_ {
|
pub fn render_core(&self) -> impl Deref<Target = RenderCore> + '_ {
|
||||||
self.render_core.read().unwrap()
|
self.render_core.read().unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,33 @@ use crate::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
pub struct GuiHandlerRenderer;
|
||||||
|
|
||||||
|
impl TScene for GuiHandlerRenderer {
|
||||||
|
fn process(
|
||||||
|
&mut self,
|
||||||
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
|
_images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
|
indices: &TargetMode<usize>,
|
||||||
|
world: &mut World,
|
||||||
|
) -> Result<()> {
|
||||||
|
let gui_handler: &mut GuiHandler = world.resources.get_mut()?;
|
||||||
|
gui_handler.process(buffer_recorder, indices)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize(
|
||||||
|
&mut self,
|
||||||
|
window_width: f32,
|
||||||
|
window_height: f32,
|
||||||
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
|
world: &mut World,
|
||||||
|
) -> Result<()> {
|
||||||
|
let gui_handler: &mut GuiHandler = world.resources.get_mut()?;
|
||||||
|
gui_handler.resize(window_width as u32, window_height as u32, images)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
pub(crate) resource_base_path: String,
|
pub(crate) resource_base_path: String,
|
||||||
|
@ -146,6 +173,11 @@ impl Engine {
|
||||||
let asset_manager = AssetManager::new(&engine_settings)?;
|
let asset_manager = AssetManager::new(&engine_settings)?;
|
||||||
let gui_handler = GuiHandler::new(create_info.gui_info, &context)?;
|
let gui_handler = GuiHandler::new(create_info.gui_info, &context)?;
|
||||||
|
|
||||||
|
context
|
||||||
|
.render_core_mut()
|
||||||
|
.add_render_routine::<GuiHandlerRenderer>(10_000_000);
|
||||||
|
context.render_core_mut().add_render_routine::<Scene>(100);
|
||||||
|
|
||||||
world.resources.insert(context);
|
world.resources.insert(context);
|
||||||
|
|
||||||
Scene::new(
|
Scene::new(
|
||||||
|
@ -163,6 +195,7 @@ impl Engine {
|
||||||
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
||||||
|
|
||||||
world.resources.insert(gui_handler);
|
world.resources.insert(gui_handler);
|
||||||
|
world.resources.insert(GuiHandlerRenderer);
|
||||||
world.resources.insert(InputMap { direction_mapping });
|
world.resources.insert(InputMap { direction_mapping });
|
||||||
world.resources.insert(asset_manager);
|
world.resources.insert(asset_manager);
|
||||||
world.resources.insert(Engine {
|
world.resources.insert(Engine {
|
||||||
|
@ -170,11 +203,7 @@ impl Engine {
|
||||||
});
|
});
|
||||||
world.resources.insert(engine_settings);
|
world.resources.insert(engine_settings);
|
||||||
|
|
||||||
world.add_system(1, Self::start_frame);
|
world.add_system(1_000_000, Self::main_system::<T>);
|
||||||
world.add_system(u32::MAX, Self::end_frame);
|
|
||||||
|
|
||||||
world.add_system(100, Self::render_scene);
|
|
||||||
world.add_system(10_000_000, Self::render_gui);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -217,46 +246,20 @@ impl Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
fn start_frame(world: &World, _commands: &mut Commands, context: &mut Context) -> Result<bool> {
|
fn main_system<T: ResourceTrait + EventConsumer>(world: &mut World) -> Result<bool> {
|
||||||
context.start_frame(world)?;
|
let gui_handler = world.resources.get_mut_unchecked::<GuiHandler>();
|
||||||
|
let input_map = world.resources.get_unchecked::<InputMap>();
|
||||||
|
let context = world.resources.get_unchecked::<Context>();
|
||||||
|
|
||||||
Ok(true)
|
let res = world.resources.get_mut_unchecked::<Context>().next_frame(
|
||||||
}
|
world,
|
||||||
|
|world, consumer: &mut T, event| {
|
||||||
fn end_frame(world: &World, _commands: &mut Commands, context: &mut Context) -> Result<bool> {
|
Self::event(world, context, gui_handler, input_map, consumer, event)
|
||||||
context.end_frame(world)?;
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_scene(
|
|
||||||
world: &World,
|
|
||||||
_commands: &mut Commands,
|
|
||||||
context: &mut Context,
|
|
||||||
scene: &mut Scene,
|
|
||||||
) -> Result<bool> {
|
|
||||||
context.render(
|
|
||||||
|recorder: &mut CommandBufferRecorder<'_>,
|
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
|
||||||
indices: &TargetMode<usize>| {
|
|
||||||
scene.process(recorder, images, indices, world)
|
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(true)
|
gui_handler.process_callbacks(world)?;
|
||||||
}
|
|
||||||
|
|
||||||
fn render_gui(
|
Ok(res)
|
||||||
_commands: &mut Commands,
|
|
||||||
context: &mut Context,
|
|
||||||
gui_handler: &mut GuiHandler,
|
|
||||||
) -> Result<bool> {
|
|
||||||
context.render(
|
|
||||||
|recorder: &mut CommandBufferRecorder<'_>,
|
|
||||||
_images: &TargetMode<Vec<Arc<Image>>>,
|
|
||||||
indices: &TargetMode<usize>| { gui_handler.process(recorder, indices) },
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ecs::{Resource, resources::Resource as ResourceTrait};
|
use ecs::Resource;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -28,118 +28,89 @@ pub enum EngineEvent<'a> {
|
||||||
FileDrop(String),
|
FileDrop(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait EventConsumer: Send + Sync + 'static {
|
||||||
|
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct InputMap {
|
pub struct InputMap {
|
||||||
pub direction_mapping: HashMap<Keycode, GuiDirection>,
|
pub direction_mapping: HashMap<Keycode, GuiDirection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait EventSystem<Func, T> {
|
|
||||||
fn event_system(world_builder: &mut WorldBuilder, func: Func);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Func, T> EventSystem<Func, T> for Engine
|
|
||||||
where
|
|
||||||
Func: Fn(&mut T, &mut Commands, EngineEvent<'_>) -> Result<()> + Send + Sync + 'static,
|
|
||||||
T: ResourceTrait,
|
|
||||||
{
|
|
||||||
fn event_system(world_builder: &mut WorldBuilder, func: Func) {
|
|
||||||
world_builder.add_system(
|
|
||||||
0,
|
|
||||||
|world: &World,
|
|
||||||
commands: &mut Commands,
|
|
||||||
consumer: &mut T,
|
|
||||||
gui_handler: &mut GuiHandler,
|
|
||||||
input_map: &mut InputMap,
|
|
||||||
context: &mut Context|
|
|
||||||
-> Result<bool> {
|
|
||||||
let res = context.events(world, |event| {
|
|
||||||
Self::event(commands, gui_handler, input_map, consumer, event, func)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
gui_handler.process_callbacks(commands)?;
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub(crate) fn event<T>(
|
pub(crate) fn event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
|
context: &Context,
|
||||||
gui_handler: &mut GuiHandler,
|
gui_handler: &mut GuiHandler,
|
||||||
input: &InputMap,
|
input: &InputMap,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
event: Event<'_>,
|
event: Event<'_>,
|
||||||
func: Func,
|
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
match event {
|
match event {
|
||||||
Event::MouseMotion(x, y) => {
|
Event::MouseMotion(x, y) => {
|
||||||
gui_handler.set_mouse_pos(x, y)?;
|
gui_handler.set_mouse_pos(x, y)?;
|
||||||
consumer.event(commands, EngineEvent::MouseMotion(x, y))?;
|
consumer.event(world, EngineEvent::MouseMotion(x, y))?;
|
||||||
}
|
}
|
||||||
Event::MouseButtonDown(mouse_button) => {
|
Event::MouseButtonDown(mouse_button) => {
|
||||||
if !gui_handler.mouse_down(mouse_button)? {
|
if !gui_handler.mouse_down(mouse_button)? {
|
||||||
consumer.event(commands, EngineEvent::MouseButtonDown(mouse_button))?;
|
consumer.event(world, EngineEvent::MouseButtonDown(mouse_button))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::MouseButtonUp(mouse_button) => {
|
Event::MouseButtonUp(mouse_button) => {
|
||||||
if !gui_handler.mouse_up(mouse_button)? {
|
if !gui_handler.mouse_up(mouse_button)? {
|
||||||
consumer.event(commands, EngineEvent::MouseButtonUp(mouse_button))?;
|
consumer.event(world, EngineEvent::MouseButtonUp(mouse_button))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::MouseWheel(x, y, direction) => {
|
Event::MouseWheel(x, y, direction) => {
|
||||||
consumer.event(commands, EngineEvent::MouseWheel(x, y, direction))?
|
consumer.event(world, EngineEvent::MouseWheel(x, y, direction))?
|
||||||
}
|
}
|
||||||
Event::KeyDown(keycode) => {
|
Event::KeyDown(keycode) => {
|
||||||
Self::key_down_event(commands, gui_handler, input, consumer, keycode)?;
|
Self::key_down_event(world, context, gui_handler, input, consumer, keycode)?;
|
||||||
}
|
}
|
||||||
Event::KeyUp(keycode) => {
|
Event::KeyUp(keycode) => {
|
||||||
Self::key_up_event(commands, gui_handler, input, consumer, keycode)?;
|
Self::key_up_event(world, gui_handler, input, consumer, keycode)?;
|
||||||
}
|
}
|
||||||
Event::TextInput(text) => {
|
Event::TextInput(text) => {
|
||||||
Self::text_input(gui_handler, text)?;
|
Self::text_input(gui_handler, text)?;
|
||||||
}
|
}
|
||||||
Event::ControllerButtonDown(controller, button) => {
|
Event::ControllerButtonDown(controller, button) => {
|
||||||
Self::button_down_event(commands, gui_handler, consumer, controller, button)?;
|
Self::button_down_event(world, gui_handler, consumer, controller, button)?;
|
||||||
}
|
}
|
||||||
Event::ControllerButtonUp(controller, button) => {
|
Event::ControllerButtonUp(controller, button) => {
|
||||||
Self::button_up_event(commands, consumer, controller, button)?;
|
Self::button_up_event(world, consumer, controller, button)?;
|
||||||
}
|
}
|
||||||
Event::ControllerAxis(controller) => {
|
Event::ControllerAxis(controller) => {
|
||||||
if !gui_handler.check_navigatable() {
|
if !gui_handler.check_navigatable() {
|
||||||
Self::axis_event(commands, consumer, &controller)?
|
Self::axis_event(world, consumer, &controller)?
|
||||||
} else {
|
} else {
|
||||||
gui_handler.update_selection(controller.direction())?;
|
gui_handler.update_selection(controller.direction())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::ControllerAdded(controller) => {
|
Event::ControllerAdded(controller) => {
|
||||||
Self::controller_added(commands, consumer, controller)?
|
Self::controller_added(world, consumer, controller)?
|
||||||
}
|
}
|
||||||
Event::ControllerRemoved(controller) => {
|
Event::ControllerRemoved(controller) => {
|
||||||
Self::controller_removed(commands, consumer, controller)?
|
Self::controller_removed(world, consumer, controller)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::JoystickAxis(joystick, axis_index, value) => consumer.event(
|
Event::JoystickAxis(joystick, axis_index, value) => consumer.event(
|
||||||
commands,
|
world,
|
||||||
EngineEvent::JoystickAxis(joystick, axis_index, value),
|
EngineEvent::JoystickAxis(joystick, axis_index, value),
|
||||||
)?,
|
)?,
|
||||||
Event::JoystickButtonDown(joystick) => {
|
Event::JoystickButtonDown(joystick) => {
|
||||||
consumer.event(commands, EngineEvent::JoystickButtonDown(joystick))?
|
consumer.event(world, EngineEvent::JoystickButtonDown(joystick))?
|
||||||
}
|
}
|
||||||
Event::JoystickButtonUp(joystick) => {
|
Event::JoystickButtonUp(joystick) => {
|
||||||
consumer.event(commands, EngineEvent::JoystickButtonUp(joystick))?
|
consumer.event(world, EngineEvent::JoystickButtonUp(joystick))?
|
||||||
}
|
}
|
||||||
Event::JoystickAdded(joystick) => {
|
Event::JoystickAdded(joystick) => {
|
||||||
consumer.event(commands, EngineEvent::JoystickAdded(joystick))?
|
consumer.event(world, EngineEvent::JoystickAdded(joystick))?
|
||||||
}
|
}
|
||||||
Event::JoystickRemoved(joystick) => {
|
Event::JoystickRemoved(joystick) => {
|
||||||
consumer.event(commands, EngineEvent::JoystickRemoved(joystick))?
|
consumer.event(world, EngineEvent::JoystickRemoved(joystick))?
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::FileDrop(filename) => {
|
Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?,
|
||||||
consumer.event(commands, EngineEvent::FileDrop(filename))?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -149,29 +120,29 @@ impl Engine {
|
||||||
impl Engine {
|
impl Engine {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn controller_added<T: EventConsumer>(
|
fn controller_added<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
consumer.event(commands, EngineEvent::ControllerAdded(controller))?;
|
consumer.event(world, EngineEvent::ControllerAdded(controller))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn controller_removed<T: EventConsumer>(
|
fn controller_removed<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
consumer.event(commands, EngineEvent::ControllerRemoved(controller))?;
|
consumer.event(world, EngineEvent::ControllerRemoved(controller))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn key_up_event<T: EventConsumer>(
|
fn key_up_event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
gui_handler: &mut GuiHandler,
|
gui_handler: &mut GuiHandler,
|
||||||
input: &InputMap,
|
input: &InputMap,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
|
@ -183,14 +154,15 @@ impl Engine {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer.event(commands, EngineEvent::KeyUp(keycode))?;
|
consumer.event(world, EngineEvent::KeyUp(keycode))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn key_down_event<T: EventConsumer>(
|
fn key_down_event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
|
context: &Context,
|
||||||
gui_handler: &mut GuiHandler,
|
gui_handler: &mut GuiHandler,
|
||||||
input: &InputMap,
|
input: &InputMap,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
|
@ -214,49 +186,50 @@ impl Engine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keycode::Escape => {
|
Keycode::Escape => {
|
||||||
if gui_handler.decline_topgui(commands)? {
|
if gui_handler.decline_topgui(world)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Keycode::V => {
|
||||||
|
if let Some(writeable) = gui_handler.writeable() {
|
||||||
|
if let Some(content) = context.window_config().clipboard_content()? {
|
||||||
|
writeable.set_text(gui_handler, content)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer.event(commands, EngineEvent::KeyDown(keycode))?;
|
consumer.event(world, EngineEvent::KeyDown(keycode))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn button_up_event<T: EventConsumer>(
|
fn button_up_event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
button: ControllerButton,
|
button: ControllerButton,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
consumer.event(
|
consumer.event(world, EngineEvent::ControllerButtonUp(controller, button))?;
|
||||||
commands,
|
|
||||||
EngineEvent::ControllerButtonUp(controller, button),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn button_down_event<T: EventConsumer>(
|
fn button_down_event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
gui_handler: &mut GuiHandler,
|
gui_handler: &mut GuiHandler,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
button: ControllerButton,
|
button: ControllerButton,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if gui_handler.check_navigatable() {
|
if gui_handler.check_navigatable() {
|
||||||
Self::check_button_down(commands, gui_handler, consumer, controller, button)?;
|
Self::check_button_down(world, gui_handler, consumer, controller, button)?;
|
||||||
} else {
|
} else {
|
||||||
consumer.event(
|
consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?;
|
||||||
commands,
|
|
||||||
EngineEvent::ControllerButtonDown(controller, button),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -264,12 +237,12 @@ impl Engine {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn axis_event<T: EventConsumer>(
|
fn axis_event<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
consumer.event(
|
consumer.event(
|
||||||
commands,
|
world,
|
||||||
EngineEvent::ControllerAxis(controller, controller.controller_axis()),
|
EngineEvent::ControllerAxis(controller, controller.controller_axis()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -278,7 +251,7 @@ impl Engine {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_button_down<T: EventConsumer>(
|
fn check_button_down<T: EventConsumer>(
|
||||||
commands: &mut Commands,
|
world: &mut World,
|
||||||
gui_handler: &mut GuiHandler,
|
gui_handler: &mut GuiHandler,
|
||||||
consumer: &mut T,
|
consumer: &mut T,
|
||||||
controller: &Controller,
|
controller: &Controller,
|
||||||
|
@ -292,31 +265,31 @@ impl Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerButton::B => {
|
ControllerButton::B => {
|
||||||
if gui_handler.decline_topgui(commands)? {
|
if gui_handler.decline_topgui(world)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerButton::RightButton => {
|
ControllerButton::RightButton => {
|
||||||
if gui_handler.next_tab_topgui(commands, false)? {
|
if gui_handler.next_tab_topgui(world, false)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerButton::LeftButton => {
|
ControllerButton::LeftButton => {
|
||||||
if gui_handler.previous_tab_topgui(commands, false)? {
|
if gui_handler.previous_tab_topgui(world, false)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerButton::RightTrigger => {
|
ControllerButton::RightTrigger => {
|
||||||
if gui_handler.next_tab_topgui(commands, true)? {
|
if gui_handler.next_tab_topgui(world, true)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerButton::LeftTrigger => {
|
ControllerButton::LeftTrigger => {
|
||||||
if gui_handler.previous_tab_topgui(commands, true)? {
|
if gui_handler.previous_tab_topgui(world, true)? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,11 +333,8 @@ impl Engine {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gui_handler.accept_custom_selection(commands, button)? {
|
if !gui_handler.accept_custom_selection(world, button)? {
|
||||||
consumer.event(
|
consumer.event(world, EngineEvent::ControllerButtonDown(controller, button))?;
|
||||||
commands,
|
|
||||||
EngineEvent::ControllerButtonDown(controller, button),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub use crate::engine::{
|
||||||
asset_handler::{AssetHandler, AssetLoader},
|
asset_handler::{AssetHandler, AssetLoader},
|
||||||
engine::*,
|
engine::*,
|
||||||
engine_create_info::EngineCreateInfo,
|
engine_create_info::EngineCreateInfo,
|
||||||
engine_event_handling::{EngineEvent, EventConsumer, EventSystem},
|
engine_event_handling::{EngineEvent, EventConsumer},
|
||||||
engine_settings::*,
|
engine_settings::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ impl TScene for Scene {
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
indices: &TargetMode<usize>,
|
indices: &TargetMode<usize>,
|
||||||
world: &World,
|
world: &mut World,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
self.frame_time = {
|
self.frame_time = {
|
||||||
let now = world.now();
|
let now = world.now();
|
||||||
|
@ -484,7 +484,7 @@ impl TScene for Scene {
|
||||||
window_width: f32,
|
window_width: f32,
|
||||||
window_height: f32,
|
window_height: f32,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
_world: &World,
|
_world: &mut World,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
self.screen_width = window_width;
|
self.screen_width = window_width;
|
||||||
self.screen_height = window_height;
|
self.screen_height = window_height;
|
||||||
|
|
|
@ -109,14 +109,11 @@ impl InputSettings {
|
||||||
pub struct Game;
|
pub struct Game;
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn update(
|
pub fn update(&mut self, world: &mut World) -> Result<()> {
|
||||||
&mut self,
|
|
||||||
commands: &mut Commands,
|
|
||||||
scene: &mut Scene,
|
|
||||||
camera_control: &mut FreeCameraControl,
|
|
||||||
) -> Result<()> {
|
|
||||||
if FREE_CAMERA_CONTROL {
|
if FREE_CAMERA_CONTROL {
|
||||||
let now = commands.now();
|
let now = world.now();
|
||||||
|
let (scene, camera_control): (&mut Scene, &mut FreeCameraControl) =
|
||||||
|
world.resources.get_mut()?;
|
||||||
|
|
||||||
camera_control.update(now, scene.view_mut())?;
|
camera_control.update(now, scene.view_mut())?;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +121,7 @@ impl Game {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event(&mut self, commands: &mut Commands, event: EngineEvent<'_>) -> Result<()> {
|
pub fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||||
if let Some(event) = Self::motion_concepts(world, event)? {
|
if let Some(event) = Self::motion_concepts(world, event)? {
|
||||||
match event {
|
match event {
|
||||||
EngineEvent::JoystickAdded(joystick) => {
|
EngineEvent::JoystickAdded(joystick) => {
|
||||||
|
|
|
@ -14,15 +14,12 @@ pub enum GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameState {
|
impl GameState {
|
||||||
pub fn update(
|
pub fn update(world: &mut World) -> Result<bool> {
|
||||||
commands: &mut Commands,
|
let me = world.resources.get_mut_unchecked::<Self>();
|
||||||
game_state: &mut GameState,
|
|
||||||
scene: &mut Scene,
|
match me {
|
||||||
camera_control: &mut FreeCameraControl,
|
GameState::Startup => *me = GameState::Game(Game),
|
||||||
) -> Result<bool> {
|
GameState::Game(game) => game.update(world)?,
|
||||||
match game_state {
|
|
||||||
GameState::Startup => *game_state = GameState::Game(Game),
|
|
||||||
GameState::Game(game) => game.update(commands, scene, camera_control)?,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -30,10 +27,10 @@ impl GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventConsumer for GameState {
|
impl EventConsumer for GameState {
|
||||||
fn event(&mut self, commands: &mut Commands, event: EngineEvent<'_>) -> Result<()> {
|
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
GameState::Startup => (),
|
GameState::Startup => (),
|
||||||
GameState::Game(game) => game.event(commands, event)?,
|
GameState::Game(game) => game.event(world, event)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -3,32 +3,14 @@ use anyhow::Result;
|
||||||
use ecs::*;
|
use ecs::*;
|
||||||
use engine::prelude::*;
|
use engine::prelude::*;
|
||||||
|
|
||||||
struct CameraControlStart;
|
|
||||||
struct CameraControlEnd;
|
|
||||||
struct CameraControlMove {
|
|
||||||
x: u32,
|
|
||||||
y: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut world_builder = World::builder();
|
let mut world_builder = World::builder();
|
||||||
|
|
||||||
Engine::new::<GameState>(EngineCreateInfo::default(), &mut world_builder)?;
|
Engine::new::<GameState>(EngineCreateInfo::default(), &mut world_builder)?;
|
||||||
Engine::event_system(&mut world_builder);
|
|
||||||
|
|
||||||
world_builder.add_system(10, GameState::update);
|
world_builder.add_system(10, GameState::update);
|
||||||
world_builder.resources.insert(GameState::default());
|
world_builder.resources.insert(GameState::default());
|
||||||
|
|
||||||
world_builder.events.register_event::<CameraControlStart>();
|
|
||||||
world_builder.events.register_event::<CameraControlEnd>();
|
|
||||||
world_builder.events.register_event::<CameraControlMove>();
|
|
||||||
|
|
||||||
world_builder.events.add_reader(Game::enable_camera_control);
|
|
||||||
world_builder
|
|
||||||
.events
|
|
||||||
.add_reader(Game::disable_camera_control);
|
|
||||||
world_builder.events.add_reader(Game::update_mouse);
|
|
||||||
|
|
||||||
let scene: &mut Scene = world_builder.resources.get_mut()?;
|
let scene: &mut Scene = world_builder.resources.get_mut()?;
|
||||||
let view = scene.view_mut();
|
let view = scene.view_mut();
|
||||||
let camera_control = FreeCameraControl::new(view)?;
|
let camera_control = FreeCameraControl::new(view)?;
|
||||||
|
@ -46,10 +28,12 @@ enum GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameState {
|
impl GameState {
|
||||||
fn update(commands: &mut Commands, game_state: &mut GameState) -> Result<bool> {
|
fn update(world: &mut World) -> Result<bool> {
|
||||||
match game_state {
|
let me = world.resources.get_mut_unchecked::<Self>();
|
||||||
GameState::Startup => *game_state = GameState::Game(Game),
|
|
||||||
GameState::Game(game) => game.update(commands)?,
|
match me {
|
||||||
|
GameState::Startup => *me = GameState::Game(Game),
|
||||||
|
GameState::Game(game) => game.update(world)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -57,10 +41,10 @@ impl GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventConsumer for GameState {
|
impl EventConsumer for GameState {
|
||||||
fn event(&mut self, commands: &mut Commands, event: EngineEvent<'_>) -> Result<()> {
|
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
GameState::Startup => (),
|
GameState::Startup => (),
|
||||||
GameState::Game(game) => game.event(commands, event)?,
|
GameState::Game(game) => game.event(world, event)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -70,48 +54,26 @@ impl EventConsumer for GameState {
|
||||||
struct Game;
|
struct Game;
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
fn enable_camera_control(
|
fn update(&mut self, _world: &mut World) -> Result<()> {
|
||||||
_: &CameraControlStart,
|
|
||||||
_commands: &mut Commands,
|
|
||||||
camera_control: &mut FreeCameraControl,
|
|
||||||
) -> Result<()> {
|
|
||||||
camera_control.mouse_down();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_camera_control(
|
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||||
_: &CameraControlEnd,
|
|
||||||
_commands: &mut Commands,
|
|
||||||
camera_control: &mut FreeCameraControl,
|
|
||||||
) -> Result<()> {
|
|
||||||
camera_control.mouse_release();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_mouse(
|
|
||||||
camera_move: &CameraControlMove,
|
|
||||||
_commands: &mut Commands,
|
|
||||||
camera_control: &mut FreeCameraControl,
|
|
||||||
scene: &mut Scene,
|
|
||||||
) -> Result<()> {
|
|
||||||
camera_control.mouse_move(camera_move.x, camera_move.y, scene.view_mut())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, _commands: &mut Commands) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn event(&mut self, commands: &mut Commands, event: EngineEvent<'_>) -> Result<()> {
|
|
||||||
match event {
|
match event {
|
||||||
EngineEvent::MouseButtonDown(MouseButton::Left) => {
|
EngineEvent::MouseButtonDown(MouseButton::Left) => {
|
||||||
commands.write_event(CameraControlStart)
|
let camera_control: &mut FreeCameraControl = world.resources.get_mut()?;
|
||||||
|
camera_control.mouse_down();
|
||||||
|
}
|
||||||
|
EngineEvent::MouseButtonUp(MouseButton::Left) => {
|
||||||
|
let camera_control: &mut FreeCameraControl = world.resources.get_mut()?;
|
||||||
|
camera_control.mouse_release();
|
||||||
|
}
|
||||||
|
EngineEvent::MouseMotion(x, y) => {
|
||||||
|
let (scene, camera_control): (&mut Scene, &mut FreeCameraControl) =
|
||||||
|
world.resources.get_mut()?;
|
||||||
|
|
||||||
|
camera_control.mouse_move(x, y, scene.view_mut())?;
|
||||||
}
|
}
|
||||||
EngineEvent::MouseButtonUp(MouseButton::Left) => commands.write_event(CameraControlEnd),
|
|
||||||
EngineEvent::MouseMotion(x, y) => commands.write_event(CameraControlMove { x, y }),
|
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use context::prelude::*;
|
use context::prelude::*;
|
||||||
use ecs::Commands;
|
use ecs::World;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
sync::{
|
sync::{
|
||||||
|
@ -26,18 +26,13 @@ where
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
G: TopLevelGui + TopGui + Send + Sync + 'static,
|
G: TopLevelGui + TopGui + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
pub fn load<R, L>(
|
pub fn load<R, L>(world: &mut World, gui: Arc<G>, loader: L) -> Result<Self>
|
||||||
commands: &mut Commands,
|
|
||||||
gui_handler: &mut GuiHandler,
|
|
||||||
gui: Arc<G>,
|
|
||||||
loader: L,
|
|
||||||
) -> Result<Self>
|
|
||||||
where
|
where
|
||||||
R: Fn(T) -> Result<()> + Send + Sync + 'static,
|
R: Fn(T) -> Result<()> + Send + Sync + 'static,
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
L: FnOnce() -> T + Send + Sync + 'static,
|
L: FnOnce() -> T + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
gui.enable(commands, gui_handler)?;
|
gui.enable(world)?;
|
||||||
|
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = channel();
|
||||||
|
|
||||||
|
@ -66,12 +61,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_result(
|
pub fn take_result(mut self, world: &mut World) -> Result<T> {
|
||||||
mut self,
|
self.gui.disable(world)?;
|
||||||
commands: &mut Commands,
|
|
||||||
gui_handler: &mut GuiHandler,
|
|
||||||
) -> Result<T> {
|
|
||||||
self.gui.disable(commands, gui_handler)?;
|
|
||||||
self.result
|
self.result
|
||||||
.take()
|
.take()
|
||||||
.ok_or(anyhow!("missing loading screen payload!"))
|
.ok_or(anyhow!("missing loading screen payload!"))
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
use cgmath::{Matrix4, SquareMatrix};
|
use cgmath::{Matrix4, SquareMatrix};
|
||||||
use ecs::World;
|
use ecs::World;
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
|
use std::any::TypeId;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
Arc, Mutex, RwLock,
|
Arc, Mutex, RwLock,
|
||||||
|
@ -47,6 +49,52 @@ impl Default for VRTransformations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SceneHandle {
|
||||||
|
type_id: TypeId,
|
||||||
|
priority: u32,
|
||||||
|
|
||||||
|
render: Box<
|
||||||
|
dyn FnMut(
|
||||||
|
&mut CommandBufferRecorder<'_>,
|
||||||
|
&TargetMode<Vec<Arc<Image>>>,
|
||||||
|
&TargetMode<usize>,
|
||||||
|
&mut World,
|
||||||
|
) -> Result<()>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
>,
|
||||||
|
|
||||||
|
resize: Box<
|
||||||
|
dyn FnMut(f32, f32, &TargetMode<Vec<Arc<Image>>>, &mut World) -> Result<()>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SceneHandle {
|
||||||
|
fn new<T: TScene>(priority: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
type_id: TypeId::of::<T>(),
|
||||||
|
priority,
|
||||||
|
render: Box::new(|recorder, images, indices, world| {
|
||||||
|
world
|
||||||
|
.resources
|
||||||
|
.get_mut_unchecked::<T>()
|
||||||
|
.process(recorder, images, indices, world)
|
||||||
|
}),
|
||||||
|
|
||||||
|
resize: Box::new(|width, height, images, world| {
|
||||||
|
world
|
||||||
|
.resources
|
||||||
|
.get_mut_unchecked::<T>()
|
||||||
|
.resize(width, height, images, world)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct RenderBackend {
|
pub struct RenderBackend {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<Mutex<Queue>>,
|
queue: Arc<Mutex<Queue>>,
|
||||||
|
@ -58,11 +106,9 @@ pub struct RenderBackend {
|
||||||
clear_color: RwLock<VkClearColorValue>,
|
clear_color: RwLock<VkClearColorValue>,
|
||||||
|
|
||||||
command_buffer: Arc<CommandBuffer>,
|
command_buffer: Arc<CommandBuffer>,
|
||||||
buffer_recorder: Option<CommandBufferRecorder<'static>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for RenderBackend {}
|
render_routines: Vec<SceneHandle>,
|
||||||
unsafe impl Sync for RenderBackend {}
|
}
|
||||||
|
|
||||||
impl RenderBackend {
|
impl RenderBackend {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -91,7 +137,8 @@ impl RenderBackend {
|
||||||
clear_color: RwLock::new(VkClearColorValue::float32([0.0, 0.0, 0.0, 1.0])),
|
clear_color: RwLock::new(VkClearColorValue::float32([0.0, 0.0, 0.0, 1.0])),
|
||||||
|
|
||||||
command_buffer,
|
command_buffer,
|
||||||
buffer_recorder: None,
|
|
||||||
|
render_routines: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +160,11 @@ impl RenderBackend {
|
||||||
*self.clear_color.write().unwrap() = VkClearColorValue::float32(clear_color);
|
*self.clear_color.write().unwrap() = VkClearColorValue::float32(clear_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_frame(&mut self, image_indices: TargetMode<usize>) -> Result<()> {
|
pub fn render(
|
||||||
|
&mut self,
|
||||||
|
world: &mut World,
|
||||||
|
image_indices: TargetMode<usize>,
|
||||||
|
) -> Result<&Arc<CommandBuffer>> {
|
||||||
// begin main command buffer
|
// begin main command buffer
|
||||||
let mut buffer_recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new(
|
let mut buffer_recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new(
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||||
|
@ -161,39 +212,27 @@ impl RenderBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buffer_recorder = Some(unsafe { std::mem::transmute(buffer_recorder) });
|
// make a call to the connected scenes
|
||||||
|
self.render_routines
|
||||||
|
.iter_mut()
|
||||||
|
.try_for_each(|scene_handle| {
|
||||||
|
(scene_handle.render)(
|
||||||
|
&mut buffer_recorder,
|
||||||
|
&*self.swapchain_images.lock().unwrap(),
|
||||||
|
&image_indices,
|
||||||
|
world,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(&self.command_buffer)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render<F>(&mut self, image_indices: TargetMode<usize>, render: F) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(
|
|
||||||
&mut CommandBufferRecorder<'_>,
|
|
||||||
&TargetMode<Vec<Arc<Image>>>,
|
|
||||||
&TargetMode<usize>,
|
|
||||||
) -> Result<()>,
|
|
||||||
{
|
|
||||||
render(
|
|
||||||
self.buffer_recorder.as_mut().unwrap(),
|
|
||||||
&*self.swapchain_images.lock().unwrap(),
|
|
||||||
&image_indices,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn end_frame(&mut self) -> &Arc<CommandBuffer> {
|
|
||||||
self.buffer_recorder = None;
|
|
||||||
&self.command_buffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(
|
pub fn resize(
|
||||||
&mut self,
|
&mut self,
|
||||||
_world: &World,
|
world: &mut World,
|
||||||
images: TargetMode<Vec<Arc<Image>>>,
|
images: TargetMode<Vec<Arc<Image>>>,
|
||||||
_width: u32,
|
width: u32,
|
||||||
_height: u32,
|
height: u32,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.image_count.store(
|
self.image_count.store(
|
||||||
match &images {
|
match &images {
|
||||||
|
@ -206,16 +245,32 @@ impl RenderBackend {
|
||||||
SeqCst,
|
SeqCst,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO
|
self.render_routines
|
||||||
// self.render_routines
|
.iter_mut()
|
||||||
// .iter_mut()
|
.try_for_each(|scene_handle| {
|
||||||
// .try_for_each(|scene_handle| {
|
(scene_handle.resize)(width as f32, height as f32, &images, world)
|
||||||
// (scene_handle.resize)(width as f32, height as f32, &images, world)
|
})?;
|
||||||
// })?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// lower priority means it is more important
|
||||||
|
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
|
||||||
|
self.render_routines.push(SceneHandle::new::<T>(priority));
|
||||||
|
self.render_routines
|
||||||
|
.sort_by_key(|scene_handle| scene_handle.priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_render_routine<T: TScene>(&mut self) {
|
||||||
|
if let Some(index) = self
|
||||||
|
.render_routines
|
||||||
|
.iter()
|
||||||
|
.position(|scene_handle| scene_handle.type_id == TypeId::of::<T>())
|
||||||
|
{
|
||||||
|
self.render_routines.remove(index as usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// getter
|
// getter
|
||||||
pub fn image_count(&self) -> usize {
|
pub fn image_count(&self) -> usize {
|
||||||
self.image_count.load(SeqCst)
|
self.image_count.load(SeqCst)
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub trait TScene: Resource + Send + Sync + 'static {
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
indices: &TargetMode<usize>,
|
indices: &TargetMode<usize>,
|
||||||
world: &World,
|
world: &mut World,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
fn resize(
|
fn resize(
|
||||||
|
@ -25,7 +25,7 @@ pub trait TScene: Resource + Send + Sync + 'static {
|
||||||
window_width: f32,
|
window_width: f32,
|
||||||
window_height: f32,
|
window_height: f32,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
world: &World,
|
world: &mut World,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,35 +37,15 @@ pub enum RenderCore {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderCore {
|
impl RenderCore {
|
||||||
pub fn begin_frame(&mut self, world: &World) -> Result<()> {
|
pub fn next_frame(&mut self, world: &mut World) -> Result<bool> {
|
||||||
match self {
|
match self {
|
||||||
RenderCore::Wsi(rc) => rc.start_frame(world),
|
RenderCore::Wsi(rc) => rc.next_frame(world),
|
||||||
_ => todo!(),
|
RenderCore::OpenVR(rc) => rc.next_frame(world),
|
||||||
|
RenderCore::OpenXR(rc) => rc.next_frame(world),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<F>(&mut self, render: F) -> Result<()>
|
pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
|
||||||
where
|
|
||||||
F: FnOnce(
|
|
||||||
&mut CommandBufferRecorder<'_>,
|
|
||||||
&TargetMode<Vec<Arc<Image>>>,
|
|
||||||
&TargetMode<usize>,
|
|
||||||
) -> Result<()>,
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
RenderCore::Wsi(rc) => rc.render(render),
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn end_frame(&mut self, world: &World) -> Result<()> {
|
|
||||||
match self {
|
|
||||||
RenderCore::Wsi(rc) => rc.end_frame(world),
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize(&mut self, world: &World, w: u32, h: u32) -> Result<()> {
|
|
||||||
match self {
|
match self {
|
||||||
RenderCore::Wsi(rc) => rc.resize(world, w, h),
|
RenderCore::Wsi(rc) => rc.resize(world, w, h),
|
||||||
RenderCore::OpenVR(rc) => rc.resize(world, w, h),
|
RenderCore::OpenVR(rc) => rc.resize(world, w, h),
|
||||||
|
@ -85,6 +65,23 @@ impl RenderCore {
|
||||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// lower priority means it is more important
|
||||||
|
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
|
||||||
|
match self {
|
||||||
|
RenderCore::Wsi(rc) => rc.add_render_routine::<T>(priority),
|
||||||
|
RenderCore::OpenVR(rc) => rc.add_render_routine::<T>(priority),
|
||||||
|
RenderCore::OpenXR(rc) => rc.add_render_routine::<T>(priority),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_render_routine<T: TScene>(&mut self) {
|
||||||
|
match self {
|
||||||
|
RenderCore::Wsi(rc) => rc.remove_render_routine::<T>(),
|
||||||
|
RenderCore::OpenVR(rc) => rc.remove_render_routine::<T>(),
|
||||||
|
RenderCore::OpenXR(rc) => rc.remove_render_routine::<T>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_clear_color(&self, color: [f32; 4]) {
|
pub fn set_clear_color(&self, color: [f32; 4]) {
|
||||||
match self {
|
match self {
|
||||||
RenderCore::Wsi(rc) => rc.set_clear_color(color),
|
RenderCore::Wsi(rc) => rc.set_clear_color(color),
|
||||||
|
|
|
@ -79,11 +79,11 @@ pub mod openvrrendercore {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, _: &World, _: u32, _: u32) -> Result<()> {
|
pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_frame(&mut self, _: &World) -> Result<bool> {
|
pub fn next_frame(&mut self, _: &mut World) -> Result<bool> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl VulkanWindowRenderCore {
|
||||||
Ok((window_render_core, TargetMode::Mono(())))
|
Ok((window_render_core, TargetMode::Mono(())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aquire_next_image_index(&mut self, world: &World) -> Result<()> {
|
fn aquire_next_image_index(&mut self, world: &mut World) -> Result<()> {
|
||||||
// there was a bug that a windows never reacted after it was minimized
|
// there was a bug that a windows never reacted after it was minimized
|
||||||
// with this timeout, the window has 250ms delay
|
// with this timeout, the window has 250ms delay
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
@ -145,7 +145,7 @@ impl VulkanWindowRenderCore {
|
||||||
self.format
|
self.format
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, world: &World, w: u32, h: u32) -> Result<()> {
|
pub fn resize(&mut self, world: &mut World, w: u32, h: u32) -> Result<()> {
|
||||||
self.swapchain.recreate((w, h))?;
|
self.swapchain.recreate((w, h))?;
|
||||||
|
|
||||||
let swapchain_images = self.swapchain.wrap_images(
|
let swapchain_images = self.swapchain.wrap_images(
|
||||||
|
@ -164,33 +164,14 @@ impl VulkanWindowRenderCore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_frame(&mut self, world: &World) -> Result<()> {
|
pub fn next_frame(&mut self, world: &mut World) -> Result<bool> {
|
||||||
self.aquire_next_image_index(world)?;
|
self.aquire_next_image_index(world)?;
|
||||||
self.render_backend
|
|
||||||
.begin_frame(TargetMode::Mono(self.current_image_index.load(SeqCst)))?;
|
|
||||||
|
|
||||||
Ok(())
|
let command_buffer = self.render_backend.render(
|
||||||
}
|
world,
|
||||||
|
|
||||||
pub fn render<F>(&mut self, render: F) -> Result<()>
|
|
||||||
where
|
|
||||||
F: FnOnce(
|
|
||||||
&mut CommandBufferRecorder<'_>,
|
|
||||||
&TargetMode<Vec<Arc<Image>>>,
|
|
||||||
&TargetMode<usize>,
|
|
||||||
) -> Result<()>,
|
|
||||||
{
|
|
||||||
self.render_backend.render(
|
|
||||||
TargetMode::Mono(self.current_image_index.load(SeqCst)),
|
TargetMode::Mono(self.current_image_index.load(SeqCst)),
|
||||||
render,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn end_frame(&mut self, world: &World) -> Result<()> {
|
|
||||||
let command_buffer = self.render_backend.end_frame();
|
|
||||||
|
|
||||||
let submits = &[SubmitInfo::default()
|
let submits = &[SubmitInfo::default()
|
||||||
.add_wait_semaphore(
|
.add_wait_semaphore(
|
||||||
&*self.image_available_sem.read().unwrap(),
|
&*self.image_available_sem.read().unwrap(),
|
||||||
|
@ -213,7 +194,7 @@ impl VulkanWindowRenderCore {
|
||||||
let (w, h) = self.wsi.window_size();
|
let (w, h) = self.wsi.window_size();
|
||||||
self.resize(world, w, h)?;
|
self.resize(world, w, h)?;
|
||||||
self.render_fence.reset();
|
self.render_fence.reset();
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure command_buffer is ready
|
// make sure command_buffer is ready
|
||||||
|
@ -224,13 +205,22 @@ impl VulkanWindowRenderCore {
|
||||||
)?;
|
)?;
|
||||||
self.render_fence.reset();
|
self.render_fence.reset();
|
||||||
|
|
||||||
Ok(())
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_clear_color(&self, color: [f32; 4]) {
|
pub fn set_clear_color(&self, color: [f32; 4]) {
|
||||||
self.render_backend.set_clear_color(color);
|
self.render_backend.set_clear_color(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// post process handling
|
||||||
|
pub fn add_render_routine<T: TScene>(&mut self, priority: u32) {
|
||||||
|
self.render_backend.add_render_routine::<T>(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_render_routine<T: TScene>(&mut self) {
|
||||||
|
self.render_backend.remove_render_routine::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
// getter
|
// getter
|
||||||
pub fn image_count(&self) -> usize {
|
pub fn image_count(&self) -> usize {
|
||||||
self.render_backend.image_count()
|
self.render_backend.image_count()
|
||||||
|
|
|
@ -77,11 +77,11 @@ pub mod openxrrendercore {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, _: &World, _: u32, _: u32) -> Result<()> {
|
pub fn resize(&mut self, _: &mut World, _: u32, _: u32) -> Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_frame(&mut self, _: &World) -> Result<bool> {
|
pub fn next_frame(&mut self, _: &mut World) -> Result<bool> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ impl SkyBox {
|
||||||
.sample_count;
|
.sample_count;
|
||||||
|
|
||||||
let context = world.resources.get_mut_unchecked::<Context>();
|
let context = world.resources.get_mut_unchecked::<Context>();
|
||||||
|
context.render_core_mut().add_render_routine::<Self>(10);
|
||||||
|
|
||||||
let images = images.into();
|
let images = images.into();
|
||||||
let cube_map = Image::cube_map([
|
let cube_map = Image::cube_map([
|
||||||
|
@ -165,7 +166,6 @@ impl SkyBox {
|
||||||
descriptor_set,
|
descriptor_set,
|
||||||
};
|
};
|
||||||
world.resources.insert(me);
|
world.resources.insert(me);
|
||||||
world.add_system(10, Self::render_sky_box);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -178,23 +178,6 @@ impl SkyBox {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_sky_box(
|
|
||||||
world: &World,
|
|
||||||
_commands: &mut Commands,
|
|
||||||
context: &mut Context,
|
|
||||||
sky_box: &mut SkyBox,
|
|
||||||
) -> Result<bool> {
|
|
||||||
context.render(
|
|
||||||
|recorder: &mut CommandBufferRecorder<'_>,
|
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
|
||||||
indices: &TargetMode<usize>| {
|
|
||||||
sky_box.process(recorder, images, indices, world)
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_render_target(
|
fn create_render_target(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
|
@ -275,7 +258,7 @@ impl TScene for SkyBox {
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
_images: &TargetMode<Vec<Arc<Image>>>,
|
_images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
indices: &TargetMode<usize>,
|
indices: &TargetMode<usize>,
|
||||||
_world: &World,
|
_world: &mut World,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if !self.enabled {
|
if !self.enabled {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -307,7 +290,7 @@ impl TScene for SkyBox {
|
||||||
_window_width: f32,
|
_window_width: f32,
|
||||||
_window_height: f32,
|
_window_height: f32,
|
||||||
images: &TargetMode<Vec<Arc<Image>>>,
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
world: &World,
|
world: &mut World,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let sample_count = world
|
let sample_count = world
|
||||||
.resources
|
.resources
|
||||||
|
|
Loading…
Reference in a new issue