Skip to main content

spru_bevy/server/
component.rs

1use std::collections::VecDeque;
2
3use bevy::prelude;
4use derive_where::derive_where;
5
6#[derive(Debug, prelude::Component)]
7#[require(FromClient<Server>, ToClient<Server>, FromUser<Server>, PendingClients<Server>)]
8pub struct Runner<Server: super::ServerSSS> {
9    pub(crate) server: Server,
10}
11
12impl<Server: super::ServerSSS> Runner<Server> {
13    pub(crate) fn new(server: Server) -> Self {
14        Self { server }
15    }
16
17    pub fn save(&self) -> Result<spru::server::Save<Server>, spru::server::error::SaveError>
18    where
19        Server::PlayerInit: Clone,
20        Server::Reaction: Clone,
21    {
22        self.server.save()
23    }
24
25    pub fn storage(
26        &self,
27    ) -> &spru::item::storage::Canonical<<Server::State as tagset::TagSet>::Repr, Server::State>
28    {
29        self.server.storage()
30    }
31}
32
33#[derive_where(Debug; spru::common::signal::ToServer<Server::Common>)]
34#[derive_where(Default)]
35#[derive(prelude::Component)]
36pub struct FromClient<Server: super::ServerSSS> {
37    queues: Vec<(
38        spru::player::Id,
39        VecDeque<spru::common::signal::ToServer<Server::Common>>,
40    )>,
41}
42
43impl<Server: super::ServerSSS> FromClient<Server> {
44    pub fn len(&self) -> usize {
45        self.queues.len()
46    }
47
48    pub fn is_empty(&self) -> bool {
49        for (_, queue) in &self.queues {
50            if !queue.is_empty() {
51                return false;
52            }
53        }
54        true
55    }
56
57    pub fn enqueue(
58        &mut self,
59        client_id: spru::player::Id,
60        signal: spru::common::signal::ToServer<Server::Common>,
61    ) {
62        get_queue_mut(client_id, &mut self.queues).push_back(signal);
63    }
64
65    pub(crate) fn dequeue_any(
66        &mut self,
67    ) -> Option<(
68        spru::player::Id,
69        spru::common::signal::ToServer<Server::Common>,
70    )> {
71        for (client_id, queue) in &mut self.queues {
72            if let Some(signal) = queue.pop_front() {
73                return Some((*client_id, signal));
74            }
75        }
76        None
77    }
78}
79
80#[derive_where(Debug; spru::common::signal::ToClient<Server::Common>)]
81#[derive_where(Default)]
82#[derive(prelude::Component)]
83pub struct ToClient<Server: super::ServerSSS> {
84    queues: Vec<(
85        spru::player::Id,
86        VecDeque<spru::common::signal::ToClient<Server::Common>>,
87    )>,
88}
89
90impl<Server: super::ServerSSS> ToClient<Server> {
91    pub fn len(&self) -> usize {
92        self.queues.len()
93    }
94
95    pub fn is_empty(&self) -> bool {
96        for (_, queue) in &self.queues {
97            if !queue.is_empty() {
98                return false;
99            }
100        }
101        true
102    }
103
104    pub(crate) fn enqueue(
105        &mut self,
106        client_id: spru::player::Id,
107        signal: spru::common::signal::ToClient<Server::Common>,
108    ) {
109        get_queue_mut(client_id, &mut self.queues).push_back(signal);
110    }
111
112    pub fn dequeue(
113        &mut self,
114        client_id: spru::player::Id,
115    ) -> Option<spru::common::signal::ToClient<Server::Common>> {
116        get_queue_mut(client_id, &mut self.queues).pop_front()
117    }
118
119    pub fn dequeue_any(
120        &mut self,
121    ) -> Option<(
122        spru::player::Id,
123        spru::common::signal::ToClient<Server::Common>,
124    )> {
125        for (client_id, queue) in &mut self.queues {
126            if let Some(signal) = queue.pop_front() {
127                return Some((*client_id, signal));
128            }
129        }
130        None
131    }
132}
133
134fn get_queue_mut<T>(
135    player_id: spru::player::Id,
136    queues: &mut Vec<(spru::player::Id, VecDeque<T>)>,
137) -> &mut VecDeque<T> {
138    let mut index = None;
139    for (i, (queue_player_id, _queue)) in queues.iter_mut().enumerate() {
140        if player_id == *queue_player_id {
141            index = Some(i);
142            break;
143        }
144    }
145
146    let index = match index {
147        Some(index) => index,
148        None => {
149            queues.push((player_id, VecDeque::new()));
150            queues.len() - 1
151        }
152    };
153
154    &mut queues[index].1
155}
156
157#[derive_where(Default; )]
158#[derive_where(Debug; super::PendingClient<Server::Common>)]
159#[derive(prelude::Component)]
160pub struct PendingClients<Server: super::ServerSSS> {
161    queue: VecDeque<super::PendingClient<Server::Common>>,
162}
163
164impl<Server: super::ServerSSS> PendingClients<Server> {
165    pub fn len(&self) -> usize {
166        self.queue.len()
167    }
168
169    pub fn is_empty(&self) -> bool {
170        self.queue.is_empty()
171    }
172
173    pub(crate) fn enqueue(&mut self, pending_client: super::PendingClient<Server::Common>) {
174        self.queue.push_back(pending_client);
175    }
176
177    pub fn dequeue(&mut self) -> Option<super::PendingClient<Server::Common>> {
178        self.queue.pop_front()
179    }
180}
181
182#[derive_where(Debug; UserInput<Server>)]
183#[derive_where(Default)]
184#[derive(prelude::Component)]
185pub struct FromUser<Server: super::ServerSSS> {
186    queue: VecDeque<UserInput<Server>>,
187}
188
189impl<Server: super::ServerSSS> FromUser<Server> {
190    pub fn len(&self) -> usize {
191        self.queue.len()
192    }
193
194    pub fn is_empty(&self) -> bool {
195        self.queue.is_empty()
196    }
197
198    pub fn add_player(&mut self, user_init_in: <Server::PlayerInit as spru::player::Init>::In) {
199        self.queue.push_back(UserInput::AddPlayer(user_init_in));
200    }
201
202    pub fn manual_trigger(&mut self, trigger: <Server::Reaction as spru::Reaction>::Trigger) {
203        self.queue.push_back(UserInput::ManualTrigger(trigger));
204    }
205
206    pub(crate) fn dequeue(&mut self) -> Option<UserInput<Server>> {
207        self.queue.pop_front()
208    }
209}
210
211#[derive_where(Debug;
212    <Server::PlayerInit as spru::player::Init>::In,
213    <Server::Reaction as spru::Reaction>::Trigger,
214)]
215pub(crate) enum UserInput<Server: super::ServerSSS> {
216    AddPlayer(<Server::PlayerInit as spru::player::Init>::In),
217    ManualTrigger(<Server::Reaction as spru::Reaction>::Trigger),
218}