diff --git a/Cargo.lock b/Cargo.lock index ad567ad4..d1fcf63b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,6 +39,28 @@ dependencies = [ "memchr", ] +[[package]] +name = "alsa" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2562ad8dcf0f789f65c6fdaad8a8a9708ed6b488e649da28c01656ad66b8b47" +dependencies = [ + "alsa-sys", + "bitflags 1.3.2", + "libc", + "nix", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "ash" version = "0.37.0+1.3.269" @@ -86,6 +108,26 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +[[package]] +name = "bindgen" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +dependencies = [ + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.38", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -145,6 +187,7 @@ dependencies = [ "bitflags 2.4.1", "colored", "component_derive", + "cpal", "downcast-rs", "dual_quaternion", "futures", @@ -180,21 +223,54 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "cmake" version = "0.1.50" @@ -221,6 +297,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "component_derive" version = "0.1.0" @@ -229,6 +315,57 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "coreaudio-rs" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" +dependencies = [ + "bitflags 1.3.2", + "core-foundation-sys", + "coreaudio-sys", +] + +[[package]] +name = "coreaudio-sys" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3120ebb80a9de008e638ad833d4127d50ea3d3a960ea23ea69bc66d9358a028" +dependencies = [ + "bindgen", +] + +[[package]] +name = "cpal" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d959d90e938c5493000514b446987c07aed46c668faaa7d34d6c7a67b1a578c" +dependencies = [ + "alsa", + "core-foundation-sys", + "coreaudio-rs", + "dasp_sample", + "jni 0.19.0", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "oboe", + "once_cell", + "parking_lot", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -263,6 +400,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "deranged" version = "0.3.9" @@ -516,6 +659,12 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gltf" version = "1.3.0" @@ -718,6 +867,49 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + [[package]] name = "jpeg-decoder" version = "0.3.0" @@ -765,6 +957,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.149" @@ -850,6 +1048,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "mach2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +dependencies = [ + "libc", +] + [[package]] name = "maths-rs" version = "0.2.5" @@ -882,6 +1089,12 @@ dependencies = [ "float-cmp 0.5.3", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -904,6 +1117,56 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "notify" version = "6.1.1" @@ -936,6 +1199,17 @@ dependencies = [ "walkdir", ] +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -976,13 +1250,34 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + [[package]] name = "num_enum" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1015,6 +1310,29 @@ dependencies = [ "memchr", ] +[[package]] +name = "oboe" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" +dependencies = [ + "jni 0.20.0", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "oboe-sys", +] + +[[package]] +name = "oboe-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f44155e7fb718d3cfddcf70690b2b51ac4412f347cd9e4fbe511abe9cd7b5f2" +dependencies = [ + "cc", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1041,9 +1359,15 @@ dependencies = [ "libc", "redox_syscall 0.4.1", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.3.0" @@ -1068,6 +1392,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad78bf43dcf80e8f950c92b84f938a0fc7590b7f6866fbcbeca781609c115590" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "png" version = "0.17.10" @@ -1097,7 +1427,7 @@ dependencies = [ "libc", "lz4_flex", "memmap2", - "num_enum", + "num_enum 0.6.1", "regex", "serde", "serde-wasm-bindgen", @@ -1204,6 +1534,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1301,6 +1637,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.21" @@ -1440,6 +1782,12 @@ dependencies = [ "roxmltree", ] +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1849,6 +2197,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -1870,7 +2227,22 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9f4b3446..9d08bdbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ meshopt = "0.1.9" colored = "2.0.4" downcast-rs = "1.2.0" intertrait = "0.2.2" +cpal = "0.15.2" [profile.dev] incremental = true diff --git a/src/audio/audio_system.rs b/src/audio/audio_system.rs new file mode 100644 index 00000000..04293e76 --- /dev/null +++ b/src/audio/audio_system.rs @@ -0,0 +1,36 @@ +use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; + +struct AudioSystem { + host: cpal::Host, + stream: Option, +} + +impl AudioSystem { + fn new() -> Self { + let host = cpal::default_host(); + + let device = if let Some(e) = host.default_output_device() { + e + } else { + log::error!("No audio output device found.\n Audio playback will be disabled."); + + return AudioSystem { + host, + stream: None, + }; + }; + + let mut format = device.default_output_config().unwrap(); + + let stream = device.build_output_stream(&format.config(), move |_: &mut [u16], _| {}, move |_| {}, None).unwrap(); + + if let Err(error) = stream.play() { + log::error!("Failed to start audio stream: {}\n Audio playback will be disabled.", error); + } + + AudioSystem { + host, + stream: Some(stream), + } + } +} \ No newline at end of file diff --git a/src/audio/mod.rs b/src/audio/mod.rs new file mode 100644 index 00000000..7bbaa9db --- /dev/null +++ b/src/audio/mod.rs @@ -0,0 +1 @@ +pub mod audio_system; \ No newline at end of file diff --git a/src/input_manager.rs b/src/input_manager.rs index 459c7174..e4be313e 100644 --- a/src/input_manager.rs +++ b/src/input_manager.rs @@ -17,11 +17,11 @@ //! - [ ] Remove panics. //! - [ ] Add device class and device grouping. -use std::f32::consts::PI; +use std::{f32::consts::PI, collections::HashMap}; use log::warn; -use crate::{RGBA, Vector2, Vector3, insert_return_length, Quaternion, orchestrator::{EntityHandle, Property, System, self, Entity, EntitySubscriber}}; +use crate::{RGBA, Vector2, Vector3, insert_return_length, Quaternion, orchestrator::{EntityHandle, Property, System, self, Entity, EntitySubscriber, EntityHash}}; /// A device class represents a type of device. Such as a keyboard, mouse, or gamepad. /// It can have associated input sources, such as the UP key on a keyboard or the left trigger on a gamepad. @@ -257,6 +257,10 @@ pub struct InputManager { devices: Vec, records: Vec, actions: Vec, + + input_sources_map: HashMap, + actions_ei_map: HashMap, + actions_ie_map: HashMap>>, } impl InputManager { @@ -268,6 +272,10 @@ impl InputManager { devices: Vec::new(), records: Vec::new(), actions: Vec::new(), + + input_sources_map: HashMap::new(), + actions_ei_map: HashMap::new(), + actions_ie_map: HashMap::new(), } } @@ -591,7 +599,7 @@ impl InputManager { // orchestrator.set_owned_property(orchestrator::InternalId(i as u32), Action::::value, v); } Value::Vector3(v) => { - // orchestrator.set_owned_property(orchestrator::InternalId(i as u32), Action::::value, v); + orchestrator.set_property(self.actions_ie_map.get(&ActionHandle(i as u32)).unwrap(), Action::::value, v); } _ => {} } @@ -788,7 +796,10 @@ impl InputManager { impl EntitySubscriber> for InputManager { fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, action: &Action) { - self.create_action(action.name, Types::Bool, &action.bindings); + let internal_handle = self.create_action(action.name, Types::Bool, &action.bindings); + } + + fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, params: &Action) { } } @@ -796,11 +807,19 @@ impl EntitySubscriber> for InputManager { fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, action: &Action>) { self.create_action(action.name, Types::Vector2, &action.bindings); } + + fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, params: &Action) { + } } impl EntitySubscriber> for InputManager { fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, action: &Action>) { - self.create_action(action.name, Types::Vector3, &action.bindings); + let internal_handle = self.create_action(action.name, Types::Vector3, &action.bindings); + + self.actions_ie_map.insert(internal_handle, handle); + } + + fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle>, params: &Action) { } } @@ -1272,7 +1291,7 @@ mod tests { } } -pub trait Extract { +pub trait Extract { fn extract(&self) -> T; } @@ -1309,12 +1328,12 @@ impl InputManager { orchestrator::InternalId(handle.0) } - pub fn get_action_value(&self, action_handle: &EntityHandle>) -> T where Value: Extract { + pub fn get_action_value(&self, action_handle: &EntityHandle>) -> T where Value: Extract { let state = self.get_action_state(ActionHandle(action_handle.get_external_key()), &DeviceHandle(0)); state.value.extract() } - pub fn set_action_value(&mut self, _action_handle: &EntityHandle>, _value: T) { + pub fn set_action_value(&mut self, _action_handle: &EntityHandle>, _value: T) { } } @@ -1323,30 +1342,44 @@ impl Entity for InputManager {} impl System for InputManager {} #[derive(Clone, Debug)] -pub struct Action { +pub struct Action { pub name: &'static str, pub bindings: Vec, - pub phantom: std::marker::PhantomData, + pub value: T, } -impl orchestrator::Entity for Action {} +impl orchestrator::Entity for Action {} -pub trait GetType { +pub trait InputValue: Default + Clone + Copy + 'static { fn get_type() -> Types; } -impl GetType for bool { +impl InputValue for bool { fn get_type() -> Types { Types::Bool } } -impl GetType for Vector2 { +impl InputValue for Vector2 { fn get_type() -> Types { Types::Vector2 } } -impl GetType for Vector3 { +impl InputValue for Vector3 { fn get_type() -> Types { Types::Vector3 } } -impl orchestrator::Component for Action { +impl orchestrator::Component for Action { // type Parameters<'a> = ActionParameters<'a>; +} + +impl Action { + pub fn new(name: &'static str, bindings: &[ActionBindingDescription]) -> Action { + Action { + name, + bindings: bindings.to_vec(), + value: T::default(), + } + } + + pub fn get_value(&self) -> T { self.value } + pub fn set_value(&mut self, _: orchestrator::OrchestratorReference, value: T) { self.value = value; } + pub const fn value() -> orchestrator::Property, T> { return orchestrator::Property { getter: Self::get_value, setter: Self::set_value } } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a19e98d7..bc06556f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ #![feature(iter_map_windows)] #![feature(pointer_is_aligned)] #![feature(coerce_unsized, unsize)] +#![feature(fn_ptr_trait)] // #![warn(missing_docs)] # Disable now because we are writing a lot of code // #![warn(missing_doc_code_examples)] # Disable now because we are writing a lot of code @@ -20,6 +21,7 @@ pub mod input_manager; pub mod file_tracker; pub mod executor; pub mod camera; +pub mod audio; pub mod math; pub mod rendering; diff --git a/src/orchestrator.rs b/src/orchestrator.rs index 508f9442..41314a7d 100644 --- a/src/orchestrator.rs +++ b/src/orchestrator.rs @@ -33,6 +33,14 @@ pub struct EntityHandle { external_id: u32, } +pub type EntityHash = u32; + +impl From> for EntityHash { + fn from(handle: EntityHandle) -> Self { + handle.internal_id + } +} + impl EntityHandle { pub fn new(object: std::rc::Rc>, internal_id: u32, external_id: u32) -> Self { Self { @@ -82,8 +90,8 @@ impl Clone for EntityHandle { } } -use std::marker::Unsize; -use std::ops::CoerceUnsized; +use std::marker::{Unsize, FnPtr}; +use std::ops::{CoerceUnsized, DerefMut, Deref}; impl CoerceUnsized> for EntityHandle where T: Unsize + ?Sized, @@ -117,7 +125,7 @@ pub trait OwnedComponent : Entity { } struct Tie { - update_function: std::boxed::Box, + update_function: std::boxed::Box, OrchestratorReference, &dyn Any)>, destination_system_handle: u32, } @@ -324,41 +332,43 @@ impl Orchestrator { } /// Ties a property of a component to a property of another component. - pub fn tie(&self, receiver_component_handle: &EntityHandle, i: fn() -> Property, _sender_component_handle: &EntityHandle, j: fn() -> Property) { + pub fn tie(&self, receiver_component_handle: &EntityHandle, i: fn() -> Property, _sender_component_handle: &EntityHandle, j: fn() -> Property) { + self.tie_internal(receiver_component_handle.internal_id, i, _sender_component_handle, j) + } + + /// Ties a property of a component to a property of another component. + pub fn tie_internal(&self, receiver_internal_id: u32, i: fn() -> Property, _sender_component_handle: &EntityHandle, j: fn() -> Property) { let property_function_pointer = j as *const (); // Use the property function pointer as a key to the ties hashmap. let property = i(); let mut ties = self.ties.write().unwrap(); - let update_function = Box::new(property.setter); + let update_function = Box::new(move |systems: &HashMap, orchestrator_reference: OrchestratorReference, value: &dyn Any| { + (property.setter)(systems[&receiver_internal_id].write().unwrap().downcast_mut::().unwrap(), orchestrator_reference, *value.downcast_ref().unwrap()) + }); if let std::collections::hash_map::Entry::Vacant(e) = ties.entry(property_function_pointer as usize) { let mut ties_new = Vec::new(); - ties_new.push(Tie { update_function, destination_system_handle: receiver_component_handle.internal_id }); + ties_new.push(Tie { update_function, destination_system_handle: receiver_internal_id }); e.insert(ties_new); } else { let ties = ties.get_mut(&(property_function_pointer as usize)).unwrap(); - if !ties.iter().any(|tie| tie.destination_system_handle == receiver_component_handle.internal_id) { - ties.push(Tie { update_function, destination_system_handle: receiver_component_handle.internal_id }); + if !ties.iter().any(|tie| tie.destination_system_handle == receiver_internal_id) { + ties.push(Tie { update_function, destination_system_handle: receiver_internal_id }); } } } pub fn set_property(&self, component_handle: &EntityHandle, function: fn() -> Property, value: V) { - let po = function as *const (); let ties = self.ties.read().unwrap(); - if let Some(ties) = ties.get(&(po as usize)) { + if let Some(ties) = ties.get(&(function.addr() as usize)) { let systems_data = self.systems_data.read().unwrap(); for tie in ties { - unsafe { - let mut component = systems_data.systems[&tie.destination_system_handle].write().unwrap(); - let setter = tie.update_function.downcast_ref_unchecked::(); - (setter)(component.downcast_mut::().unwrap(), OrchestratorReference { orchestrator: self, internal_id: tie.destination_system_handle }, value); - } + (tie.update_function)(&systems_data.systems, OrchestratorReference { orchestrator: self, internal_id: tie.destination_system_handle }, &value); } } } @@ -526,6 +536,7 @@ impl <'a, F, P0, P1, P2> TaskFunction<'a, (P0, P1, P2)> for F where pub trait EntitySubscriber { fn on_create(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &T); + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &T); } #[cfg(test)] @@ -614,6 +625,8 @@ mod tests { COUNTER += 1; } } + + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &Component) {} } let _: Option> = orchestrator.spawn_entity(System::new()); @@ -816,13 +829,13 @@ pub struct OrchestratorReference<'a> { } impl <'a> OrchestratorReference<'a> { - pub fn tie<'b, T: Entity + 'static, U: Entity + 'b, V: 'static>(&self, receiver_component_handle: &EntityHandle, i: fn() -> Property, sender_component_handle: &EntityHandle, j: fn() -> Property) { + pub fn tie<'b, T: Entity + 'static, U: Entity + 'b, V: Any + Copy + 'static>(&self, receiver_component_handle: &EntityHandle, i: fn() -> Property, sender_component_handle: &EntityHandle, j: fn() -> Property) { self.orchestrator.tie(receiver_component_handle, i, sender_component_handle, j); } - // pub fn tie_self(&self, consuming_property: fn() -> Property, sender_component_handle: &EntityHandle, j: fn() -> Property) { - // self.orchestrator.tie(&EntityHandle::::new(object, internal_id, external_id){ internal_id: self.internal_id, external_id: 0, phantom: std::marker::PhantomData }, consuming_property, sender_component_handle, j); - // } + pub fn tie_self(&self, consuming_property: fn() -> Property, sender_component_handle: &EntityHandle, j: fn() -> Property) { + self.orchestrator.tie_internal(self.internal_id, consuming_property, sender_component_handle, j); + } pub fn spawn_entity<'c, T, P, F: 'c>(&self, function: F) -> Option> where T: Entity + 'static, F: IntoHandler { self.orchestrator.spawn_entity::<'c, T, P, F>(function) diff --git a/src/rendering/renderer.rs b/src/rendering/renderer.rs index 78193dfd..d9ac11ee 100644 --- a/src/rendering/renderer.rs +++ b/src/rendering/renderer.rs @@ -71,7 +71,7 @@ impl Renderer { if self.swapchain_handles.is_empty() { return; } let render_system = orchestrator.get_entity(&self.render_system); - let mut render_system = render_system.get_mut(); + let render_system = render_system.get(); let swapchain_handle = self.swapchain_handles[0]; @@ -89,7 +89,7 @@ impl Renderer { visibility_render_model.render(&orchestrator, render_system.deref(), command_buffer_recording.as_mut()); let tonemap_render_model = orchestrator.get_entity(&self.tonemap_render_model); - let mut tonemap_render_model = tonemap_render_model.get_mut(); + let tonemap_render_model = tonemap_render_model.get(); tonemap_render_model.render(command_buffer_recording.as_mut()); @@ -119,6 +119,10 @@ impl orchestrator::EntitySubscriber for Renderer { self.swapchain_handles.push(swapchain_handle); } + + fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle, params: &window_system::Window) { + + } } impl orchestrator::Entity for Renderer {} \ No newline at end of file diff --git a/src/rendering/visibility_model/render_domain.rs b/src/rendering/visibility_model/render_domain.rs index f8de0352..fbfe3db8 100644 --- a/src/rendering/visibility_model/render_domain.rs +++ b/src/rendering/visibility_model/render_domain.rs @@ -860,6 +860,10 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDom fn on_create(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, camera: &camera::Camera) { self.camera = Some(handle); } + + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &camera::Camera) { + + } } #[derive(Copy, Clone)] @@ -1084,6 +1088,10 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain assert!((self.visibility_info.vertex_count as usize) < MAX_PRIMITIVE_TRIANGLES, "Primitive triangle count exceeded"); assert!((self.visibility_info.triangle_count as usize) < MAX_TRIANGLES, "Triangle count exceeded"); } + + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &mesh::Mesh) { + + } } impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { @@ -1102,6 +1110,10 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderD assert!(lighting_data.count < MAX_LIGHTS as u32, "Light count exceeded"); } + + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &DirectionalLight) { + + } } impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { @@ -1120,6 +1132,10 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain assert!(lighting_data.count < MAX_LIGHTS as u32, "Light count exceeded"); } + + fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle, params: &PointLight) { + + } } impl Entity for VisibilityWorldRenderDomain {} diff --git a/src/rendering/vulkan_render_system.rs b/src/rendering/vulkan_render_system.rs index db2cc233..3199bd4e 100644 --- a/src/rendering/vulkan_render_system.rs +++ b/src/rendering/vulkan_render_system.rs @@ -3524,10 +3524,7 @@ impl render_system::CommandBufferRecording for VulkanCommandBufferRecording<'_> .image_memory_barriers(&image_memory_barriers) .buffer_memory_barriers(&buffer_memory_barriers) .memory_barriers(&memory_barriers) - .dependency_flags(vk::DependencyFlags::BY_REGION) - /* .build() */; - - dbg!(dependency_info); + .dependency_flags(vk::DependencyFlags::BY_REGION); let command_buffer = self.get_command_buffer(); diff --git a/src/window_system.rs b/src/window_system.rs index 219c375a..fab8cb57 100644 --- a/src/window_system.rs +++ b/src/window_system.rs @@ -708,6 +708,10 @@ impl EntitySubscriber for WindowSystem { fn on_create(&mut self, _orchestrator: orchestrator::OrchestratorReference, _handle: orchestrator::EntityHandle, _window: &Window) { self.create_window("Main Window", Extent { width: 1920, height: 1080, depth: 1 }, "main_window"); } + + fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: orchestrator::EntityHandle, params: &Window) { + + } } #[cfg(test)] diff --git a/tests/gallery_shooter.rs b/tests/gallery_shooter.rs index b0dad55a..ed5a46d3 100644 --- a/tests/gallery_shooter.rs +++ b/tests/gallery_shooter.rs @@ -11,19 +11,17 @@ fn gallery_shooter() { let orchestrator = app.get_mut_orchestrator(); - let lookaround_action_handle: EntityHandle> = orchestrator.spawn(input_manager::Action{ name: "Lookaround", bindings: vec![ + let lookaround_action_handle: EntityHandle> = orchestrator.spawn(input_manager::Action::new("Lookaround", &[ input_manager::ActionBindingDescription::new(input_manager::InputSourceAction::Name("Mouse.Position")).mapped(input_manager::Value::Vector3(Vector3::new(1f32, 1f32, 1f32)), input_manager::Function::Sphere), input_manager::ActionBindingDescription::new(input_manager::InputSourceAction::Name("Gamepad.RightStick")), - ], - phantom: std::marker::PhantomData, - }); + ],) + ); - let _trigger_action: orchestrator::EntityHandle> = orchestrator.spawn(input_manager::Action{ name: "Trigger", bindings: vec![ + let _trigger_action: orchestrator::EntityHandle> = orchestrator.spawn(input_manager::Action::new("Trigger", &[ input_manager::ActionBindingDescription::new(input_manager::InputSourceAction::Name("Mouse.LeftButton")), // input_manager::ActionBindingDescription::new(input_manager::InputSourceAction::Name("Gamepad.RightTrigger")), - ], - phantom: std::marker::PhantomData, - }); + ],) + ); let player: EntityHandle = orchestrator.spawn_entity(Player::new(lookaround_action_handle)).expect("Failed to spawn player"); @@ -69,7 +67,7 @@ impl Player { focus_distance: 0.0, }); - // orchestrator.tie(&camera_handle, byte_engine::camera::Camera::orientation, &lookaround, input_manager::Action::value); + orchestrator.tie(&camera_handle, byte_engine::camera::Camera::orientation, &lookaround, input_manager::Action::value); // orchestrator.tie_self(Player::lookaround, &handle, input_manager::Action::value);