bones_framework/networking/
input.rs

1//! Input traits required by networking. These traits are networking specific, either only used in networking,
2//! or extending other traits from [`crate::input`] for networking.
3
4use std::fmt::Debug;
5
6use bones_schema::HasSchema;
7
8use crate::input::{InputCollector, PlayerControls};
9
10use super::NetworkInputStatus;
11
12/// Define input types used by game for use in networking.
13///
14/// As long as types `PlayerControls` and `InputCollector` implement traits [`PlayerControls`] and [`InputCollector`],
15/// trait bounds [`NetworkPlayerControl`] and [`NetworkInputCollector`] are automatically implemented.
16#[allow(missing_docs)]
17pub trait NetworkInputConfig<'a> {
18    type Dense: DenseInput + Debug + Default;
19    type Control: NetworkPlayerControl<Self::Dense>;
20
21    // Must be HasSchema because expected to be retrieved from `World` as `Resource`.
22    type PlayerControls: PlayerControls<'a, Self::Control> + HasSchema;
23
24    // InputCollector type params must match that of PlayerControls, so using associated types.
25    type InputCollector: InputCollector<
26            'a,
27            <Self::PlayerControls as PlayerControls<'a, Self::Control>>::ControlMapping,
28            <Self::PlayerControls as PlayerControls<'a, Self::Control>>::ControlSource,
29            Self::Control,
30        > + Default;
31}
32
33/// Required for use of [`PlayerControls`] in networking.
34pub trait NetworkPlayerControls<'a, Dense: DenseInput, Control>:
35    PlayerControls<'a, Control>
36{
37    /// Update control of player from dense input.
38    ///
39    /// [`NetworkInputStatus`] communicates if input is confirmed, predicted, or from disconnected player.
40    fn network_update(
41        &mut self,
42        player_idx: usize,
43        dense_input: &Dense,
44        status: NetworkInputStatus,
45    );
46
47    /// Get dense control for player.
48    fn get_dense_control(&self, player_idx: usize) -> Dense;
49}
50
51impl<'a, T, Dense, Control> NetworkPlayerControls<'a, Dense, Control> for T
52where
53    Dense: DenseInput,
54    Control: NetworkPlayerControl<Dense>,
55    T: PlayerControls<'a, Control>,
56{
57    // type NetworkControl = PlayerControl;
58    fn network_update(
59        &mut self,
60        player_idx: usize,
61        dense_input: &Dense,
62        _status: NetworkInputStatus,
63    ) {
64        self.get_control_mut(player_idx)
65            .update_from_dense(dense_input);
66    }
67
68    fn get_dense_control(&self, player_idx: usize) -> Dense {
69        self.get_control(player_idx).get_dense_input()
70    }
71}
72
73/// Dense input for network replication.
74pub trait DenseInput:
75    bytemuck::Pod + bytemuck::Zeroable + Copy + Clone + PartialEq + Eq + Send + Sync
76{
77}
78
79/// Automatic implementation for `DenseInput`.
80impl<T> DenseInput for T where
81    T: bytemuck::Pod + bytemuck::Zeroable + Copy + Clone + PartialEq + Eq + Send + Sync
82{
83}
84
85///  Trait allowing for creating and applying [`DenseInput`] from control.
86pub trait NetworkPlayerControl<Dense: DenseInput>: Send + Sync + Default {
87    /// Get [`DenseInput`] for control.
88    fn get_dense_input(&self) -> Dense;
89
90    /// Update control from [`DenseInput`].
91    fn update_from_dense(&mut self, new_control: &Dense);
92}
93
94/// Extension of [`InputCollector`] exposing dense control for networking.
95///
96/// This trait is automatically implemented for [`InputCollector`]'s such that `Control`
97/// implements [`NetworkPlayerControl`] (i.e. implements dense input)
98pub trait NetworkInputCollector<'a, Dense, ControlMapping, ControlSource, Control>:
99    InputCollector<'a, ControlMapping, ControlSource, Control>
100where
101    Dense: DenseInput,
102    ControlMapping: HasSchema,
103    Control: NetworkPlayerControl<Dense>,
104{
105    /// Get dense control
106    fn get_dense_control(&self, player_idx: usize, control_soure: ControlSource) -> Dense;
107}
108
109/// Provide automatic [`NetworkInputCollector`] for [`InputCollector`] when type parameters
110/// meet required bounds for networking.
111impl<'a, T, Dense, ControlMapping, ControlSource, Control>
112    NetworkInputCollector<'a, Dense, ControlMapping, ControlSource, Control> for T
113where
114    Dense: DenseInput,
115    Control: NetworkPlayerControl<Dense>,
116    ControlMapping: HasSchema,
117    T: InputCollector<'a, ControlMapping, ControlSource, Control>,
118{
119    fn get_dense_control(&self, player_idx: usize, control_source: ControlSource) -> Dense {
120        self.get_control(player_idx, control_source)
121            .get_dense_input()
122    }
123}