Compare commits
1 commit
b52e6d82c1
...
644e021423
Author | SHA1 | Date | |
---|---|---|---|
644e021423 |
19 changed files with 469 additions and 535 deletions
|
@ -19,7 +19,6 @@ members = [
|
||||||
"promise",
|
"promise",
|
||||||
"ring_buffer",
|
"ring_buffer",
|
||||||
"scene_update_macros",
|
"scene_update_macros",
|
||||||
"skybox",
|
|
||||||
"transaction_derive",
|
"transaction_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ impl ImageFormatChecker {
|
||||||
self.image_data.height,
|
self.image_data.height,
|
||||||
)
|
)
|
||||||
.format(initial_format)
|
.format(initial_format)
|
||||||
.max_mip_map_levels()
|
.attach_sampler(Sampler::pretty_sampler().build(device)?);
|
||||||
.attach_pretty_sampler(device)?;
|
|
||||||
|
|
||||||
let mut format = initial_format;
|
let mut format = initial_format;
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ impl ImageFormatChecker {
|
||||||
return Err(anyhow::Error::msg(format!(
|
return Err(anyhow::Error::msg(format!(
|
||||||
"Image format {:?} for asset does not work",
|
"Image format {:?} for asset does not work",
|
||||||
format
|
format
|
||||||
)));
|
)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,14 @@ use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
use std::sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
pub trait ContextObject {
|
||||||
|
fn name(&self) -> &str;
|
||||||
|
|
||||||
|
fn update(&mut self) -> Result<()>;
|
||||||
|
|
||||||
|
fn event(&mut self, event: Event) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
core: VulkanCore,
|
core: VulkanCore,
|
||||||
pub(crate) presentation: PresentationCore,
|
pub(crate) presentation: PresentationCore,
|
||||||
|
@ -57,17 +65,18 @@ impl Context {
|
||||||
&mut self.sound_handler
|
&mut self.sound_handler
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_frame<C, F>(&mut self, world: &mut World, mut f: F) -> Result<bool>
|
pub fn next_frame<C>(&mut self, world: &mut World) -> Result<bool> {
|
||||||
where
|
|
||||||
C: Send + Sync + 'static,
|
|
||||||
F: FnMut(&mut World, &mut C, Event) -> Result<()> + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
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(w, consumer, event),
|
|event| {
|
||||||
|
// TODO
|
||||||
|
// if let Some(ctx_obj) = world.resources.get_mut_opt::<C>() {
|
||||||
|
// ctx_obj.event(event)?;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|w, h| render_core.write().unwrap().resize(world, w, h),
|
|w, h| render_core.write().unwrap().resize(world, w, h),
|
||||||
) {
|
) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
|
|
|
@ -2,3 +2,5 @@
|
||||||
|
|
||||||
pub mod core;
|
pub mod core;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
|
pub use crate::core::context::ContextObject;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
use super::engine_event_handling::*;
|
use super::engine_object::*;
|
||||||
use super::engine_settings::EngineSettings;
|
use super::engine_settings::EngineSettings;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -11,7 +11,7 @@ use crate::assets::asset_manager::AssetManager;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
struct GuiPostProcess(Arc<GuiHandler>);
|
struct GuiPostProcess(Arc<GuiHandler>);
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ impl context::prelude::PostProcess for GuiPostProcess {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
|
input: Arc<RwLock<Input>>,
|
||||||
|
|
||||||
// loads and keeps track of raw data
|
// loads and keeps track of raw data
|
||||||
asset_manager: AssetManager,
|
asset_manager: AssetManager,
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ pub struct Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn new<T: EventConsumer>(
|
pub fn new(
|
||||||
#[allow(unused)] mut create_info: EngineCreateInfo<'_>,
|
#[allow(unused)] mut create_info: EngineCreateInfo<'_>,
|
||||||
world: &mut WorldBuilder,
|
world: &mut WorldBuilder,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -186,12 +188,13 @@ impl Engine {
|
||||||
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
||||||
|
|
||||||
let engine = Engine {
|
let engine = Engine {
|
||||||
|
input: Arc::new(RwLock::new(Input { direction_mapping })),
|
||||||
|
|
||||||
asset_manager,
|
asset_manager,
|
||||||
|
|
||||||
resource_base_path: create_info.resource_base_path,
|
resource_base_path: create_info.resource_base_path,
|
||||||
};
|
};
|
||||||
|
|
||||||
world.resources.insert(InputMap { direction_mapping });
|
|
||||||
world.resources.insert(context);
|
world.resources.insert(context);
|
||||||
world.resources.insert(engine);
|
world.resources.insert(engine);
|
||||||
world.resources.insert(engine_settings);
|
world.resources.insert(engine_settings);
|
||||||
|
@ -205,7 +208,7 @@ impl Engine {
|
||||||
|
|
||||||
world.resources.insert(scene);
|
world.resources.insert(scene);
|
||||||
|
|
||||||
world.add_system(Self::main_system::<T>);
|
world.add_system(Self::main_system);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -248,25 +251,10 @@ impl Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
fn main_system<T: EventConsumer>(world: &mut World) -> Result<bool> {
|
fn main_system(world: &mut World) -> Result<bool> {
|
||||||
world
|
world
|
||||||
.resources
|
.resources
|
||||||
.get::<Arc<GuiHandler>>()
|
.get_mut_unchecked::<Context>()
|
||||||
.process_callbacks()?;
|
.next_frame::<()>(world)
|
||||||
|
|
||||||
let gui_handler = world.resources.get_unchecked::<Arc<GuiHandler>>();
|
|
||||||
let input_map = world.resources.get_unchecked::<InputMap>();
|
|
||||||
let context = world.resources.get_unchecked::<Context>();
|
|
||||||
|
|
||||||
let res = world.resources.get_mut_unchecked::<Context>().next_frame(
|
|
||||||
world,
|
|
||||||
|world, consumer: &mut T, event| {
|
|
||||||
Self::event(world, context, gui_handler, input_map, consumer, event)
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
gui_handler.process_callbacks()?;
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,332 +0,0 @@
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum EngineEvent {
|
|
||||||
MouseMotion(u32, u32),
|
|
||||||
MouseButtonDown(MouseButton),
|
|
||||||
MouseButtonUp(MouseButton),
|
|
||||||
MouseWheel(i32, i32, MouseWheelDirection),
|
|
||||||
|
|
||||||
KeyDown(Keycode),
|
|
||||||
KeyUp(Keycode),
|
|
||||||
|
|
||||||
ButtonDown(ControllerButton),
|
|
||||||
ButtonUp(ControllerButton),
|
|
||||||
ControllerAxis(ControllerAxis),
|
|
||||||
|
|
||||||
ControllerAdded(Arc<RwLock<Controller>>),
|
|
||||||
ControllerRemoved(Arc<RwLock<Controller>>),
|
|
||||||
|
|
||||||
FileDrop(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait EventConsumer: Send + Sync + 'static {
|
|
||||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct InputMap {
|
|
||||||
pub direction_mapping: HashMap<Keycode, GuiDirection>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine {
|
|
||||||
pub(crate) fn event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
context: &Context,
|
|
||||||
gui_handler: &GuiHandler,
|
|
||||||
input: &InputMap,
|
|
||||||
consumer: &mut T,
|
|
||||||
event: Event,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
match event {
|
|
||||||
Event::MouseMotion(x, y) => {
|
|
||||||
gui_handler.set_mouse_pos(x, y)?;
|
|
||||||
consumer.event(world, EngineEvent::MouseMotion(x, y))?;
|
|
||||||
}
|
|
||||||
Event::MouseButtonDown(mouse_button) => {
|
|
||||||
if !gui_handler.mouse_down(mouse_button)? {
|
|
||||||
consumer.event(world, EngineEvent::MouseButtonDown(mouse_button))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::MouseButtonUp(mouse_button) => {
|
|
||||||
if !gui_handler.mouse_up(mouse_button)? {
|
|
||||||
consumer.event(world, EngineEvent::MouseButtonUp(mouse_button))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::MouseWheel(x, y, direction) => {
|
|
||||||
consumer.event(world, EngineEvent::MouseWheel(x, y, direction))?
|
|
||||||
}
|
|
||||||
Event::KeyDown(keycode) => {
|
|
||||||
Self::key_down_event(world, context, gui_handler, input, consumer, keycode)?;
|
|
||||||
}
|
|
||||||
Event::KeyUp(keycode) => {
|
|
||||||
Self::key_up_event(world, gui_handler, input, consumer, keycode)?;
|
|
||||||
}
|
|
||||||
Event::TextInput(text) => {
|
|
||||||
Self::text_input(gui_handler, text)?;
|
|
||||||
}
|
|
||||||
Event::ControllerButtonDown(button) => {
|
|
||||||
Self::button_down_event(world, gui_handler, consumer, button)?;
|
|
||||||
}
|
|
||||||
Event::ControllerButtonUp(button) => {
|
|
||||||
Self::button_up_event(world, consumer, button)?;
|
|
||||||
}
|
|
||||||
Event::ControllerAxis(controller) => {
|
|
||||||
let controller = controller.read().unwrap();
|
|
||||||
|
|
||||||
if !gui_handler.check_navigatable()? {
|
|
||||||
Self::axis_event(world, consumer, &controller)?
|
|
||||||
} else {
|
|
||||||
gui_handler.update_selection(controller.direction())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::ControllerAdded(controller) => {
|
|
||||||
Self::controller_added(world, consumer, controller)?
|
|
||||||
}
|
|
||||||
Event::ControllerRemoved(controller) => {
|
|
||||||
Self::controller_removed(world, consumer, controller)?
|
|
||||||
}
|
|
||||||
Event::FileDrop(filename) => consumer.event(world, EngineEvent::FileDrop(filename))?,
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Engine {
|
|
||||||
#[inline]
|
|
||||||
fn controller_added<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
consumer: &mut T,
|
|
||||||
controller: Arc<RwLock<Controller>>,
|
|
||||||
) -> Result<()> {
|
|
||||||
consumer.event(world, EngineEvent::ControllerAdded(controller))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn controller_removed<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
consumer: &mut T,
|
|
||||||
controller: Arc<RwLock<Controller>>,
|
|
||||||
) -> Result<()> {
|
|
||||||
consumer.event(world, EngineEvent::ControllerRemoved(controller))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn key_up_event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
gui_handler: &GuiHandler,
|
|
||||||
input: &InputMap,
|
|
||||||
consumer: &mut T,
|
|
||||||
keycode: Keycode,
|
|
||||||
) -> Result<()> {
|
|
||||||
if input.direction_mapping.get(&keycode).is_some()
|
|
||||||
&& gui_handler.update_selection(GuiDirection::None)?
|
|
||||||
{
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
consumer.event(world, EngineEvent::KeyUp(keycode))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn key_down_event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
context: &Context,
|
|
||||||
gui_handler: &GuiHandler,
|
|
||||||
input: &InputMap,
|
|
||||||
consumer: &mut T,
|
|
||||||
keycode: Keycode,
|
|
||||||
) -> Result<()> {
|
|
||||||
if let Some(direction) = input.direction_mapping.get(&keycode) {
|
|
||||||
if gui_handler.update_selection(*direction)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match keycode {
|
|
||||||
Keycode::Backspace => {
|
|
||||||
if gui_handler.remove_char()? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keycode::Return => {
|
|
||||||
if gui_handler.accept_selection()? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keycode::Escape => {
|
|
||||||
if gui_handler.decline_topgui()? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keycode::V => {
|
|
||||||
if let Some(writeable) = gui_handler.writeable()? {
|
|
||||||
if let Some(content) = context.window_config().clipboard_content()? {
|
|
||||||
writeable.set_text(content)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
consumer.event(world, EngineEvent::KeyDown(keycode))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn button_up_event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
consumer: &mut T,
|
|
||||||
button: ControllerButton,
|
|
||||||
) -> Result<()> {
|
|
||||||
consumer.event(world, EngineEvent::ButtonUp(button))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn button_down_event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
gui_handler: &GuiHandler,
|
|
||||||
consumer: &mut T,
|
|
||||||
button: ControllerButton,
|
|
||||||
) -> Result<()> {
|
|
||||||
if gui_handler.check_navigatable()? {
|
|
||||||
Self::check_button_down(world, gui_handler, consumer, button)?;
|
|
||||||
} else {
|
|
||||||
consumer.event(world, EngineEvent::ButtonDown(button))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn axis_event<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
consumer: &mut T,
|
|
||||||
controller: &Controller,
|
|
||||||
) -> Result<()> {
|
|
||||||
consumer.event(
|
|
||||||
world,
|
|
||||||
EngineEvent::ControllerAxis(controller.controller_axis()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_button_down<T: EventConsumer>(
|
|
||||||
world: &mut World,
|
|
||||||
gui_handler: &GuiHandler,
|
|
||||||
consumer: &mut T,
|
|
||||||
button: ControllerButton,
|
|
||||||
) -> Result<()> {
|
|
||||||
match button {
|
|
||||||
ControllerButton::A => {
|
|
||||||
if gui_handler.accept_selection()? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::B => {
|
|
||||||
if gui_handler.decline_topgui()? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::RightButton => {
|
|
||||||
if gui_handler.next_tab_topgui(false)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::LeftButton => {
|
|
||||||
if gui_handler.previous_tab_topgui(false)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::RightTrigger => {
|
|
||||||
if gui_handler.next_tab_topgui(true)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::LeftTrigger => {
|
|
||||||
if gui_handler.previous_tab_topgui(true)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::DPadDown => {
|
|
||||||
let selection_res = gui_handler.update_selection(GuiDirection::Down)?;
|
|
||||||
gui_handler.update_selection(GuiDirection::None)?;
|
|
||||||
|
|
||||||
if selection_res {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::DPadUp => {
|
|
||||||
let selection_res = gui_handler.update_selection(GuiDirection::Up)?;
|
|
||||||
gui_handler.update_selection(GuiDirection::None)?;
|
|
||||||
|
|
||||||
if selection_res {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::DPadRight => {
|
|
||||||
let selection_res = gui_handler.update_selection(GuiDirection::Right)?;
|
|
||||||
gui_handler.update_selection(GuiDirection::None)?;
|
|
||||||
|
|
||||||
if selection_res {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerButton::DPadLeft => {
|
|
||||||
let selection_res = gui_handler.update_selection(GuiDirection::Left)?;
|
|
||||||
gui_handler.update_selection(GuiDirection::None)?;
|
|
||||||
|
|
||||||
if selection_res {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
if !gui_handler.accept_custom_selection(button)? {
|
|
||||||
consumer.event(world, EngineEvent::ButtonDown(button))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn text_input(gui_handler: &GuiHandler, text: String) -> Result<()> {
|
|
||||||
if let Some(writeable) = gui_handler.writeable()? {
|
|
||||||
for c in text.chars() {
|
|
||||||
writeable.add_letter(c)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
420
engine/src/engine/engine_object.rs
Normal file
420
engine/src/engine/engine_object.rs
Normal file
|
@ -0,0 +1,420 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use context::ContextObject;
|
||||||
|
|
||||||
|
use std::any::Any;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
// use super::engine_object_data::{EngineObjectAccess, EngineObjectDataHandle};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum EngineEvent {
|
||||||
|
MouseMotion(u32, u32),
|
||||||
|
MouseButtonDown(MouseButton),
|
||||||
|
MouseButtonUp(MouseButton),
|
||||||
|
MouseWheel(i32, i32, MouseWheelDirection),
|
||||||
|
|
||||||
|
KeyDown(Keycode),
|
||||||
|
KeyUp(Keycode),
|
||||||
|
|
||||||
|
ButtonDown(ControllerButton),
|
||||||
|
ButtonUp(ControllerButton),
|
||||||
|
ControllerAxis(ControllerAxis),
|
||||||
|
|
||||||
|
ControllerAdded(Arc<RwLock<Controller>>),
|
||||||
|
ControllerRemoved(Arc<RwLock<Controller>>),
|
||||||
|
|
||||||
|
FileDrop(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub trait EngineObjectHelper: Any {
|
||||||
|
// type Payload: Send + Sync;
|
||||||
|
|
||||||
|
// fn access(&self) -> EngineObjectAccess<'_, Self::Payload>;
|
||||||
|
// fn payload(&self) -> EngineObjectDataHandle<Self::Payload>;
|
||||||
|
// fn ui(&self) -> &States;
|
||||||
|
// fn ui_mut(&mut self) -> &mut States;
|
||||||
|
|
||||||
|
// fn access_callback_mut<'a, F>(
|
||||||
|
// &'a self,
|
||||||
|
// f: F,
|
||||||
|
// ) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
||||||
|
// where
|
||||||
|
// F: FnMut(EngineObjectAccess<'a, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
||||||
|
// {
|
||||||
|
// self.payload().access_callback_mut(f)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn access_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
||||||
|
// where
|
||||||
|
// F: Fn(EngineObjectAccess<'_, Self::Payload>) -> Result<()> + Send + Sync + 'static,
|
||||||
|
// {
|
||||||
|
// self.payload().access_callback(f)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn handle_callback_mut<F>(&self, mut f: F) -> impl FnMut() -> Result<()> + Send + Sync + 'static
|
||||||
|
// where
|
||||||
|
// F: FnMut(
|
||||||
|
// EngineObjectDataHandle<Self::Payload>,
|
||||||
|
// EngineObjectAccess<'_, Self::Payload>,
|
||||||
|
// ) -> Result<()>
|
||||||
|
// + Send
|
||||||
|
// + Sync
|
||||||
|
// + 'static,
|
||||||
|
// {
|
||||||
|
// let handle = self.payload();
|
||||||
|
|
||||||
|
// move || {
|
||||||
|
// let data = handle.as_data();
|
||||||
|
// let access = data.access();
|
||||||
|
|
||||||
|
// f(handle.copy(), access)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn handle_callback<F>(&self, f: F) -> impl Fn() -> Result<()> + Send + Sync + 'static
|
||||||
|
// where
|
||||||
|
// F: Fn(
|
||||||
|
// EngineObjectDataHandle<Self::Payload>,
|
||||||
|
// EngineObjectAccess<'_, Self::Payload>,
|
||||||
|
// ) -> Result<()>
|
||||||
|
// + Send
|
||||||
|
// + Sync
|
||||||
|
// + 'static,
|
||||||
|
// {
|
||||||
|
// let handle = self.payload();
|
||||||
|
|
||||||
|
// move || {
|
||||||
|
// let data = handle.as_data();
|
||||||
|
// let access = data.access();
|
||||||
|
|
||||||
|
// f(handle.copy(), access)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub trait EngineObject: Any {
|
||||||
|
fn name(&self) -> &str;
|
||||||
|
|
||||||
|
fn update(&mut self) -> Result<()>;
|
||||||
|
fn event(&mut self, event: EngineEvent) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Input {
|
||||||
|
pub direction_mapping: HashMap<Keycode, GuiDirection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ContextObjectImpl<E>
|
||||||
|
where
|
||||||
|
E: EngineObject + Send + Sync,
|
||||||
|
{
|
||||||
|
engine_object: E,
|
||||||
|
|
||||||
|
context: Arc<Context>,
|
||||||
|
input: Arc<RwLock<Input>>,
|
||||||
|
gui_handler: Arc<GuiHandler>,
|
||||||
|
|
||||||
|
ctrl_pressed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> ContextObjectImpl<E>
|
||||||
|
where
|
||||||
|
E: EngineObject + Send + Sync,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
context: Arc<Context>,
|
||||||
|
engine_object: E,
|
||||||
|
input: Arc<RwLock<Input>>,
|
||||||
|
gui_handler: Arc<GuiHandler>,
|
||||||
|
) -> Result<Self> {
|
||||||
|
Ok(ContextObjectImpl {
|
||||||
|
context,
|
||||||
|
engine_object,
|
||||||
|
input,
|
||||||
|
gui_handler,
|
||||||
|
ctrl_pressed: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> ContextObject for ContextObjectImpl<E>
|
||||||
|
where
|
||||||
|
E: EngineObject + Send + Sync,
|
||||||
|
{
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.engine_object.name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) -> anyhow::Result<()> {
|
||||||
|
self.gui_handler.process_callbacks()?;
|
||||||
|
self.engine_object.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(&mut self, event: Event) -> anyhow::Result<()> {
|
||||||
|
match event {
|
||||||
|
Event::MouseMotion(x, y) => {
|
||||||
|
self.gui_handler.set_mouse_pos(x, y)?;
|
||||||
|
self.engine_object.event(EngineEvent::MouseMotion(x, y))?;
|
||||||
|
}
|
||||||
|
Event::MouseButtonDown(mouse_button) => {
|
||||||
|
if !self.gui_handler.mouse_down(mouse_button)? {
|
||||||
|
self.engine_object
|
||||||
|
.event(EngineEvent::MouseButtonDown(mouse_button))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::MouseButtonUp(mouse_button) => {
|
||||||
|
if !self.gui_handler.mouse_up(mouse_button)? {
|
||||||
|
self.engine_object
|
||||||
|
.event(EngineEvent::MouseButtonUp(mouse_button))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::MouseWheel(x, y, direction) => self
|
||||||
|
.engine_object
|
||||||
|
.event(EngineEvent::MouseWheel(x, y, direction))?,
|
||||||
|
Event::KeyDown(keycode) => {
|
||||||
|
self.key_down_event(keycode)?;
|
||||||
|
}
|
||||||
|
Event::KeyUp(keycode) => {
|
||||||
|
self.key_up_event(keycode)?;
|
||||||
|
}
|
||||||
|
Event::TextInput(text) => {
|
||||||
|
self.text_input(text)?;
|
||||||
|
}
|
||||||
|
Event::ControllerButtonDown(button) => {
|
||||||
|
self.button_down_event(button)?;
|
||||||
|
}
|
||||||
|
Event::ControllerButtonUp(button) => {
|
||||||
|
self.button_up_event(button)?;
|
||||||
|
}
|
||||||
|
Event::ControllerAxis(controller) => {
|
||||||
|
let controller = controller.read().unwrap();
|
||||||
|
|
||||||
|
if !self.gui_handler.check_navigatable()? {
|
||||||
|
self.axis_event(&controller)?
|
||||||
|
} else {
|
||||||
|
self.gui_handler.update_selection(controller.direction())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::ControllerAdded(controller) => self.controller_added(controller)?,
|
||||||
|
Event::ControllerRemoved(controller) => self.controller_removed(controller)?,
|
||||||
|
Event::FileDrop(filename) => {
|
||||||
|
self.engine_object.event(EngineEvent::FileDrop(filename))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> ContextObjectImpl<E>
|
||||||
|
where
|
||||||
|
E: EngineObject + Send + Sync,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn controller_added(&mut self, controller: Arc<RwLock<Controller>>) -> Result<()> {
|
||||||
|
self.engine_object
|
||||||
|
.event(EngineEvent::ControllerAdded(controller))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn controller_removed(&mut self, controller: Arc<RwLock<Controller>>) -> Result<()> {
|
||||||
|
self.engine_object
|
||||||
|
.event(EngineEvent::ControllerRemoved(controller))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn key_up_event(&mut self, keycode: Keycode) -> Result<()> {
|
||||||
|
let input = self.input.read().unwrap();
|
||||||
|
|
||||||
|
if input.direction_mapping.get(&keycode).is_some()
|
||||||
|
&& self.gui_handler.update_selection(GuiDirection::None)?
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
match keycode {
|
||||||
|
Keycode::RCtrl | Keycode::LCtrl => {
|
||||||
|
self.ctrl_pressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.engine_object.event(EngineEvent::KeyUp(keycode))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn key_down_event(&mut self, keycode: Keycode) -> Result<()> {
|
||||||
|
let input = self.input.read().unwrap();
|
||||||
|
|
||||||
|
if let Some(direction) = input.direction_mapping.get(&keycode) {
|
||||||
|
if self.gui_handler.update_selection(*direction)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match keycode {
|
||||||
|
Keycode::Backspace => {
|
||||||
|
if self.gui_handler.remove_char()? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keycode::Return => {
|
||||||
|
if self.gui_handler.accept_selection()? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keycode::Escape => {
|
||||||
|
if self.gui_handler.decline_topgui()? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keycode::RCtrl | Keycode::LCtrl => {
|
||||||
|
self.ctrl_pressed = true;
|
||||||
|
}
|
||||||
|
Keycode::V => {
|
||||||
|
if let Some(writeable) = self.gui_handler.writeable()? {
|
||||||
|
if let Some(content) = self.context.window_config().clipboard_content()? {
|
||||||
|
writeable.set_text(content)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.engine_object.event(EngineEvent::KeyDown(keycode))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn button_up_event(&mut self, button: ControllerButton) -> Result<()> {
|
||||||
|
self.engine_object.event(EngineEvent::ButtonUp(button))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn button_down_event(&mut self, button: ControllerButton) -> Result<()> {
|
||||||
|
if self.gui_handler.check_navigatable()? {
|
||||||
|
self.check_button_down(button)?;
|
||||||
|
} else {
|
||||||
|
self.engine_object.event(EngineEvent::ButtonDown(button))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn axis_event(&mut self, controller: &Controller) -> Result<()> {
|
||||||
|
self.engine_object
|
||||||
|
.event(EngineEvent::ControllerAxis(controller.controller_axis()))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn check_button_down(&mut self, button: ControllerButton) -> Result<()> {
|
||||||
|
match button {
|
||||||
|
ControllerButton::A => {
|
||||||
|
if self.gui_handler.accept_selection()? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::B => {
|
||||||
|
if self.gui_handler.decline_topgui()? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::RightButton => {
|
||||||
|
if self.gui_handler.next_tab_topgui(false)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::LeftButton => {
|
||||||
|
if self.gui_handler.previous_tab_topgui(false)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::RightTrigger => {
|
||||||
|
if self.gui_handler.next_tab_topgui(true)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::LeftTrigger => {
|
||||||
|
if self.gui_handler.previous_tab_topgui(true)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::DPadDown => {
|
||||||
|
let selection_res = self.gui_handler.update_selection(GuiDirection::Down)?;
|
||||||
|
self.gui_handler.update_selection(GuiDirection::None)?;
|
||||||
|
|
||||||
|
if selection_res {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::DPadUp => {
|
||||||
|
let selection_res = self.gui_handler.update_selection(GuiDirection::Up)?;
|
||||||
|
self.gui_handler.update_selection(GuiDirection::None)?;
|
||||||
|
|
||||||
|
if selection_res {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::DPadRight => {
|
||||||
|
let selection_res = self.gui_handler.update_selection(GuiDirection::Right)?;
|
||||||
|
self.gui_handler.update_selection(GuiDirection::None)?;
|
||||||
|
|
||||||
|
if selection_res {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerButton::DPadLeft => {
|
||||||
|
let selection_res = self.gui_handler.update_selection(GuiDirection::Left)?;
|
||||||
|
self.gui_handler.update_selection(GuiDirection::None)?;
|
||||||
|
|
||||||
|
if selection_res {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.gui_handler.accept_custom_selection(button)? {
|
||||||
|
self.engine_object.event(EngineEvent::ButtonDown(button))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn text_input(&self, text: String) -> Result<()> {
|
||||||
|
if let Some(writeable) = self.gui_handler.writeable()? {
|
||||||
|
for c in text.chars() {
|
||||||
|
writeable.add_letter(c)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod engine_settings;
|
pub mod engine_settings;
|
||||||
|
|
||||||
pub mod engine_event_handling;
|
pub mod engine_object;
|
||||||
|
|
||||||
pub mod asset_handler;
|
pub mod asset_handler;
|
||||||
pub mod engine_create_info;
|
pub mod engine_create_info;
|
||||||
|
|
|
@ -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},
|
engine_object::{EngineEvent, EngineObject},
|
||||||
engine_settings::*,
|
engine_settings::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::{Deg, Matrix4, Vector2, Vector3, num_traits::clamp, vec3};
|
use cgmath::{num_traits::clamp, vec3, Deg, Matrix4, Vector2, Vector3};
|
||||||
|
|
||||||
pub struct TopDownCameraControl {
|
pub struct CameraControl {
|
||||||
zoom_levels: Vec<f32>,
|
zoom_levels: Vec<f32>,
|
||||||
current_zoom_level: usize,
|
current_zoom_level: usize,
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ pub struct TopDownCameraControl {
|
||||||
mouse_position_start: Option<(u32, u32)>,
|
mouse_position_start: Option<(u32, u32)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopDownCameraControl {
|
impl CameraControl {
|
||||||
const SCALE: f32 = 0.3;
|
const SCALE: f32 = 0.3;
|
||||||
const MIN_PITCH: f32 = 10.0;
|
const MIN_PITCH: f32 = 10.0;
|
||||||
const MAX_PITCH: f32 = 80.0;
|
const MAX_PITCH: f32 = 80.0;
|
||||||
|
@ -91,8 +91,8 @@ impl TopDownCameraControl {
|
||||||
self.rotation = Deg((self.rotation.0 + (self.stick_direction.x * factors.x)) % 360.0);
|
self.rotation = Deg((self.rotation.0 + (self.stick_direction.x * factors.x)) % 360.0);
|
||||||
self.arc = Deg(clamp(
|
self.arc = Deg(clamp(
|
||||||
self.arc.0 - (self.stick_direction.y * factors.y),
|
self.arc.0 - (self.stick_direction.y * factors.y),
|
||||||
TopDownCameraControl::MIN_PITCH,
|
CameraControl::MIN_PITCH,
|
||||||
TopDownCameraControl::MAX_PITCH,
|
CameraControl::MAX_PITCH,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.set_camera_offset(view)
|
self.set_camera_offset(view)
|
||||||
|
@ -102,14 +102,14 @@ impl TopDownCameraControl {
|
||||||
self.mouse_position = (x, y);
|
self.mouse_position = (x, y);
|
||||||
|
|
||||||
if let Some((start_x, start_y)) = self.mouse_position_start {
|
if let Some((start_x, start_y)) = self.mouse_position_start {
|
||||||
let x_diff = (start_x as i32 - x as i32) as f32 * TopDownCameraControl::SCALE;
|
let x_diff = (start_x as i32 - x as i32) as f32 * CameraControl::SCALE;
|
||||||
let y_diff = (start_y as i32 - y as i32) as f32 * TopDownCameraControl::SCALE;
|
let y_diff = (start_y as i32 - y as i32) as f32 * CameraControl::SCALE;
|
||||||
|
|
||||||
self.rotation = Deg((self.rotation_start.0 + x_diff) % 360.0);
|
self.rotation = Deg((self.rotation_start.0 + x_diff) % 360.0);
|
||||||
self.arc = Deg(clamp(
|
self.arc = Deg(clamp(
|
||||||
self.arc_start.0 - y_diff,
|
self.arc_start.0 - y_diff,
|
||||||
TopDownCameraControl::MIN_PITCH,
|
CameraControl::MIN_PITCH,
|
||||||
TopDownCameraControl::MAX_PITCH,
|
CameraControl::MAX_PITCH,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.set_camera_offset(view)?;
|
self.set_camera_offset(view)?;
|
|
@ -1,36 +0,0 @@
|
||||||
use crate::prelude::*;
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub struct FreeCameraControl {}
|
|
||||||
|
|
||||||
impl Default for FreeCameraControl {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FreeCameraControl {
|
|
||||||
pub fn roll(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pitch(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn yaw(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn forward_back(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn left_right(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn up_down(&mut self, view: &View) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,9 +6,8 @@ pub mod validcommandbuffer;
|
||||||
|
|
||||||
pub mod view;
|
pub mod view;
|
||||||
|
|
||||||
pub mod top_down_camera_control;
|
pub mod camera_control;
|
||||||
|
|
||||||
pub mod view_frustum;
|
pub mod view_frustum;
|
||||||
|
|
||||||
pub mod free_camera_control;
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
|
@ -6,6 +6,6 @@ pub use super::validcommandbuffer::*;
|
||||||
|
|
||||||
pub use super::view::*;
|
pub use super::view::*;
|
||||||
|
|
||||||
pub use super::top_down_camera_control::*;
|
pub use super::camera_control::*;
|
||||||
|
|
||||||
pub use super::view_frustum::*;
|
pub use super::view_frustum::*;
|
||||||
|
|
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
plexus = "0.0.11"
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
|
||||||
ecs = { path = "../../ecs" }
|
ecs = { path = "../../ecs" }
|
||||||
|
|
|
@ -6,55 +6,7 @@ use engine::prelude::*;
|
||||||
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(EngineCreateInfo::default(), &mut world_builder)?;
|
||||||
|
|
||||||
world_builder.add_system(GameState::update);
|
|
||||||
world_builder.resources.insert(GameState::Startup);
|
|
||||||
|
|
||||||
world_builder.build().run()
|
world_builder.build().run()
|
||||||
}
|
}
|
||||||
|
|
||||||
enum GameState {
|
|
||||||
Startup,
|
|
||||||
Loading,
|
|
||||||
Menu,
|
|
||||||
Game(Game),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GameState {
|
|
||||||
fn update(world: &mut World) -> Result<bool> {
|
|
||||||
match world.resources.get_mut_unchecked::<Self>() {
|
|
||||||
GameState::Startup => (),
|
|
||||||
GameState::Loading => (),
|
|
||||||
GameState::Menu => (),
|
|
||||||
GameState::Game(game) => game.update(world)?,
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventConsumer for GameState {
|
|
||||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> {
|
|
||||||
match self {
|
|
||||||
GameState::Startup => (),
|
|
||||||
GameState::Loading => (),
|
|
||||||
GameState::Menu => (),
|
|
||||||
GameState::Game(game) => game.event(world, event)?,
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Game {}
|
|
||||||
|
|
||||||
impl Game {
|
|
||||||
fn update(&mut self, world: &mut World) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn event(&mut self, world: &mut World, event: EngineEvent) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -178,9 +178,9 @@ impl EventSystem {
|
||||||
.map_err(|s| anyhow::Error::msg(s))?)
|
.map_err(|s| anyhow::Error::msg(s))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F, R>(&mut self, mut event_callback: F, mut resize: R) -> Result<bool>
|
pub fn poll_events<F, R>(&mut self, event_callback: F, mut resize: R) -> Result<bool>
|
||||||
where
|
where
|
||||||
F: FnMut(Event) -> Result<()>,
|
F: Fn(Event) -> Result<()>,
|
||||||
R: FnMut(u32, u32) -> Result<()>,
|
R: FnMut(u32, u32) -> Result<()>,
|
||||||
{
|
{
|
||||||
let mut controller_axis_changed = false;
|
let mut controller_axis_changed = false;
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl PresentationCore {
|
||||||
|
|
||||||
pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool>
|
pub fn poll_events<F, R>(&mut self, event_callback: F, resize_event: R) -> Result<bool>
|
||||||
where
|
where
|
||||||
F: FnMut(Event) -> Result<()>,
|
F: Fn(Event) -> Result<()>,
|
||||||
R: FnMut(u32, u32) -> Result<()>,
|
R: FnMut(u32, u32) -> Result<()>,
|
||||||
{
|
{
|
||||||
self.event_system.poll_events(event_callback, resize_event)
|
self.event_system.poll_events(event_callback, resize_event)
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "skybox"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["hodasemi <michaelh.95@t-online.de>"]
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow.workspace = true
|
|
||||||
|
|
||||||
ecs = { path = "../ecs" }
|
|
||||||
context = { path = "../context" }
|
|
|
@ -1,54 +0,0 @@
|
||||||
use std::{path::PathBuf, sync::Arc};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use context::prelude::*;
|
|
||||||
use ecs::*;
|
|
||||||
|
|
||||||
pub struct SkyBoxImages {
|
|
||||||
left: PathBuf,
|
|
||||||
right: PathBuf,
|
|
||||||
front: PathBuf,
|
|
||||||
back: PathBuf,
|
|
||||||
top: PathBuf,
|
|
||||||
bottom: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ExactSizeIterator<Item = PathBuf>> From<T> for SkyBoxImages {
|
|
||||||
fn from(mut paths: T) -> Self {
|
|
||||||
debug_assert_eq!(paths.len(), 6);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
left: paths.next().unwrap(),
|
|
||||||
right: paths.next().unwrap(),
|
|
||||||
front: paths.next().unwrap(),
|
|
||||||
back: paths.next().unwrap(),
|
|
||||||
top: paths.next().unwrap(),
|
|
||||||
bottom: paths.next().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SkyBox {
|
|
||||||
cube_map: Arc<Image>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SkyBox {
|
|
||||||
pub fn new(world: &mut WorldBuilder, images: impl Into<SkyBoxImages>) -> Result<Self> {
|
|
||||||
let images = images.into();
|
|
||||||
let context = world.resources.get::<Context>();
|
|
||||||
|
|
||||||
let cube_map = Image::cube_map([
|
|
||||||
images.left.try_into()?,
|
|
||||||
images.right.try_into()?,
|
|
||||||
images.front.try_into()?,
|
|
||||||
images.back.try_into()?,
|
|
||||||
images.top.try_into()?,
|
|
||||||
images.bottom.try_into()?,
|
|
||||||
])?
|
|
||||||
.max_mip_map_levels()
|
|
||||||
.attach_pretty_sampler(context.device())?
|
|
||||||
.build(context.device(), context.queue())?;
|
|
||||||
|
|
||||||
Ok(Self { cube_map })
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue