Fix engine for new concept
This commit is contained in:
parent
4e8f652ffd
commit
5513558f3d
24 changed files with 546 additions and 577 deletions
0
.zed/settings.json
Normal file
0
.zed/settings.json
Normal file
|
@ -36,7 +36,7 @@ pub struct Context {
|
||||||
render_core: Arc<RwLock<Box<dyn RenderCore>>>,
|
render_core: Arc<RwLock<Box<dyn RenderCore>>>,
|
||||||
|
|
||||||
#[cfg(feature = "sound")]
|
#[cfg(feature = "sound")]
|
||||||
sound_handler: Mutex<SoundHandler>,
|
sound_handler: SoundHandler,
|
||||||
|
|
||||||
os_specific: OsSpecific,
|
os_specific: OsSpecific,
|
||||||
|
|
||||||
|
@ -61,12 +61,11 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sound")]
|
#[cfg(feature = "sound")]
|
||||||
pub fn sound(&self) -> MutexGuard<'_, SoundHandler> {
|
pub fn sound(&mut self) -> &mut SoundHandler {
|
||||||
self.sound_handler.lock().unwrap()
|
&mut self.sound_handler
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<C>(&self, world: &mut World) -> Result<()> {
|
pub fn next_frame<C>(&mut self, world: &mut World) -> Result<bool> {
|
||||||
'running: loop {
|
|
||||||
let render_core = self.render_core.clone();
|
let render_core = self.render_core.clone();
|
||||||
|
|
||||||
match self.presentation.poll_events(
|
match self.presentation.poll_events(
|
||||||
|
@ -82,7 +81,7 @@ impl Context {
|
||||||
) {
|
) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
if !res {
|
if !res {
|
||||||
break 'running;
|
return Ok(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -93,13 +92,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.render_core_mut().next_frame(world)? {
|
if !self.render_core_mut().next_frame(world)? {
|
||||||
break 'running;
|
return Ok(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_core_mut().clear_post_processing_routines();
|
Ok(true)
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_core(&self) -> impl Deref<Target = Box<dyn RenderCore>> + '_ {
|
pub fn render_core(&self) -> impl Deref<Target = Box<dyn RenderCore>> + '_ {
|
||||||
|
@ -129,17 +125,17 @@ impl Context {
|
||||||
self.core.queue()
|
self.core.queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn controllers(&self) -> RwLockReadGuard<'_, Vec<Arc<RwLock<Controller>>>> {
|
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] {
|
||||||
self.presentation.event_system().controllers()
|
self.presentation.event_system().controllers()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_controller(&self) -> Result<Option<Arc<RwLock<Controller>>>> {
|
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> {
|
||||||
Ok(self.presentation.event_system().active_controller()?)
|
self.presentation.event_system().active_controller()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_active_controller(&self, controller: &Arc<RwLock<Controller>>) {
|
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
|
||||||
self.presentation
|
self.presentation
|
||||||
.event_system()
|
.event_system_mut()
|
||||||
.set_active_controller(controller)
|
.set_active_controller(controller)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +180,7 @@ impl ContextInterface for Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sound")]
|
#[cfg(feature = "sound")]
|
||||||
fn sound_handler(&self) -> MutexGuard<'_, SoundHandler> {
|
fn sound_handler(&mut self) -> &mut SoundHandler {
|
||||||
self.sound()
|
self.sound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,22 +398,22 @@ impl ContextBuilder {
|
||||||
|
|
||||||
let vr_mode = self.get_vr_mode();
|
let vr_mode = self.get_vr_mode();
|
||||||
|
|
||||||
let presentation =
|
let mut presentation =
|
||||||
PresentationCore::new(vr_mode, &self.window_create_info, self.app_info.clone())?;
|
PresentationCore::new(vr_mode, &self.window_create_info, self.app_info.clone())?;
|
||||||
|
|
||||||
presentation
|
presentation
|
||||||
.event_system()
|
.event_system_mut()
|
||||||
.set_controller_axis_enable_deadzone(self.controller_deadzones.axis_enable_deadzone);
|
.set_controller_axis_enable_deadzone(self.controller_deadzones.axis_enable_deadzone);
|
||||||
presentation
|
presentation
|
||||||
.event_system()
|
.event_system_mut()
|
||||||
.set_controller_axis_disable_deadzone(self.controller_deadzones.axis_disable_deadzone);
|
.set_controller_axis_disable_deadzone(self.controller_deadzones.axis_disable_deadzone);
|
||||||
presentation
|
presentation
|
||||||
.event_system()
|
.event_system_mut()
|
||||||
.set_controller_trigger_enable_deadzone(
|
.set_controller_trigger_enable_deadzone(
|
||||||
self.controller_deadzones.trigger_enable_deadzone,
|
self.controller_deadzones.trigger_enable_deadzone,
|
||||||
);
|
);
|
||||||
presentation
|
presentation
|
||||||
.event_system()
|
.event_system_mut()
|
||||||
.set_controller_trigger_disable_deadzone(
|
.set_controller_trigger_disable_deadzone(
|
||||||
self.controller_deadzones.trigger_disable_deadzone,
|
self.controller_deadzones.trigger_disable_deadzone,
|
||||||
);
|
);
|
||||||
|
@ -440,15 +436,15 @@ impl ContextBuilder {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if self.enable_mouse {
|
if self.enable_mouse {
|
||||||
presentation.event_system().enable_mouse();
|
presentation.event_system_mut().enable_mouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.enable_keyboard {
|
if self.enable_keyboard {
|
||||||
presentation.event_system().enable_keyboard();
|
presentation.event_system_mut().enable_keyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.enable_controller {
|
if self.enable_controller {
|
||||||
presentation.event_system().enable_controller();
|
presentation.event_system_mut().enable_controller();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Context {
|
Ok(Context {
|
||||||
|
@ -457,7 +453,7 @@ impl ContextBuilder {
|
||||||
render_core: Arc::new(RwLock::new(render_core)),
|
render_core: Arc::new(RwLock::new(render_core)),
|
||||||
|
|
||||||
#[cfg(feature = "sound")]
|
#[cfg(feature = "sound")]
|
||||||
sound_handler: Mutex::new(self.create_sound_handler()?),
|
sound_handler: self.create_sound_handler()?,
|
||||||
|
|
||||||
os_specific,
|
os_specific,
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap};
|
use crate::{ComponentDebug, ComponentNotFoundError, EntityComponent, MultiMut, TypeMap};
|
||||||
|
|
||||||
pub const COMPONENT_SEPARATOR: char = '§';
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EntityNotFoundError {
|
pub struct EntityNotFoundError {
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::{
|
||||||
mem::transmute,
|
mem::transmute,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use utilities::prelude::{remove_life_time, remove_life_time_mut};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Resources {
|
pub struct Resources {
|
||||||
map: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
|
map: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
|
||||||
|
@ -32,6 +34,10 @@ impl Resources {
|
||||||
self.get_opt::<T>().unwrap()
|
self.get_opt::<T>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_unchecked<'a, T: Any + Send + Sync>(&self) -> &'a T {
|
||||||
|
unsafe { remove_life_time(self.get::<T>()) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_opt<T: Any + Send + Sync>(&self) -> Option<&T> {
|
pub fn get_opt<T: Any + Send + Sync>(&self) -> Option<&T> {
|
||||||
self.map
|
self.map
|
||||||
.get(&TypeId::of::<T>())
|
.get(&TypeId::of::<T>())
|
||||||
|
@ -42,6 +48,10 @@ impl Resources {
|
||||||
self.get_mut_opt::<T>().unwrap()
|
self.get_mut_opt::<T>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_mut_unchecked<'a, T: Any + Send + Sync>(&mut self) -> &'a mut T {
|
||||||
|
unsafe { remove_life_time_mut(self.get_mut::<T>()) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_mut_opt<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
|
pub fn get_mut_opt<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
|
||||||
self.map
|
self.map
|
||||||
.get_mut(&TypeId::of::<T>())
|
.get_mut(&TypeId::of::<T>())
|
||||||
|
|
|
@ -79,12 +79,16 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn now(&self) -> Duration {
|
||||||
|
self.start_time.elapsed()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_entity(&mut self) -> EntityObject {
|
pub fn new_entity(&mut self) -> EntityObject {
|
||||||
self.entity_object_manager.create_entity()
|
self.entity_object_manager.create_entity()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn now(&self) -> Duration {
|
pub fn entities(&self) -> impl Iterator<Item = &EntityObject> {
|
||||||
self.start_time.elapsed()
|
self.entities.values()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn entity(
|
pub fn entity(
|
||||||
|
|
|
@ -6,8 +6,8 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicU32, Ordering},
|
|
||||||
Arc, RwLock, RwLockReadGuard,
|
Arc, RwLock, RwLockReadGuard,
|
||||||
|
atomic::{AtomicU32, Ordering},
|
||||||
};
|
};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ pub struct AssetCache {
|
||||||
|
|
||||||
impl AssetCache {
|
impl AssetCache {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
context: &Arc<Context>,
|
context: &Context,
|
||||||
engine_settings: &Arc<EngineSettings>,
|
engine_settings: &EngineSettings,
|
||||||
loaded_assets: impl IntoIterator<Item = (String, Asset)>,
|
loaded_assets: impl IntoIterator<Item = (String, Asset)>,
|
||||||
names: impl IntoIterator<Item = (AssetPath, String)>,
|
names: impl IntoIterator<Item = (AssetPath, String)>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
@ -52,7 +52,7 @@ impl AssetCache {
|
||||||
|
|
||||||
let device = context.device().clone();
|
let device = context.device().clone();
|
||||||
let queue = context.queue().clone();
|
let queue = context.queue().clone();
|
||||||
let engine_settings = engine_settings.clone();
|
let render_type = engine_settings.graphics_info()?.render_type;
|
||||||
|
|
||||||
let rw_lock_assets = rw_lock_assets.clone();
|
let rw_lock_assets = rw_lock_assets.clone();
|
||||||
let ready_count = ready_count.clone();
|
let ready_count = ready_count.clone();
|
||||||
|
@ -63,13 +63,7 @@ impl AssetCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
let gltf_asset = GltfAsset::new(&path)?;
|
let gltf_asset = GltfAsset::new(&path)?;
|
||||||
let asset = Asset::new(
|
let asset = Asset::new(&device, &queue, render_type, gltf_asset, &name)?;
|
||||||
&device,
|
|
||||||
&queue,
|
|
||||||
engine_settings.graphics_info()?.render_type,
|
|
||||||
gltf_asset,
|
|
||||||
&name,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut locked_assets = rw_lock_assets.write().unwrap();
|
let mut locked_assets = rw_lock_assets.write().unwrap();
|
|
@ -9,7 +9,7 @@ use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
pub struct AssetManager {
|
pub struct AssetManager {
|
||||||
engine_settings: Arc<EngineSettings>,
|
gltf_directory: AssetPath,
|
||||||
|
|
||||||
gltf_file_list: Vec<String>,
|
gltf_file_list: Vec<String>,
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ pub struct AssetManager {
|
||||||
|
|
||||||
impl AssetManager {
|
impl AssetManager {
|
||||||
/// Constructor for `AssetManager`, creates lists of '.gltf' and '.ent' files
|
/// Constructor for `AssetManager`, creates lists of '.gltf' and '.ent' files
|
||||||
pub(crate) fn new(engine_settings: Arc<EngineSettings>) -> Result<AssetManager> {
|
pub(crate) fn new(engine_settings: &EngineSettings) -> Result<AssetManager> {
|
||||||
let mut asset_manager = AssetManager {
|
let mut asset_manager = AssetManager {
|
||||||
engine_settings,
|
gltf_directory: engine_settings.gltf_directory().clone(),
|
||||||
|
|
||||||
gltf_file_list: Vec::new(),
|
gltf_file_list: Vec::new(),
|
||||||
gltf_file_map: HashMap::new(),
|
gltf_file_map: HashMap::new(),
|
||||||
|
@ -65,7 +65,7 @@ impl AssetManager {
|
||||||
|
|
||||||
pub fn create_cache_with<'a, 'b>(
|
pub fn create_cache_with<'a, 'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &Arc<Context>,
|
world: &World,
|
||||||
asset_names: impl IntoIterator<Item = &'b &'b str> + Clone,
|
asset_names: impl IntoIterator<Item = &'b &'b str> + Clone,
|
||||||
) -> Result<AssetCache> {
|
) -> Result<AssetCache> {
|
||||||
let mut assets = Vec::new();
|
let mut assets = Vec::new();
|
||||||
|
@ -91,7 +91,12 @@ impl AssetManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetCache::new(context, &self.engine_settings, assets, names)
|
AssetCache::new(
|
||||||
|
world.resources.get::<Context>(),
|
||||||
|
world.resources.get::<EngineSettings>(),
|
||||||
|
assets,
|
||||||
|
names,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears all loaded files
|
/// Clears all loaded files
|
||||||
|
@ -111,9 +116,9 @@ impl AssetManager {
|
||||||
/// Updates the lists of all '.gltf' and '.ent' files
|
/// Updates the lists of all '.gltf' and '.ent' files
|
||||||
pub fn update_files(&mut self) -> Result<()> {
|
pub fn update_files(&mut self) -> Result<()> {
|
||||||
let (mut gltf_file_list, gltf_file_map) =
|
let (mut gltf_file_list, gltf_file_map) =
|
||||||
super::search_file_names(self.engine_settings.gltf_directory(), ".gltf")?;
|
super::search_file_names(&self.gltf_directory, ".gltf")?;
|
||||||
let (mut glb_file_list, glb_file_map) =
|
let (mut glb_file_list, glb_file_map) =
|
||||||
super::search_file_names(self.engine_settings.gltf_directory(), ".glb")?;
|
super::search_file_names(&self.gltf_directory, ".glb")?;
|
||||||
|
|
||||||
gltf_file_list.append(&mut glb_file_list);
|
gltf_file_list.append(&mut glb_file_list);
|
||||||
|
|
||||||
|
@ -127,7 +132,7 @@ impl AssetManager {
|
||||||
/// Creates an empty `EditableEntity`
|
/// Creates an empty `EditableEntity`
|
||||||
pub fn load_asset_file(&mut self, world: &mut World, asset_file: &str) -> Result<EntityObject> {
|
pub fn load_asset_file(&mut self, world: &mut World, asset_file: &str) -> Result<EntityObject> {
|
||||||
// load asset
|
// load asset
|
||||||
let asset = self.load_gltf_asset(world.resources.get::<Context>(), asset_file, true)?;
|
let asset = self.load_gltf_asset(world, asset_file, true)?;
|
||||||
|
|
||||||
let mut entity_object = world.new_entity();
|
let mut entity_object = world.new_entity();
|
||||||
|
|
||||||
|
@ -166,7 +171,11 @@ impl AssetManager {
|
||||||
let asset = Asset::new(
|
let asset = Asset::new(
|
||||||
context.device(),
|
context.device(),
|
||||||
context.queue(),
|
context.queue(),
|
||||||
self.engine_settings.graphics_info()?.render_type,
|
world
|
||||||
|
.resources
|
||||||
|
.get::<EngineSettings>()
|
||||||
|
.graphics_info()?
|
||||||
|
.render_type,
|
||||||
gltf_asset,
|
gltf_asset,
|
||||||
asset_path,
|
asset_path,
|
||||||
)?;
|
)?;
|
||||||
|
@ -196,7 +205,7 @@ impl AssetManager {
|
||||||
|
|
||||||
pub fn async_load_gltf_file<'a, 'b>(
|
pub fn async_load_gltf_file<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
context: &Arc<Context>,
|
world: &World,
|
||||||
files: impl IntoIterator<Item = &'b &'b str>,
|
files: impl IntoIterator<Item = &'b &'b str>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut asset_files: Vec<(AssetPath, String)> = Vec::new();
|
let mut asset_files: Vec<(AssetPath, String)> = Vec::new();
|
||||||
|
@ -214,12 +223,15 @@ impl AssetManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = world.resources.get::<Context>();
|
||||||
|
let engine_settings = world.resources.get::<EngineSettings>();
|
||||||
|
|
||||||
// naively spawn for every file a thread
|
// naively spawn for every file a thread
|
||||||
// TODO: spawn thread dependent on the cpu core count
|
// TODO: spawn thread dependent on the cpu core count
|
||||||
for (path, file_name) in asset_files {
|
for (path, file_name) in asset_files {
|
||||||
let device = context.device().clone();
|
let device = context.device().clone();
|
||||||
let queue = context.queue().clone();
|
let queue = context.queue().clone();
|
||||||
let engine_settings = self.engine_settings.clone();
|
let render_type = engine_settings.graphics_info()?.render_type;
|
||||||
|
|
||||||
let loaded_gltf_files = self.loaded_gltf_files.clone();
|
let loaded_gltf_files = self.loaded_gltf_files.clone();
|
||||||
let queued_for_async_load = self.queued_for_async_load.clone();
|
let queued_for_async_load = self.queued_for_async_load.clone();
|
||||||
|
@ -231,13 +243,7 @@ impl AssetManager {
|
||||||
|
|
||||||
let gltf_asset = GltfAsset::new(&path)?;
|
let gltf_asset = GltfAsset::new(&path)?;
|
||||||
|
|
||||||
let asset = Asset::new(
|
let asset = Asset::new(&device, &queue, render_type, gltf_asset, &file_name)?;
|
||||||
&device,
|
|
||||||
&queue,
|
|
||||||
engine_settings.graphics_info()?.render_type,
|
|
||||||
gltf_asset,
|
|
||||||
&file_name,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut gltf_files_lock = loaded_gltf_files.write().unwrap();
|
let mut gltf_files_lock = loaded_gltf_files.write().unwrap();
|
||||||
|
@ -264,7 +270,10 @@ impl AssetManager {
|
||||||
|
|
||||||
/// checks if the '.gltf' file with given name is already loaded, if not, loads it
|
/// checks if the '.gltf' file with given name is already loaded, if not, loads it
|
||||||
/// add - if true, adds the asset to the internal map
|
/// add - if true, adds the asset to the internal map
|
||||||
fn load_gltf_asset(&mut self, context: &Context, gltf_file: &str, add: bool) -> Result<Asset> {
|
fn load_gltf_asset(&mut self, world: &World, gltf_file: &str, add: bool) -> Result<Asset> {
|
||||||
|
let context = world.resources.get::<Context>();
|
||||||
|
let engine_settings = world.resources.get::<EngineSettings>();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let queued_lock = self.queued_for_async_load.read().unwrap();
|
let queued_lock = self.queued_for_async_load.read().unwrap();
|
||||||
|
|
||||||
|
@ -283,7 +292,7 @@ impl AssetManager {
|
||||||
let asset = Asset::new(
|
let asset = Asset::new(
|
||||||
context.device(),
|
context.device(),
|
||||||
context.queue(),
|
context.queue(),
|
||||||
self.engine_settings.graphics_info()?.render_type,
|
engine_settings.graphics_info()?.render_type,
|
||||||
gltf_asset,
|
gltf_asset,
|
||||||
gltf_file,
|
gltf_file,
|
||||||
)?;
|
)?;
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod assetcache;
|
pub mod asset_cache;
|
||||||
pub mod assetmanager;
|
pub mod asset_manager;
|
||||||
|
|
||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use std::marker::PhantomData;
|
use crate::assets::asset_manager::AssetManager;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use crate::assets::assetmanager::AssetManager;
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
@ -12,80 +8,69 @@ pub trait AssetLoader {
|
||||||
fn load_entity(&mut self, assets: AssetHandler<'_>, entity_file: &str) -> Result<EntityObject>;
|
fn load_entity(&mut self, assets: AssetHandler<'_>, entity_file: &str) -> Result<EntityObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct AssetHandler<'a> {
|
pub struct AssetHandler<'a> {
|
||||||
pub(crate) asset_manager: &'a RwLock<AssetManager>,
|
world: &'a mut World,
|
||||||
|
asset_manager: &'a mut AssetManager,
|
||||||
pub(crate) resource_base_path: &'a String,
|
resource_base_path: String,
|
||||||
|
|
||||||
pub(crate) phantom_data: PhantomData<&'a ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AssetHandler<'a> {
|
impl<'a> AssetHandler<'a> {
|
||||||
pub fn context(&self) -> &Arc<Context> {
|
pub fn create(world: &'a mut World) -> Self {
|
||||||
self.context
|
let asset_manager = world.resources.get_mut_unchecked::<AssetManager>();
|
||||||
|
let engine = world.resources.get::<Engine>();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
asset_manager,
|
||||||
|
resource_base_path: engine.resource_base_path.clone(),
|
||||||
|
world,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_file_cache(&self) -> Result<()> {
|
pub fn update_file_cache(&mut self) -> Result<()> {
|
||||||
self.asset_manager.write().unwrap().update_files()
|
self.asset_manager.update_files()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preload_assets<'b>(&self, files: impl IntoIterator<Item = &'b &'b str>) -> Result<()> {
|
pub fn preload_assets<'b>(&self, files: impl IntoIterator<Item = &'b &'b str>) -> Result<()> {
|
||||||
self.asset_manager
|
self.asset_manager.async_load_gltf_file(self.world, files)
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.async_load_gltf_file(self.context, files)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_cache<'b>(
|
pub fn create_cache<'b>(
|
||||||
&self,
|
&mut self,
|
||||||
names: impl IntoIterator<Item = &'b &'b str> + Clone,
|
names: impl IntoIterator<Item = &'b &'b str> + Clone,
|
||||||
) -> Result<AssetCache> {
|
) -> Result<AssetCache> {
|
||||||
self.asset_manager
|
self.asset_manager.create_cache_with(self.world, names)
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.create_cache_with(self.context, names)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_cache(&self, cache: &AssetCache) -> Result<()> {
|
pub fn insert_cache(&self, cache: &AssetCache) -> Result<()> {
|
||||||
self.asset_manager
|
self.asset_manager.insert_cached_assets(cache)
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.insert_cached_assets(cache)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self) -> Result<()> {
|
pub fn clear(&mut self) -> Result<()> {
|
||||||
self.asset_manager.write().unwrap().clear()
|
self.asset_manager.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gltf_files(&self) -> Result<Vec<String>> {
|
pub fn gltf_files(&self) -> Result<Vec<String>> {
|
||||||
Ok(self.asset_manager.read().unwrap().gltf_files().clone())
|
Ok(self.asset_manager.gltf_files().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_entity(&self, asset_file: &str) -> Result<EntityObject> {
|
pub fn create_entity(&mut self, asset_file: &str) -> Result<EntityObject> {
|
||||||
self.asset_manager.write().unwrap().load_asset_file(
|
self.asset_manager.load_asset_file(self.world, asset_file)
|
||||||
self.context,
|
|
||||||
self.entity_object_manager,
|
|
||||||
asset_file,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_entity_absolute(&self, asset_path: &str) -> Result<EntityObject> {
|
pub fn create_entity_absolute(&mut self, asset_path: &str) -> Result<EntityObject> {
|
||||||
self.asset_manager
|
self.asset_manager
|
||||||
.write()
|
.load_asset_file_absolute(self.world, asset_path)
|
||||||
.unwrap()
|
|
||||||
.load_asset_file_absolute(self.context, self.entity_object_manager, asset_path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_entity(&self) -> EntityObject {
|
pub fn empty_entity(&mut self) -> EntityObject {
|
||||||
self.entity_object_manager.create_entity()
|
self.world.new_entity()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resource_base_path(&self) -> &str {
|
pub fn resource_base_path(&self) -> &str {
|
||||||
self.resource_base_path
|
&self.resource_base_path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_entity_id(&self) -> u32 {
|
pub fn world(&mut self) -> &mut World {
|
||||||
self.entity_object_manager.fetch_add_entity_id()
|
&mut self.world
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +1,17 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
use super::asset_handler::AssetHandler;
|
use super::engine_object::*;
|
||||||
|
use super::engine_settings::EngineSettings;
|
||||||
use super::engineobject::*;
|
|
||||||
use super::enginesettings::EngineSettings;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use assetpath::AssetPath;
|
use assetpath::AssetPath;
|
||||||
use context::prelude::cgmath::vec3;
|
use context::prelude::cgmath::vec3;
|
||||||
use loading_screen::LoadingScreen;
|
|
||||||
|
|
||||||
use crate::assets::assetmanager::AssetManager;
|
use crate::assets::asset_manager::AssetManager;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
use std::collections::HashMap;
|
||||||
use std::{collections::HashMap, marker::PhantomData};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::{
|
|
||||||
ptr::NonNull,
|
|
||||||
sync::{Mutex, MutexGuard},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
|
||||||
pub struct EngineCreateInfo<'a> {
|
|
||||||
pub app_info: ApplicationInfo,
|
|
||||||
|
|
||||||
pub window_info: WindowCreateInfo,
|
|
||||||
|
|
||||||
pub os_specific_config: OsSpecificConfig,
|
|
||||||
|
|
||||||
pub vulkan_debug_info: VulkanDebugInfo,
|
|
||||||
pub volume_info: HashMap<String, f32>,
|
|
||||||
|
|
||||||
pub gui_info: GuiHandlerCreateInfo<'a>,
|
|
||||||
|
|
||||||
pub enable_backtrace: bool,
|
|
||||||
pub enable_mouse: bool,
|
|
||||||
pub enable_keyboard: bool,
|
|
||||||
pub enable_controller: bool,
|
|
||||||
|
|
||||||
pub controller_deadzones: ControllerDeadzones,
|
|
||||||
|
|
||||||
pub resource_base_path: String,
|
|
||||||
|
|
||||||
// engine settings
|
|
||||||
pub controller_directories: ControllerPictureDirectories,
|
|
||||||
pub asset_directories: AssetDirectories,
|
|
||||||
|
|
||||||
pub graphics_info: GraphicsInfo,
|
|
||||||
pub raytracing_info: RaytracingInfo,
|
|
||||||
pub rasterizer_info: RasterizerInfo,
|
|
||||||
pub key_backgrounds: ButtonBackgrounds,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GuiPostProcess(Arc<GuiHandler>);
|
struct GuiPostProcess(Arc<GuiHandler>);
|
||||||
|
|
||||||
|
@ -73,37 +34,34 @@ impl context::prelude::PostProcess for GuiPostProcess {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
engine_settings: Arc<EngineSettings>,
|
|
||||||
|
|
||||||
gui_handler: Arc<GuiHandler>,
|
|
||||||
gui_post_process: Arc<GuiPostProcess>,
|
|
||||||
input: Arc<RwLock<Input>>,
|
input: Arc<RwLock<Input>>,
|
||||||
|
|
||||||
// loads and keeps track of raw data
|
// loads and keeps track of raw data
|
||||||
asset_manager: AssetManager,
|
asset_manager: AssetManager,
|
||||||
|
|
||||||
resource_base_path: String,
|
pub(crate) resource_base_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn new(#[allow(unused)] mut create_info: EngineCreateInfo<'_>) -> Result<Self> {
|
pub fn new(
|
||||||
if let Font::Path(path) = &mut create_info.gui_info.font {
|
#[allow(unused)] mut create_info: EngineCreateInfo<'_>,
|
||||||
path.set_prefix(&create_info.resource_base_path);
|
world: &mut WorldBuilder,
|
||||||
}
|
) -> Result<()> {
|
||||||
create_info.gui_info.resource_directory.assume_prefix_free();
|
|
||||||
|
|
||||||
create_info
|
create_info
|
||||||
.controller_directories
|
.controller_directories
|
||||||
.xbox_path
|
.xbox_path
|
||||||
.set_prefix(&create_info.resource_base_path);
|
.as_mut()
|
||||||
|
.map(|p| p.set_prefix(&create_info.resource_base_path));
|
||||||
create_info
|
create_info
|
||||||
.controller_directories
|
.controller_directories
|
||||||
.steam_path
|
.steam_path
|
||||||
.set_prefix(&create_info.resource_base_path);
|
.as_mut()
|
||||||
|
.map(|p| p.set_prefix(&create_info.resource_base_path));
|
||||||
create_info
|
create_info
|
||||||
.controller_directories
|
.controller_directories
|
||||||
.ps4_path
|
.ps4_path
|
||||||
.set_prefix(&create_info.resource_base_path);
|
.as_mut()
|
||||||
|
.map(|p| p.set_prefix(&create_info.resource_base_path));
|
||||||
|
|
||||||
create_info
|
create_info
|
||||||
.asset_directories
|
.asset_directories
|
||||||
|
@ -129,7 +87,7 @@ impl Engine {
|
||||||
|
|
||||||
// --------------- context --------------------
|
// --------------- context --------------------
|
||||||
|
|
||||||
let context = {
|
let mut context = {
|
||||||
create_info.app_info.engine_name = "EngineNameNeeded".to_string();
|
create_info.app_info.engine_name = "EngineNameNeeded".to_string();
|
||||||
create_info.app_info.engine_version = 1;
|
create_info.app_info.engine_version = 1;
|
||||||
|
|
||||||
|
@ -182,10 +140,9 @@ impl Engine {
|
||||||
};
|
};
|
||||||
|
|
||||||
// update sound handler center
|
// update sound handler center
|
||||||
{
|
context
|
||||||
let sound_handler = context.sound();
|
.sound()
|
||||||
sound_handler.set_direction(vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0))?;
|
.set_direction(vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0))?;
|
||||||
}
|
|
||||||
|
|
||||||
// --------------- settings -------------------
|
// --------------- settings -------------------
|
||||||
|
|
||||||
|
@ -198,7 +155,7 @@ impl Engine {
|
||||||
.ok_or_else(|| anyhow::Error::msg("No proper render type could be found"))?;
|
.ok_or_else(|| anyhow::Error::msg("No proper render type could be found"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let engine_settings = Arc::new(EngineSettings::new(
|
let engine_settings = EngineSettings::new(
|
||||||
&context,
|
&context,
|
||||||
create_info.graphics_info,
|
create_info.graphics_info,
|
||||||
create_info.raytracing_info,
|
create_info.raytracing_info,
|
||||||
|
@ -207,15 +164,26 @@ impl Engine {
|
||||||
create_info.asset_directories,
|
create_info.asset_directories,
|
||||||
create_info.key_backgrounds,
|
create_info.key_backgrounds,
|
||||||
create_info.resource_base_path.clone(),
|
create_info.resource_base_path.clone(),
|
||||||
)?);
|
|
||||||
|
|
||||||
let asset_manager = AssetManager::new(engine_settings.clone())?;
|
|
||||||
|
|
||||||
let gui_handler = GuiHandler::new(
|
|
||||||
create_info.gui_info,
|
|
||||||
&(context.clone() as Arc<dyn ContextInterface>),
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let asset_manager = AssetManager::new(&engine_settings)?;
|
||||||
|
|
||||||
|
if let Some(mut gui_info) = create_info.gui_info {
|
||||||
|
if let Font::Path(path) = &mut gui_info.font {
|
||||||
|
path.set_prefix(&create_info.resource_base_path);
|
||||||
|
}
|
||||||
|
gui_info.resource_directory.assume_prefix_free();
|
||||||
|
|
||||||
|
let gui_handler = GuiHandler::new(gui_info, &context)?;
|
||||||
|
|
||||||
|
let gui_post_process = Arc::new(GuiPostProcess(gui_handler.clone()));
|
||||||
|
context
|
||||||
|
.render_core()
|
||||||
|
.add_post_processing_routine(gui_post_process.clone());
|
||||||
|
|
||||||
|
world.resources.insert(gui_handler);
|
||||||
|
}
|
||||||
|
|
||||||
// default keyboard navigation
|
// default keyboard navigation
|
||||||
let mut direction_mapping = HashMap::new();
|
let mut direction_mapping = HashMap::new();
|
||||||
// direction_mapping.insert(Keycode::A, GuiDirection::Left);
|
// direction_mapping.insert(Keycode::A, GuiDirection::Left);
|
||||||
|
@ -227,105 +195,62 @@ impl Engine {
|
||||||
direction_mapping.insert(Keycode::Up, GuiDirection::Up);
|
direction_mapping.insert(Keycode::Up, GuiDirection::Up);
|
||||||
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
direction_mapping.insert(Keycode::Down, GuiDirection::Down);
|
||||||
|
|
||||||
let input = Input { direction_mapping };
|
let engine = Engine {
|
||||||
|
input: Arc::new(RwLock::new(Input { direction_mapping })),
|
||||||
let gui_post_process = Arc::new(GuiPostProcess(gui_handler.clone()));
|
|
||||||
context
|
|
||||||
.render_core()
|
|
||||||
.add_post_processing_routine(gui_post_process.clone());
|
|
||||||
|
|
||||||
Ok(Engine {
|
|
||||||
gui_post_process,
|
|
||||||
gui_handler,
|
|
||||||
input: Arc::new(RwLock::new(input)),
|
|
||||||
|
|
||||||
asset_manager,
|
asset_manager,
|
||||||
|
|
||||||
resource_base_path: create_info.resource_base_path,
|
resource_base_path: create_info.resource_base_path,
|
||||||
|
};
|
||||||
|
|
||||||
engine_settings,
|
world.resources.insert(context);
|
||||||
})
|
world.resources.insert(engine);
|
||||||
}
|
world.resources.insert(engine_settings);
|
||||||
|
|
||||||
pub fn set_game_object<E>(&self, engine_object: Option<E>) -> Result<()>
|
world.add_system(Self::main_system);
|
||||||
where
|
|
||||||
E: EngineObject + Send + Sync,
|
|
||||||
{
|
|
||||||
self.context().set_context_object(match engine_object {
|
|
||||||
Some(engine_object) => Some(ContextObjectImpl::new(
|
|
||||||
self.graphical.context.clone(),
|
|
||||||
engine_object,
|
|
||||||
self.graphical.input.clone(),
|
|
||||||
self.gui_handler().clone(),
|
|
||||||
)?),
|
|
||||||
None => None,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn loading_screen<T, R, L, G>(
|
// pub fn set_game_object<E>(&self, engine_object: Option<E>) -> Result<()>
|
||||||
&self,
|
// where
|
||||||
gui: Option<Arc<G>>,
|
// E: EngineObject + Send + Sync,
|
||||||
loader: L,
|
// {
|
||||||
on_ready: R,
|
// self.context().set_context_object(match engine_object {
|
||||||
) -> Result<()>
|
// Some(engine_object) => Some(ContextObjectImpl::new(
|
||||||
where
|
// self.graphical.context.clone(),
|
||||||
R: Fn(T) -> anyhow::Result<()> + 'static + Send + Sync,
|
// engine_object,
|
||||||
T: Send + Sync + 'static,
|
// self.graphical.input.clone(),
|
||||||
L: FnOnce() -> T + Send + Sync + 'static,
|
// self.gui_handler().clone(),
|
||||||
G: TopLevelGui + TopGui + Send + Sync + 'static,
|
// )?),
|
||||||
{
|
// None => None,
|
||||||
LoadingScreen::load(self.context(), gui, loader, on_ready)
|
// });
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_point_light(&self) -> Result<Light> {
|
// Ok(())
|
||||||
Light::point_light(self.context().device())
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_directional_light(&self) -> Result<Light> {
|
// pub fn loading_screen<T, R, L, G>(
|
||||||
Light::directional_light(self.context().device())
|
// &self,
|
||||||
}
|
// gui: Option<Arc<G>>,
|
||||||
|
// loader: L,
|
||||||
pub fn new_spot_light(&self) -> Result<Light> {
|
// on_ready: R,
|
||||||
Light::spot_light(self.context().device())
|
// ) -> Result<()>
|
||||||
}
|
// where
|
||||||
|
// R: Fn(T) -> anyhow::Result<()> + 'static + Send + Sync,
|
||||||
pub fn controller_icon(&self, button: ControllerButton) -> Result<Arc<Image>> {
|
// T: Send + Sync + 'static,
|
||||||
Ok(self.settings().controller_icon(self, button)?.unwrap_or(
|
// L: FnOnce() -> T + Send + Sync + 'static,
|
||||||
self.settings()
|
// G: TopLevelGui + TopGui + Send + Sync + 'static,
|
||||||
.controller_button_for(self, button, ControllerType::XBox)?,
|
// {
|
||||||
))
|
// LoadingScreen::load(self.context(), gui, loader, on_ready)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn build_path(&self, path: &str) -> AssetPath {
|
pub fn build_path(&self, path: &str) -> AssetPath {
|
||||||
(self.resource_base_path.as_str(), path).into()
|
(self.resource_base_path.as_str(), path).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assets(&self) -> AssetHandler<'_> {
|
pub fn main_system(world: &mut World) -> Result<()> {
|
||||||
AssetHandler {
|
//
|
||||||
asset_manager: &self.asset_manager,
|
|
||||||
|
|
||||||
context: &self.graphical.context,
|
Ok(())
|
||||||
|
|
||||||
resource_base_path: &self.resource_base_path,
|
|
||||||
|
|
||||||
phantom_data: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getter
|
|
||||||
impl Engine {
|
|
||||||
pub fn settings(&self) -> &Arc<EngineSettings> {
|
|
||||||
&self.engine_settings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Engine {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.context
|
|
||||||
.render_core()
|
|
||||||
.remove_post_processing_routine(self.gui_post_process.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
97
engine/src/engine/engine_create_info.rs
Normal file
97
engine/src/engine/engine_create_info.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EngineCreateInfo<'a> {
|
||||||
|
pub app_info: ApplicationInfo,
|
||||||
|
|
||||||
|
pub window_info: WindowCreateInfo,
|
||||||
|
|
||||||
|
pub os_specific_config: OsSpecificConfig,
|
||||||
|
|
||||||
|
pub vulkan_debug_info: VulkanDebugInfo,
|
||||||
|
pub volume_info: HashMap<String, f32>,
|
||||||
|
|
||||||
|
pub gui_info: Option<GuiHandlerCreateInfo<'a>>,
|
||||||
|
|
||||||
|
pub enable_backtrace: bool,
|
||||||
|
pub enable_mouse: bool,
|
||||||
|
pub enable_keyboard: bool,
|
||||||
|
pub enable_controller: bool,
|
||||||
|
|
||||||
|
pub controller_deadzones: ControllerDeadzones,
|
||||||
|
|
||||||
|
pub resource_base_path: String,
|
||||||
|
|
||||||
|
// engine settings
|
||||||
|
pub controller_directories: ControllerPictureDirectories,
|
||||||
|
pub asset_directories: AssetDirectories,
|
||||||
|
|
||||||
|
pub graphics_info: GraphicsInfo,
|
||||||
|
pub raytracing_info: RaytracingInfo,
|
||||||
|
pub rasterizer_info: RasterizerInfo,
|
||||||
|
pub key_backgrounds: ButtonBackgrounds,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for EngineCreateInfo<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
app_info: ApplicationInfo {
|
||||||
|
application_name: "Default Application Name".to_string(),
|
||||||
|
application_version: 1,
|
||||||
|
engine_name: "Default Engine Name".to_string(),
|
||||||
|
engine_version: 1,
|
||||||
|
},
|
||||||
|
window_info: WindowCreateInfo {
|
||||||
|
title: "Default Window Title".to_string(),
|
||||||
|
width: 1600,
|
||||||
|
height: 900,
|
||||||
|
fullscreen: false,
|
||||||
|
requested_display: None,
|
||||||
|
},
|
||||||
|
os_specific_config: OsSpecificConfig {
|
||||||
|
enable_game_mode: true,
|
||||||
|
},
|
||||||
|
vulkan_debug_info: VulkanDebugInfo {
|
||||||
|
debugging: false,
|
||||||
|
steam_layer: false,
|
||||||
|
verbose: false,
|
||||||
|
renderdoc: false,
|
||||||
|
},
|
||||||
|
volume_info: HashMap::new(),
|
||||||
|
gui_info: None,
|
||||||
|
enable_backtrace: true,
|
||||||
|
enable_mouse: true,
|
||||||
|
enable_keyboard: true,
|
||||||
|
enable_controller: true,
|
||||||
|
controller_deadzones: ControllerDeadzones::default(),
|
||||||
|
resource_base_path: String::new(),
|
||||||
|
controller_directories: ControllerPictureDirectories::default(),
|
||||||
|
asset_directories: AssetDirectories::default(),
|
||||||
|
graphics_info: GraphicsInfo {
|
||||||
|
sample_count: VK_SAMPLE_COUNT_4_BIT,
|
||||||
|
render_type: SceneType::Raytracer,
|
||||||
|
render_scale: 1.0,
|
||||||
|
vsync: true,
|
||||||
|
},
|
||||||
|
raytracing_info: RaytracingInfo {
|
||||||
|
triangles_per_as: 8,
|
||||||
|
accelerate_buffer_size: 1024,
|
||||||
|
stack_size: 32,
|
||||||
|
|
||||||
|
max_lights: 32,
|
||||||
|
recursion_depth: 3,
|
||||||
|
use_default_pipeline: true,
|
||||||
|
max_samplers: 1024,
|
||||||
|
},
|
||||||
|
rasterizer_info: RasterizerInfo {
|
||||||
|
shadow_image_size: 1024,
|
||||||
|
enable_lighting: true,
|
||||||
|
use_deferred: false,
|
||||||
|
use_shadow_maps: false,
|
||||||
|
},
|
||||||
|
key_backgrounds: ButtonBackgrounds::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::Result;
|
use anyhow::{Result, bail};
|
||||||
use assetpath::AssetPath;
|
use assetpath::AssetPath;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -54,9 +54,9 @@ pub struct RasterizerInfo {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ControllerPictureDirectories {
|
pub struct ControllerPictureDirectories {
|
||||||
pub xbox_path: AssetPath,
|
pub xbox_path: Option<AssetPath>,
|
||||||
pub steam_path: AssetPath,
|
pub steam_path: Option<AssetPath>,
|
||||||
pub ps4_path: AssetPath,
|
pub ps4_path: Option<AssetPath>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
@ -97,7 +97,7 @@ pub struct EngineSettings {
|
||||||
impl EngineSettings {
|
impl EngineSettings {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
context: &Arc<Context>,
|
context: &Context,
|
||||||
mut graphics_info: GraphicsInfo,
|
mut graphics_info: GraphicsInfo,
|
||||||
raytracing_info: RaytracingInfo,
|
raytracing_info: RaytracingInfo,
|
||||||
rasterizer_info: RasterizerInfo,
|
rasterizer_info: RasterizerInfo,
|
||||||
|
@ -191,15 +191,25 @@ impl EngineSettings {
|
||||||
|
|
||||||
pub fn controller_icon(
|
pub fn controller_icon(
|
||||||
&self,
|
&self,
|
||||||
engine: &Engine,
|
context: &Context,
|
||||||
|
button: ControllerButton,
|
||||||
|
) -> Result<Arc<Image>> {
|
||||||
|
Ok(self
|
||||||
|
._controller_icon(context, button)?
|
||||||
|
.unwrap_or(self.controller_button_for(context, button, ControllerType::XBox)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _controller_icon(
|
||||||
|
&self,
|
||||||
|
context: &Context,
|
||||||
button: ControllerButton,
|
button: ControllerButton,
|
||||||
) -> Result<Option<Arc<Image>>> {
|
) -> Result<Option<Arc<Image>>> {
|
||||||
// TODO: don't check it every time we request a button
|
// TODO: don't check it every time we request a button
|
||||||
self.check_controller(engine.context())?;
|
self.check_controller(context)?;
|
||||||
|
|
||||||
match self.current_controller_type.read().unwrap().as_ref() {
|
match self.current_controller_type.read().unwrap().as_ref() {
|
||||||
Some(controller_type) => Ok(Some(self.controller_button_for(
|
Some(controller_type) => Ok(Some(self.controller_button_for(
|
||||||
engine,
|
context,
|
||||||
button,
|
button,
|
||||||
*controller_type,
|
*controller_type,
|
||||||
)?)),
|
)?)),
|
||||||
|
@ -209,7 +219,7 @@ impl EngineSettings {
|
||||||
|
|
||||||
pub fn controller_button_for(
|
pub fn controller_button_for(
|
||||||
&self,
|
&self,
|
||||||
engine: &Engine,
|
context: &Context,
|
||||||
button: ControllerButton,
|
button: ControllerButton,
|
||||||
controller: ControllerType,
|
controller: ControllerType,
|
||||||
) -> Result<Arc<Image>> {
|
) -> Result<Arc<Image>> {
|
||||||
|
@ -219,26 +229,27 @@ impl EngineSettings {
|
||||||
return Ok(image.clone());
|
return Ok(image.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let image_path = match controller {
|
let image_path_opt = match controller {
|
||||||
ControllerType::PS4 => AssetPath::from((
|
ControllerType::PS4 => self.controller_directories.ps4_path.as_ref().map(|path| {
|
||||||
self.controller_directories.ps4_path.full_path(),
|
AssetPath::from((path.full_path(), Self::ps4_input_map_to_texture(&button)))
|
||||||
Self::ps4_input_map_to_texture(&button),
|
}),
|
||||||
)),
|
ControllerType::Steam => self.controller_directories.steam_path.as_ref().map(|path| {
|
||||||
ControllerType::Steam => AssetPath::from((
|
AssetPath::from((path.full_path(), Self::steam_input_map_to_texture(&button)))
|
||||||
self.controller_directories.steam_path.full_path(),
|
}),
|
||||||
Self::steam_input_map_to_texture(&button),
|
|
||||||
)),
|
ControllerType::XBox => self.controller_directories.xbox_path.as_ref().map(|path| {
|
||||||
ControllerType::XBox => AssetPath::from((
|
AssetPath::from((path.full_path(), Self::xbox_input_map_to_texture(&button)))
|
||||||
self.controller_directories.xbox_path.full_path(),
|
}),
|
||||||
Self::xbox_input_map_to_texture(&button),
|
|
||||||
)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctx = engine.context();
|
let image_path = match image_path_opt {
|
||||||
|
Some(p) => p,
|
||||||
|
None => bail!("path not set"),
|
||||||
|
};
|
||||||
|
|
||||||
let image = Image::from_file(image_path)?
|
let image = Image::from_file(image_path)?
|
||||||
.attach_sampler(Sampler::nearest_sampler().build(ctx.device())?)
|
.attach_sampler(Sampler::nearest_sampler().build(context.device())?)
|
||||||
.build(ctx.device(), ctx.queue())?;
|
.build(context.device(), context.queue())?;
|
||||||
|
|
||||||
map.insert(button, image.clone());
|
map.insert(button, image.clone());
|
||||||
|
|
||||||
|
@ -336,8 +347,8 @@ impl EngineSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_controller(&self, context: &Arc<Context>) -> Result<()> {
|
fn check_controller(&self, context: &Context) -> Result<()> {
|
||||||
let active_controller = context.active_controller()?;
|
let active_controller = context.active_controller();
|
||||||
|
|
||||||
match &active_controller {
|
match &active_controller {
|
||||||
// there is an controller connected
|
// there is an controller connected
|
|
@ -1,7 +1,8 @@
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod enginesettings;
|
pub mod engine_settings;
|
||||||
|
|
||||||
pub mod engineobject;
|
pub mod engine_object;
|
||||||
|
|
||||||
pub mod asset_handler;
|
pub mod asset_handler;
|
||||||
|
pub mod engine_create_info;
|
||||||
// pub mod engine_object_data;
|
// pub mod engine_object_data;
|
||||||
|
|
|
@ -7,18 +7,13 @@ pub use loading_screen::*;
|
||||||
pub use crate::scene::prelude::*;
|
pub use crate::scene::prelude::*;
|
||||||
|
|
||||||
pub use crate::engine::{
|
pub use crate::engine::{
|
||||||
// engine_object_data::*,
|
asset_handler::{AssetHandler, AssetLoader},
|
||||||
engineobject::{
|
engine::*,
|
||||||
EngineObject,
|
engine_create_info::EngineCreateInfo,
|
||||||
// EngineObjectHelper
|
engine_object::{EngineEvent, EngineObject},
|
||||||
},
|
engine_settings::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::engine::asset_handler::{AssetHandler, AssetLoader};
|
|
||||||
pub use crate::engine::{engine::*, enginesettings::*};
|
|
||||||
|
|
||||||
pub use crate::engine::engineobject::EngineEvent;
|
|
||||||
|
|
||||||
pub use serde::{
|
pub use serde::{
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
Deserialize, Deserializer, Serialize, Serializer,
|
||||||
ser::{SerializeMap, SerializeSeq, SerializeStruct},
|
ser::{SerializeMap, SerializeSeq, SerializeStruct},
|
||||||
|
@ -27,7 +22,7 @@ pub use serde::{
|
||||||
pub use ecs::*;
|
pub use ecs::*;
|
||||||
pub use ron;
|
pub use ron;
|
||||||
|
|
||||||
pub use crate::assets::assetcache::AssetCache;
|
pub use crate::assets::asset_cache::AssetCache;
|
||||||
|
|
||||||
pub use asset::*;
|
pub use asset::*;
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,11 @@ pub struct Audio {
|
||||||
|
|
||||||
current_state: Option<Arc<Sound>>,
|
current_state: Option<Arc<Sound>>,
|
||||||
position: Vector3<f32>,
|
position: Vector3<f32>,
|
||||||
context: Arc<Context>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Audio {
|
impl Audio {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
context: &Arc<Context>,
|
context: &mut Context,
|
||||||
sounds: impl Into<Option<HashMap<String, AssetPath>>>,
|
sounds: impl Into<Option<HashMap<String, AssetPath>>>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut sound_map = HashMap::new();
|
let mut sound_map = HashMap::new();
|
||||||
|
@ -43,12 +42,11 @@ impl Audio {
|
||||||
|
|
||||||
current_state: None,
|
current_state: None,
|
||||||
position: Vector3::zero(),
|
position: Vector3::zero(),
|
||||||
context: context.clone(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_info(
|
pub fn from_info(
|
||||||
context: &Arc<Context>,
|
context: &mut Context,
|
||||||
data_prefix: &str,
|
data_prefix: &str,
|
||||||
sounds: Vec<(String, AssetPath)>,
|
sounds: Vec<(String, AssetPath)>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
@ -75,10 +73,14 @@ impl Audio {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_sound(&mut self, path: AssetPath, sound_type: &str) -> Result<()> {
|
pub fn set_sound(
|
||||||
|
&mut self,
|
||||||
|
context: &mut Context,
|
||||||
|
path: AssetPath,
|
||||||
|
sound_type: &str,
|
||||||
|
) -> Result<()> {
|
||||||
if let Some(audio) = self.custom_sounds.get_mut(sound_type) {
|
if let Some(audio) = self.custom_sounds.get_mut(sound_type) {
|
||||||
*audio = self
|
*audio = context
|
||||||
.context
|
|
||||||
.sound()
|
.sound()
|
||||||
.load_sound(path, "sfx", SoundInterpretation::Spatial)?;
|
.load_sound(path, "sfx", SoundInterpretation::Spatial)?;
|
||||||
}
|
}
|
||||||
|
@ -101,9 +103,9 @@ impl Audio {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(&mut self) -> Result<()> {
|
fn clear(&mut self, context: &mut Context) -> Result<()> {
|
||||||
for sound in self.custom_sounds.values() {
|
for sound in self.custom_sounds.values() {
|
||||||
self.context.sound().remove_sound(sound)?;
|
context.sound().remove_sound(sound)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -147,10 +149,15 @@ impl Audio {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_custom_sound(&mut self, path: AssetPath, sound_type: &str) -> Result<()> {
|
pub fn add_custom_sound(
|
||||||
|
&mut self,
|
||||||
|
context: &mut Context,
|
||||||
|
path: AssetPath,
|
||||||
|
sound_type: &str,
|
||||||
|
) -> Result<()> {
|
||||||
self.custom_sounds.insert(
|
self.custom_sounds.insert(
|
||||||
sound_type.to_string(),
|
sound_type.to_string(),
|
||||||
self.context
|
context
|
||||||
.sound()
|
.sound()
|
||||||
.load_sound(path, "sfx", SoundInterpretation::Spatial)?,
|
.load_sound(path, "sfx", SoundInterpretation::Spatial)?,
|
||||||
);
|
);
|
||||||
|
@ -168,8 +175,14 @@ impl EntityComponent for Audio {
|
||||||
self.play(ON_ENABLE_SOUND, false)
|
self.play(ON_ENABLE_SOUND, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable(&mut self, _world: &mut World) -> Result<()> {
|
fn disable(&mut self, world: &mut World) -> Result<()> {
|
||||||
self.play(ON_DISABLE_SOUND, false)
|
self.play(ON_DISABLE_SOUND, false)?;
|
||||||
|
|
||||||
|
if let Some(sound) = &self.current_state {
|
||||||
|
sound.stop_looping().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.clear(world.resources.get_mut::<Context>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,13 +191,3 @@ impl ComponentDebug for Audio {
|
||||||
"Audio"
|
"Audio"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Audio {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(sound) = &self.current_state {
|
|
||||||
sound.stop_looping().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.clear().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ use rayon::prelude::*;
|
||||||
use utilities::prelude::cgmath::{Matrix4, Vector3, vec3};
|
use utilities::prelude::cgmath::{Matrix4, Vector3, vec3};
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time::Instant;
|
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
@ -32,18 +31,15 @@ pub struct Scene {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<Mutex<Queue>>,
|
queue: Arc<Mutex<Queue>>,
|
||||||
|
|
||||||
pub(crate) render_type: SceneType,
|
render_type: SceneType,
|
||||||
|
|
||||||
pub(crate) map: Option<Box<dyn Map>>,
|
last_frame: Duration,
|
||||||
|
frame_time: Duration,
|
||||||
pub(crate) start_time: Instant,
|
|
||||||
pub(crate) last_frame: Duration,
|
|
||||||
pub(crate) frame_time: Duration,
|
|
||||||
|
|
||||||
// renderer of this scene
|
// renderer of this scene
|
||||||
pub(crate) renderer: Box<dyn RenderingFrontEnd + Send + Sync>,
|
renderer: Box<dyn RenderingFrontEnd + Send + Sync>,
|
||||||
|
|
||||||
pub(crate) frustum_check: Option<
|
frustum_check: Option<
|
||||||
Box<
|
Box<
|
||||||
dyn Fn(&EntityObject, &Matrix4<f32>, &ViewFrustum, &FrustumPlanes) -> Result<bool>
|
dyn Fn(&EntityObject, &Matrix4<f32>, &ViewFrustum, &FrustumPlanes) -> Result<bool>
|
||||||
+ Send
|
+ Send
|
||||||
|
@ -51,10 +47,10 @@ pub struct Scene {
|
||||||
>,
|
>,
|
||||||
>,
|
>,
|
||||||
|
|
||||||
pub(crate) particle_system_vulkan_objects: ParticleSystemVulkanObjects,
|
particle_system_vulkan_objects: ParticleSystemVulkanObjects,
|
||||||
|
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
pub(crate) timings: Timings,
|
timings: Timings,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
|
@ -87,7 +83,7 @@ impl Scene {
|
||||||
|
|
||||||
let particle_system_vulkan_objects = ParticleSystemVulkanObjects::new(device, queue, cs)?;
|
let particle_system_vulkan_objects = ParticleSystemVulkanObjects::new(device, queue, cs)?;
|
||||||
|
|
||||||
let mut scene = Scene {
|
let scene = Scene {
|
||||||
screen_width,
|
screen_width,
|
||||||
screen_height,
|
screen_height,
|
||||||
|
|
||||||
|
@ -95,13 +91,11 @@ impl Scene {
|
||||||
|
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
queue: queue.clone(),
|
queue: queue.clone(),
|
||||||
map: None,
|
|
||||||
|
|
||||||
frustum_check: None,
|
frustum_check: None,
|
||||||
|
|
||||||
renderer,
|
renderer,
|
||||||
|
|
||||||
start_time: Instant::now(),
|
|
||||||
last_frame: Duration::from_secs(0),
|
last_frame: Duration::from_secs(0),
|
||||||
frame_time: Duration::from_secs(0),
|
frame_time: Duration::from_secs(0),
|
||||||
|
|
||||||
|
@ -124,19 +118,6 @@ impl Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// object handling
|
|
||||||
impl Scene {
|
|
||||||
pub fn set_map(&mut self, map_opt: Option<Box<dyn Map>>) -> Result<()> {
|
|
||||||
if let Some(old_map) = self.map.take() {
|
|
||||||
old_map.disable(self)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.map = map_opt;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
pub(crate) fn _world_to_screen_space(
|
pub(crate) fn _world_to_screen_space(
|
||||||
(screen_width, screen_height): (f32, f32),
|
(screen_width, screen_height): (f32, f32),
|
||||||
|
@ -189,12 +170,13 @@ impl Scene {
|
||||||
VkCommandBufferBeginInfo::new(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
VkCommandBufferBeginInfo::new(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
begin_info.set_inheritance_info(&inheritance_info);
|
begin_info.set_inheritance_info(&inheritance_info);
|
||||||
|
|
||||||
let scene = world.resources.get_mut::<Scene>();
|
let scene = world.resources.get_mut_unchecked::<Scene>();
|
||||||
|
|
||||||
let particle_handles = scene.particle_system_vulkan_objects_mut();
|
let particle_handles = scene.particle_system_vulkan_objects_mut();
|
||||||
|
let pipeline = particle_handles.pipeline.clone();
|
||||||
let mut recorder = particle_handles.begin(begin_info)?;
|
let mut recorder = particle_handles.begin(begin_info)?;
|
||||||
|
|
||||||
particle_system.animate(&mut recorder, &particle_handles.pipeline, world)?;
|
particle_system.animate(&mut recorder, &pipeline, world)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -405,9 +387,10 @@ 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,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
self.frame_time = {
|
self.frame_time = {
|
||||||
let now = self.now();
|
let now = world.now();
|
||||||
|
|
||||||
let d = if self.last_frame < now {
|
let d = if self.last_frame < now {
|
||||||
now - self.last_frame
|
now - self.last_frame
|
||||||
|
@ -430,11 +413,8 @@ impl TScene for Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate movements and collision detection when map is present
|
|
||||||
if self.map.is_some() {
|
|
||||||
self.update()?;
|
|
||||||
|
|
||||||
// queue particle system commands
|
// queue particle system commands
|
||||||
|
{
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
let before = Instant::now();
|
let before = Instant::now();
|
||||||
|
|
||||||
|
@ -446,6 +426,8 @@ impl TScene for Scene {
|
||||||
.add("particles", Instant::now().duration_since(before));
|
.add("particles", Instant::now().duration_since(before));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gather entities
|
||||||
|
let content = {
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
let before = Instant::now();
|
let before = Instant::now();
|
||||||
|
|
||||||
|
@ -457,9 +439,8 @@ impl TScene for Scene {
|
||||||
let frustum = view.frustum();
|
let frustum = view.frustum();
|
||||||
let planes = frustum.planes();
|
let planes = frustum.planes();
|
||||||
|
|
||||||
let content: Vec<Option<&EntityObject>> = self
|
let content: Vec<Option<&EntityObject>> = world
|
||||||
.entities
|
.entities()
|
||||||
.par_values()
|
|
||||||
.map(|entity_object| {
|
.map(|entity_object| {
|
||||||
if frustum_check(entity_object, &vp, &frustum, &planes)? {
|
if frustum_check(entity_object, &vp, &frustum, &planes)? {
|
||||||
Ok(Some(entity_object))
|
Ok(Some(entity_object))
|
||||||
|
@ -471,25 +452,28 @@ impl TScene for Scene {
|
||||||
|
|
||||||
content.into_iter().flatten().collect()
|
content.into_iter().flatten().collect()
|
||||||
}
|
}
|
||||||
None => self
|
None => world.entities().collect(),
|
||||||
.entities
|
|
||||||
.par_iter()
|
|
||||||
.map(|(_entity, entity_object)| entity_object)
|
|
||||||
.collect(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
self.timings
|
self.timings
|
||||||
.add("frustum", Instant::now().duration_since(before));
|
.add("frustum", Instant::now().duration_since(before));
|
||||||
|
|
||||||
|
content
|
||||||
|
};
|
||||||
|
|
||||||
|
// render
|
||||||
|
{
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
let before = Instant::now();
|
let before = Instant::now();
|
||||||
|
|
||||||
self.renderer
|
self.renderer
|
||||||
.process(content, buffer_recorder, images, indices)?;
|
.process(content, buffer_recorder, images, indices)?;
|
||||||
|
|
||||||
#[cfg(feature = "timings")]
|
#[cfg(feature = "timings")]
|
||||||
self.timings
|
self.timings
|
||||||
.add("renderer", Instant::now().duration_since(before));
|
.add("renderer", Instant::now().duration_since(before));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,11 @@ impl EntityManager {
|
||||||
|
|
||||||
impl AssetLoader for EntityManager {
|
impl AssetLoader for EntityManager {
|
||||||
/// Loads an entity file and creates an Entity
|
/// Loads an entity file and creates an Entity
|
||||||
fn load_entity(&mut self, assets: AssetHandler<'_>, entity_file: &str) -> Result<EntityObject> {
|
fn load_entity(
|
||||||
|
&mut self,
|
||||||
|
mut assets: AssetHandler<'_>,
|
||||||
|
entity_file: &str,
|
||||||
|
) -> Result<EntityObject> {
|
||||||
// load entity file
|
// load entity file
|
||||||
let file = self.load_entity_file(entity_file);
|
let file = self.load_entity_file(entity_file);
|
||||||
|
|
||||||
|
@ -165,7 +169,10 @@ impl AssetLoader for EntityManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_object.insert_component(Audio::new(assets.context(), entity_parser.sound_map)?);
|
entity_object.insert_component(Audio::new(
|
||||||
|
assets.world().resources.get_mut::<Context>(),
|
||||||
|
entity_parser.sound_map,
|
||||||
|
)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(entity_object)
|
Ok(entity_object)
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub enum CollisionEventType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type HitCallback =
|
pub type HitCallback =
|
||||||
dyn FnMut(&mut SceneContents<'_>, Entity, Entity) -> Result<CollisionEventType> + Send + Sync;
|
dyn FnMut(&mut World, Entity, Entity) -> Result<CollisionEventType> + Send + Sync;
|
||||||
|
|
||||||
// HitBox is basically a cylinder
|
// HitBox is basically a cylinder
|
||||||
pub struct HitBox {
|
pub struct HitBox {
|
||||||
|
@ -88,10 +88,7 @@ impl HitBox {
|
||||||
|
|
||||||
pub fn set_event<F>(&mut self, f: F)
|
pub fn set_event<F>(&mut self, f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&mut SceneContents<'_>, Entity, Entity) -> Result<CollisionEventType>
|
F: FnMut(&mut World, Entity, Entity) -> Result<CollisionEventType> + Send + Sync + 'static,
|
||||||
+ Send
|
|
||||||
+ Sync
|
|
||||||
+ 'static,
|
|
||||||
{
|
{
|
||||||
self.hit_event = Some(Box::new(f));
|
self.hit_event = Some(Box::new(f));
|
||||||
}
|
}
|
||||||
|
@ -126,12 +123,12 @@ impl HitBox {
|
||||||
|
|
||||||
pub fn collision(
|
pub fn collision(
|
||||||
&mut self,
|
&mut self,
|
||||||
scene: &mut SceneContents<'_>,
|
world: &mut World,
|
||||||
me: Entity,
|
me: Entity,
|
||||||
collider: Entity,
|
collider: Entity,
|
||||||
) -> Result<CollisionEventType> {
|
) -> Result<CollisionEventType> {
|
||||||
match &mut self.hit_event {
|
match &mut self.hit_event {
|
||||||
Some(hit_event) => hit_event(scene, me, collider),
|
Some(hit_event) => hit_event(world, me, collider),
|
||||||
None => Ok(CollisionEventType::Ignore),
|
None => Ok(CollisionEventType::Ignore),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,7 @@ use engine::prelude::*;
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut world_builder = World::builder();
|
let mut world_builder = World::builder();
|
||||||
|
|
||||||
let (context, engine, scene) = Engine::new(EngineCreateInfo {
|
Engine::new(EngineCreateInfo::default(), &mut world_builder)?;
|
||||||
app_info: todo!(),
|
|
||||||
window_info: todo!(),
|
|
||||||
os_specific_config: todo!(),
|
|
||||||
vulkan_debug_info: todo!(),
|
|
||||||
volume_info: todo!(),
|
|
||||||
gui_info: todo!(),
|
|
||||||
enable_backtrace: todo!(),
|
|
||||||
enable_mouse: todo!(),
|
|
||||||
enable_keyboard: todo!(),
|
|
||||||
enable_controller: todo!(),
|
|
||||||
controller_deadzones: todo!(),
|
|
||||||
resource_base_path: todo!(),
|
|
||||||
controller_directories: todo!(),
|
|
||||||
asset_directories: todo!(),
|
|
||||||
graphics_info: todo!(),
|
|
||||||
raytracing_info: todo!(),
|
|
||||||
rasterizer_info: todo!(),
|
|
||||||
key_backgrounds: todo!(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
world_builder.resources.insert(context);
|
|
||||||
world_builder.resources.insert(engine);
|
|
||||||
world_builder.resources.insert(scene);
|
|
||||||
|
|
||||||
world_builder.build().run()
|
world_builder.build().run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
use sdl2;
|
use sdl2;
|
||||||
use sdl2::controller::Button;
|
|
||||||
use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent};
|
|
||||||
use sdl2::keyboard::Keycode;
|
|
||||||
use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection};
|
|
||||||
use sdl2::EventPump;
|
use sdl2::EventPump;
|
||||||
use sdl2::EventSubsystem;
|
use sdl2::EventSubsystem;
|
||||||
use sdl2::GameControllerSubsystem;
|
use sdl2::GameControllerSubsystem;
|
||||||
use sdl2::Sdl;
|
use sdl2::Sdl;
|
||||||
|
use sdl2::controller::Button;
|
||||||
|
use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent};
|
||||||
|
use sdl2::keyboard::Keycode;
|
||||||
|
use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection};
|
||||||
|
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::sync::{Arc, RwLock};
|
||||||
use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard};
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
|
@ -76,37 +75,33 @@ pub enum Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventSystem {
|
pub struct EventSystem {
|
||||||
event_pump: RwLock<EventPump>,
|
event_pump: EventPump,
|
||||||
mouse: Mutex<MouseUtil>,
|
mouse: MouseUtil,
|
||||||
controller_subsystem: Mutex<GameControllerSubsystem>,
|
controller_subsystem: GameControllerSubsystem,
|
||||||
event_subsystem: Mutex<EventSubsystem>,
|
event_subsystem: EventSubsystem,
|
||||||
|
|
||||||
controller_deadzones: RwLock<ControllerDeadzones>,
|
controller_deadzones: ControllerDeadzones,
|
||||||
|
|
||||||
selected_controller: RwLock<Option<Arc<RwLock<Controller>>>>,
|
selected_controller: Option<Arc<RwLock<Controller>>>,
|
||||||
connected_controllers: RwLock<Vec<Arc<RwLock<Controller>>>>,
|
connected_controllers: Vec<Arc<RwLock<Controller>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventSystem {
|
impl EventSystem {
|
||||||
pub fn new(sdl2_context: &Sdl) -> Result<EventSystem> {
|
pub fn new(sdl2_context: &Sdl) -> Result<EventSystem> {
|
||||||
let event_system = EventSystem {
|
let mut event_system = EventSystem {
|
||||||
event_pump: RwLock::new(
|
event_pump: sdl2_context
|
||||||
sdl2_context
|
|
||||||
.event_pump()
|
.event_pump()
|
||||||
.map_err(|s| anyhow::Error::msg(s))?,
|
.map_err(|s| anyhow::Error::msg(s))?,
|
||||||
),
|
mouse: sdl2_context.mouse(),
|
||||||
mouse: Mutex::new(sdl2_context.mouse()),
|
controller_subsystem: sdl2_context
|
||||||
controller_subsystem: Mutex::new(
|
|
||||||
sdl2_context
|
|
||||||
.game_controller()
|
.game_controller()
|
||||||
.map_err(|s| anyhow::Error::msg(s))?,
|
.map_err(|s| anyhow::Error::msg(s))?,
|
||||||
),
|
event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?,
|
||||||
event_subsystem: Mutex::new(sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?),
|
|
||||||
|
|
||||||
controller_deadzones: RwLock::new(ControllerDeadzones::default()),
|
controller_deadzones: ControllerDeadzones::default(),
|
||||||
|
|
||||||
selected_controller: RwLock::new(None),
|
selected_controller: None,
|
||||||
connected_controllers: RwLock::new(Vec::new()),
|
connected_controllers: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
event_system.disable_mouse();
|
event_system.disable_mouse();
|
||||||
|
@ -116,102 +111,81 @@ impl EventSystem {
|
||||||
Ok(event_system)
|
Ok(event_system)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_mouse(&self) {
|
pub fn enable_mouse(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump.enable_event(SdlEventType::MouseMotion);
|
||||||
|
self.event_pump.enable_event(SdlEventType::MouseButtonDown);
|
||||||
|
self.event_pump.enable_event(SdlEventType::MouseButtonUp);
|
||||||
|
|
||||||
event_pump.enable_event(SdlEventType::MouseMotion);
|
self.mouse.show_cursor(true);
|
||||||
event_pump.enable_event(SdlEventType::MouseButtonDown);
|
|
||||||
event_pump.enable_event(SdlEventType::MouseButtonUp);
|
|
||||||
|
|
||||||
self.mouse.lock().unwrap().show_cursor(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_mouse(&self) {
|
pub fn disable_mouse(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump.disable_event(SdlEventType::MouseMotion);
|
||||||
|
self.event_pump.disable_event(SdlEventType::MouseButtonDown);
|
||||||
|
self.event_pump.disable_event(SdlEventType::MouseButtonUp);
|
||||||
|
|
||||||
event_pump.disable_event(SdlEventType::MouseMotion);
|
self.mouse.show_cursor(false);
|
||||||
event_pump.disable_event(SdlEventType::MouseButtonDown);
|
|
||||||
event_pump.disable_event(SdlEventType::MouseButtonUp);
|
|
||||||
|
|
||||||
self.mouse.lock().unwrap().show_cursor(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_keyboard(&self) {
|
pub fn enable_keyboard(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump.enable_event(SdlEventType::KeyUp);
|
||||||
|
self.event_pump.enable_event(SdlEventType::KeyDown);
|
||||||
event_pump.enable_event(SdlEventType::KeyUp);
|
|
||||||
event_pump.enable_event(SdlEventType::KeyDown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_keyboard(&self) {
|
pub fn disable_keyboard(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump.disable_event(SdlEventType::KeyUp);
|
||||||
|
self.event_pump.disable_event(SdlEventType::KeyDown);
|
||||||
event_pump.disable_event(SdlEventType::KeyUp);
|
|
||||||
event_pump.disable_event(SdlEventType::KeyDown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_controller(&self) {
|
pub fn enable_controller(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump
|
||||||
|
.enable_event(SdlEventType::ControllerAxisMotion);
|
||||||
event_pump.enable_event(SdlEventType::ControllerAxisMotion);
|
self.event_pump
|
||||||
event_pump.enable_event(SdlEventType::ControllerButtonDown);
|
.enable_event(SdlEventType::ControllerButtonDown);
|
||||||
event_pump.enable_event(SdlEventType::ControllerButtonUp);
|
self.event_pump
|
||||||
|
.enable_event(SdlEventType::ControllerButtonUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_controller(&self) {
|
pub fn disable_controller(&mut self) {
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
self.event_pump
|
||||||
|
.disable_event(SdlEventType::ControllerAxisMotion);
|
||||||
event_pump.disable_event(SdlEventType::ControllerAxisMotion);
|
self.event_pump
|
||||||
event_pump.disable_event(SdlEventType::ControllerButtonDown);
|
.disable_event(SdlEventType::ControllerButtonDown);
|
||||||
event_pump.disable_event(SdlEventType::ControllerButtonUp);
|
self.event_pump
|
||||||
|
.disable_event(SdlEventType::ControllerButtonUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_controller_axis_enable_deadzone(&self, deadzone: f32) {
|
pub fn set_controller_axis_enable_deadzone(&mut self, deadzone: f32) {
|
||||||
self.controller_deadzones
|
self.controller_deadzones.axis_enable_deadzone = deadzone;
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.axis_enable_deadzone = deadzone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_controller_axis_disable_deadzone(&self, deadzone: f32) {
|
pub fn set_controller_axis_disable_deadzone(&mut self, deadzone: f32) {
|
||||||
self.controller_deadzones
|
self.controller_deadzones.axis_disable_deadzone = deadzone;
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.axis_disable_deadzone = deadzone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_controller_trigger_enable_deadzone(&self, deadzone: f32) {
|
pub fn set_controller_trigger_enable_deadzone(&mut self, deadzone: f32) {
|
||||||
self.controller_deadzones
|
self.controller_deadzones.trigger_enable_deadzone = deadzone;
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.trigger_enable_deadzone = deadzone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_controller_trigger_disable_deadzone(&self, deadzone: f32) {
|
pub fn set_controller_trigger_disable_deadzone(&mut self, deadzone: f32) {
|
||||||
self.controller_deadzones
|
self.controller_deadzones.trigger_disable_deadzone = deadzone;
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.trigger_disable_deadzone = deadzone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn quit(&self) -> Result<()> {
|
pub fn quit(&self) -> Result<()> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.event_subsystem
|
.event_subsystem
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push_event(SdlEvent::Quit { timestamp: 0 })
|
.push_event(SdlEvent::Quit { timestamp: 0 })
|
||||||
.map_err(|s| anyhow::Error::msg(s))?)
|
.map_err(|s| anyhow::Error::msg(s))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F, R>(&self, 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: Fn(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;
|
||||||
let mut event_pump = self.event_pump.write().unwrap();
|
|
||||||
|
|
||||||
for event in event_pump.poll_iter() {
|
for event in self.event_pump.poll_iter() {
|
||||||
match event {
|
match event {
|
||||||
SdlEvent::Window { win_event, .. } => match win_event {
|
SdlEvent::Window { win_event, .. } => match win_event {
|
||||||
WindowEvent::Resized(w, h) | WindowEvent::SizeChanged(w, h) => {
|
WindowEvent::Resized(w, h) | WindowEvent::SizeChanged(w, h) => {
|
||||||
|
@ -288,9 +262,9 @@ impl EventSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(controller) = Controller::new(
|
if let Ok(controller) = Controller::new(
|
||||||
self.controller_subsystem.lock().unwrap().deref(),
|
&self.controller_subsystem,
|
||||||
which as u32,
|
which as u32,
|
||||||
self.controller_deadzones.read().unwrap().clone(),
|
self.controller_deadzones.clone(),
|
||||||
) {
|
) {
|
||||||
let controller = {
|
let controller = {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
|
@ -301,16 +275,10 @@ impl EventSystem {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut connected_controllers =
|
|
||||||
self.connected_controllers.write().unwrap();
|
|
||||||
|
|
||||||
let mut selected_controller = self.selected_controller.write().unwrap();
|
|
||||||
|
|
||||||
let arc_controller = Arc::new(RwLock::new(controller));
|
let arc_controller = Arc::new(RwLock::new(controller));
|
||||||
|
self.connected_controllers.push(arc_controller.clone());
|
||||||
|
|
||||||
connected_controllers.push(arc_controller.clone());
|
if self.selected_controller.is_none() {
|
||||||
|
|
||||||
if selected_controller.is_none() {
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
let contr = arc_controller.read().unwrap();
|
let contr = arc_controller.read().unwrap();
|
||||||
|
|
||||||
|
@ -321,7 +289,7 @@ impl EventSystem {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
*selected_controller = Some(arc_controller.clone());
|
self.selected_controller = Some(arc_controller.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
arc_controller
|
arc_controller
|
||||||
|
@ -332,11 +300,10 @@ impl EventSystem {
|
||||||
}
|
}
|
||||||
SdlEvent::ControllerDeviceRemoved { which, .. } => {
|
SdlEvent::ControllerDeviceRemoved { which, .. } => {
|
||||||
let removed_controller = {
|
let removed_controller = {
|
||||||
let mut selected_controller = self.selected_controller.write().unwrap();
|
if self.selected_controller.is_some() {
|
||||||
|
|
||||||
if selected_controller.is_some() {
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
let contr = selected_controller.as_ref().unwrap().read().unwrap();
|
let contr =
|
||||||
|
self.selected_controller.as_ref().unwrap().read().unwrap();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Remove active controller: {}({})",
|
"Remove active controller: {}({})",
|
||||||
|
@ -346,14 +313,20 @@ impl EventSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
// unwrap is save since we just tested for `is_some()`
|
// unwrap is save since we just tested for `is_some()`
|
||||||
if selected_controller.as_ref().unwrap().read().unwrap().id() == which {
|
if self
|
||||||
*selected_controller = None;
|
.selected_controller
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.id()
|
||||||
|
== which
|
||||||
|
{
|
||||||
|
self.selected_controller = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut connected_controllers = self.connected_controllers.write().unwrap();
|
self.connected_controllers
|
||||||
|
|
||||||
connected_controllers
|
|
||||||
.iter()
|
.iter()
|
||||||
.position(|controller_cell| {
|
.position(|controller_cell| {
|
||||||
let controller = controller_cell.read().unwrap();
|
let controller = controller_cell.read().unwrap();
|
||||||
|
@ -361,7 +334,7 @@ impl EventSystem {
|
||||||
})
|
})
|
||||||
.map(|remove_index| {
|
.map(|remove_index| {
|
||||||
let removed_controller =
|
let removed_controller =
|
||||||
connected_controllers.swap_remove(remove_index);
|
self.connected_controllers.swap_remove(remove_index);
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
let contr = removed_controller.read().unwrap();
|
let contr = removed_controller.read().unwrap();
|
||||||
|
@ -373,17 +346,18 @@ impl EventSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we removed the selected controller, take the controller at the first position if possible
|
// if we removed the selected controller, take the controller at the first position if possible
|
||||||
if selected_controller.is_none()
|
if self.selected_controller.is_none()
|
||||||
&& !connected_controllers.is_empty()
|
&& !self.connected_controllers.is_empty()
|
||||||
{
|
{
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
println!(
|
println!(
|
||||||
"Set active controller: {}",
|
"Set active controller: {}",
|
||||||
connected_controllers[0].read().unwrap().name()
|
self.connected_controllers[0].read().unwrap().name()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
*selected_controller = Some(connected_controllers[0].clone());
|
self.selected_controller =
|
||||||
|
Some(self.connected_controllers[0].clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
removed_controller
|
removed_controller
|
||||||
|
@ -436,9 +410,7 @@ impl EventSystem {
|
||||||
// which,
|
// which,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let mut selected_controller = self.selected_controller.write().unwrap();
|
if let Some(controller) = self.selected_controller.as_mut() {
|
||||||
|
|
||||||
if let Some(controller) = selected_controller.as_mut() {
|
|
||||||
let mut controller = controller.write().unwrap();
|
let mut controller = controller.write().unwrap();
|
||||||
|
|
||||||
// // only update axis, when selected controller made the change
|
// // only update axis, when selected controller made the change
|
||||||
|
@ -481,7 +453,7 @@ impl EventSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller_axis_changed {
|
if controller_axis_changed {
|
||||||
if let Some(controller) = self.selected_controller.read().unwrap().as_ref() {
|
if let Some(controller) = &self.selected_controller {
|
||||||
let (left_trigger, right_trigger) = {
|
let (left_trigger, right_trigger) = {
|
||||||
let mut controller_lock = controller.write().unwrap();
|
let mut controller_lock = controller.write().unwrap();
|
||||||
|
|
||||||
|
@ -516,23 +488,21 @@ impl EventSystem {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn controllers(&self) -> RwLockReadGuard<'_, Vec<Arc<RwLock<Controller>>>> {
|
pub fn controllers(&self) -> &[Arc<RwLock<Controller>>] {
|
||||||
self.connected_controllers.read().unwrap()
|
&self.connected_controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_controller(&self) -> Result<Option<Arc<RwLock<Controller>>>> {
|
pub fn active_controller(&self) -> &Option<Arc<RwLock<Controller>>> {
|
||||||
Ok(self.selected_controller.read().unwrap().clone())
|
&self.selected_controller
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_active_controller(&self, controller: &Arc<RwLock<Controller>>) {
|
pub fn set_active_controller(&mut self, controller: &Arc<RwLock<Controller>>) {
|
||||||
if let Some(res) = self
|
if let Some(res) = self
|
||||||
.connected_controllers
|
.connected_controllers
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|c| Arc::ptr_eq(c, controller))
|
.find(|c| Arc::ptr_eq(c, controller))
|
||||||
{
|
{
|
||||||
*self.selected_controller.write().unwrap() = Some(res.clone());
|
self.selected_controller = Some(res.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ impl PresentationCore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F, R>(&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: Fn(Event) -> Result<()>,
|
F: Fn(Event) -> Result<()>,
|
||||||
R: FnMut(u32, u32) -> Result<()>,
|
R: FnMut(u32, u32) -> Result<()>,
|
||||||
|
@ -123,6 +123,10 @@ impl PresentationCore {
|
||||||
&self.event_system
|
&self.event_system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn event_system_mut(&mut self) -> &mut EventSystem {
|
||||||
|
&mut self.event_system
|
||||||
|
}
|
||||||
|
|
||||||
pub fn activate_vulkan_instance_extensions(
|
pub fn activate_vulkan_instance_extensions(
|
||||||
&self,
|
&self,
|
||||||
extensions: &mut InstanceExtensions,
|
extensions: &mut InstanceExtensions,
|
||||||
|
|
|
@ -171,10 +171,11 @@ impl<S: TScene + 'static> RenderBackend<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a call to the connected scene
|
// make a call to the connected scene
|
||||||
world.resources.get_mut::<S>().process(
|
world.resources.get_mut_unchecked::<S>().process(
|
||||||
&mut buffer_recorder,
|
&mut buffer_recorder,
|
||||||
&*self.swapchain_images.lock().unwrap(),
|
&*self.swapchain_images.lock().unwrap(),
|
||||||
&image_indices,
|
&image_indices,
|
||||||
|
world,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// post processing
|
// post processing
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub trait TScene: Send + Sync {
|
||||||
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,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
fn resize(
|
fn resize(
|
||||||
|
|
Loading…
Reference in a new issue