Skip to content

Commit

Permalink
Updated ties.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Dec 18, 2023
1 parent 11fe75e commit 45764f0
Show file tree
Hide file tree
Showing 12 changed files with 531 additions and 54 deletions.
380 changes: 376 additions & 4 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions src/audio/audio_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};

struct AudioSystem {
host: cpal::Host,
stream: Option<cpal::Stream>,
}

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),
}
}
}
1 change: 1 addition & 0 deletions src/audio/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod audio_system;
65 changes: 49 additions & 16 deletions src/input_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -257,6 +257,10 @@ pub struct InputManager {
devices: Vec<Device>,
records: Vec<Record>,
actions: Vec<InputAction>,

input_sources_map: HashMap<EntityHash, InputSourceHandle>,
actions_ei_map: HashMap<EntityHash, ActionHandle>,
actions_ie_map: HashMap<ActionHandle, EntityHandle<Action<Vector3>>>,
}

impl InputManager {
Expand All @@ -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(),
}
}

Expand Down Expand Up @@ -591,7 +599,7 @@ impl InputManager {
// orchestrator.set_owned_property(orchestrator::InternalId(i as u32), Action::<Vector2>::value, v);
}
Value::Vector3(v) => {
// orchestrator.set_owned_property(orchestrator::InternalId(i as u32), Action::<Vector3>::value, v);
orchestrator.set_property(self.actions_ie_map.get(&ActionHandle(i as u32)).unwrap(), Action::<Vector3>::value, v);
}
_ => {}
}
Expand Down Expand Up @@ -788,19 +796,30 @@ impl InputManager {

impl EntitySubscriber<Action<bool>> for InputManager {
fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle<Action<bool>>, action: &Action<bool>) {
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<Action<bool>>, params: &Action<bool>) {
}
}

impl EntitySubscriber<Action<Vector2>> for InputManager {
fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle<Action<Vector2>>, action: &Action<maths_rs::vec::Vec2<f32>>) {
self.create_action(action.name, Types::Vector2, &action.bindings);
}

fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle<Action<Vector2>>, params: &Action<Vector2>) {
}
}

impl EntitySubscriber<Action<Vector3>> for InputManager {
fn on_create(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle<Action<Vector3>>, action: &Action<maths_rs::vec::Vec3<f32>>) {
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<Action<Vector3>>, params: &Action<Vector3>) {
}
}

Expand Down Expand Up @@ -1272,7 +1291,7 @@ mod tests {
}
}

pub trait Extract<T: GetType> {
pub trait Extract<T: InputValue> {
fn extract(&self) -> T;
}

Expand Down Expand Up @@ -1309,12 +1328,12 @@ impl InputManager {
orchestrator::InternalId(handle.0)
}

pub fn get_action_value<T: GetType + Clone + 'static>(&self, action_handle: &EntityHandle<Action<T>>) -> T where Value: Extract<T> {
pub fn get_action_value<T: InputValue + Clone + 'static>(&self, action_handle: &EntityHandle<Action<T>>) -> T where Value: Extract<T> {
let state = self.get_action_state(ActionHandle(action_handle.get_external_key()), &DeviceHandle(0));
state.value.extract()
}

pub fn set_action_value<T: GetType + Clone + 'static>(&mut self, _action_handle: &EntityHandle<Action<T>>, _value: T) {
pub fn set_action_value<T: InputValue + Clone + 'static>(&mut self, _action_handle: &EntityHandle<Action<T>>, _value: T) {

}
}
Expand All @@ -1323,30 +1342,44 @@ impl Entity for InputManager {}
impl System for InputManager {}

#[derive(Clone, Debug)]
pub struct Action<T: Clone> {
pub struct Action<T: InputValue> {
pub name: &'static str,
pub bindings: Vec<ActionBindingDescription>,
pub phantom: std::marker::PhantomData<T>,
pub value: T,
}

impl <T: GetType + Clone + 'static> orchestrator::Entity for Action<T> {}
impl <T: InputValue> orchestrator::Entity for Action<T> {}

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 <T: Clone + GetType + 'static> orchestrator::Component for Action<T> {
impl <T: Clone + InputValue + 'static> orchestrator::Component for Action<T> {
// type Parameters<'a> = ActionParameters<'a>;
}

impl <T: InputValue + Clone + 'static> Action<T> {
pub fn new(name: &'static str, bindings: &[ActionBindingDescription]) -> Action<T> {
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<Action<T>, T> { return orchestrator::Property { getter: Self::get_value, setter: Self::set_value } }
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;
Expand Down
51 changes: 32 additions & 19 deletions src/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ pub struct EntityHandle<T: Entity + ?Sized> {
external_id: u32,
}

pub type EntityHash = u32;

impl <T: Entity + ?Sized> From<EntityHandle<T>> for EntityHash {
fn from(handle: EntityHandle<T>) -> Self {
handle.internal_id
}
}

impl <T: Entity> EntityHandle<T> {
pub fn new(object: std::rc::Rc<std::sync::RwLock<T>>, internal_id: u32, external_id: u32) -> Self {
Self {
Expand Down Expand Up @@ -82,8 +90,8 @@ impl <T: Entity + ?Sized> Clone for EntityHandle<T> {
}
}

use std::marker::Unsize;
use std::ops::CoerceUnsized;
use std::marker::{Unsize, FnPtr};
use std::ops::{CoerceUnsized, DerefMut, Deref};
impl<T: Entity, U: Entity> CoerceUnsized<EntityHandle<U>> for EntityHandle<T>
where
T: Unsize<U> + ?Sized,
Expand Down Expand Up @@ -117,7 +125,7 @@ pub trait OwnedComponent<T: Entity> : Entity {
}

struct Tie {
update_function: std::boxed::Box<dyn std::any::Any>,
update_function: std::boxed::Box<dyn Fn(&HashMap<u32, EntityStorage>, OrchestratorReference, &dyn Any)>,
destination_system_handle: u32,
}

Expand Down Expand Up @@ -324,41 +332,43 @@ impl Orchestrator {
}

/// Ties a property of a component to a property of another component.
pub fn tie<T: Entity + 'static, U: Entity, V: 'static>(&self, receiver_component_handle: &EntityHandle<T>, i: fn() -> Property<T, V>, _sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
pub fn tie<T: Entity + 'static, U: Entity, V: Any + Copy + 'static>(&self, receiver_component_handle: &EntityHandle<T>, i: fn() -> Property<T, V>, _sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
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<T: Entity + 'static, U: Entity, V: Any + Copy + 'static>(&self, receiver_internal_id: u32, i: fn() -> Property<T, V>, _sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
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<u32, EntityStorage>, orchestrator_reference: OrchestratorReference, value: &dyn Any| {
(property.setter)(systems[&receiver_internal_id].write().unwrap().downcast_mut::<T>().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<C: Entity + 'static, V: Clone + Copy + 'static>(&self, component_handle: &EntityHandle<C>, function: fn() -> Property<C, V>, 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::<fn(&mut C, OrchestratorReference, V)>();
(setter)(component.downcast_mut::<C>().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);
}
}
}
Expand Down Expand Up @@ -526,6 +536,7 @@ impl <'a, F, P0, P1, P2> TaskFunction<'a, (P0, P1, P2)> for F where

pub trait EntitySubscriber<T: Entity + Component> {
fn on_create(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle<T>, params: &T);
fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle<T>, params: &T);
}

#[cfg(test)]
Expand Down Expand Up @@ -614,6 +625,8 @@ mod tests {
COUNTER += 1;
}
}

fn on_update(&mut self, orchestrator: OrchestratorReference, handle: EntityHandle<Component>, params: &Component) {}
}

let _: Option<EntityHandle<System>> = orchestrator.spawn_entity(System::new());
Expand Down Expand Up @@ -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<T>, i: fn() -> Property<T, V>, sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
pub fn tie<'b, T: Entity + 'static, U: Entity + 'b, V: Any + Copy + 'static>(&self, receiver_component_handle: &EntityHandle<T>, i: fn() -> Property<T, V>, sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
self.orchestrator.tie(receiver_component_handle, i, sender_component_handle, j);
}

// pub fn tie_self<T: Entity + 'static, U: Entity, V: 'static, S0: 'static, S1: 'static>(&self, consuming_property: fn() -> Property<S0, T, V>, sender_component_handle: &EntityHandle<U>, j: fn() -> Property<S1, U, V>) {
// self.orchestrator.tie(&EntityHandle::<T>::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<T: Entity + 'static, U: Entity, V: Any + Copy + 'static>(&self, consuming_property: fn() -> Property<T, V>, sender_component_handle: &EntityHandle<U>, j: fn() -> Property<U, V>) {
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<EntityHandle<T>> where T: Entity + 'static, F: IntoHandler<P, T> {
self.orchestrator.spawn_entity::<'c, T, P, F>(function)
Expand Down
8 changes: 6 additions & 2 deletions src/rendering/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand All @@ -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());

Expand Down Expand Up @@ -119,6 +119,10 @@ impl orchestrator::EntitySubscriber<window_system::Window> for Renderer {

self.swapchain_handles.push(swapchain_handle);
}

fn on_update(&mut self, orchestrator: orchestrator::OrchestratorReference, handle: EntityHandle<window_system::Window>, params: &window_system::Window) {

}
}

impl orchestrator::Entity for Renderer {}
Loading

0 comments on commit 45764f0

Please sign in to comment.