beetmash_net/networking/
transport_plugin.rs

1use crate::prelude::*;
2use bevy::prelude::*;
3use bevy::time::common_conditions::on_timer;
4use forky::prelude::ResultTEExt;
5use std::time::Duration;
6
7pub const DEFAULT_TRANSPORT_INTERVAL: Duration = Duration::from_millis(100);
8
9#[extend::ext(name=AppExtTransport)]
10pub impl App {
11	/// Adds the [`transport_incoming`] and [`transport_outgoing`] systems for a given transport type, and inserts it as a [`NonSend`]
12	/// ```rust
13	/// app
14	/// 	.insert_non_send_resource(ChannelsTransport)
15	/// 	.add_plugins(TransportPlugin::<ChannelsTransport>::new());
16	/// ```
17	fn add_transport<T: 'static + Transport>(
18		&mut self,
19		transport: T,
20	) -> &mut Self {
21		self.add_transport_with_duration(transport, DEFAULT_TRANSPORT_INTERVAL)
22	}
23	fn add_transport_with_duration<T: 'static + Transport>(
24		&mut self,
25		transport: T,
26		interval: Duration,
27	) -> &mut Self {
28		self.insert_non_send_resource(transport).add_systems(
29			Update,
30			(
31				transport_incoming::<T>
32					.run_if(on_timer(interval))
33					.before(MessageIncomingSet),
34				transport_outgoing::<T>
35					.run_if(on_timer(interval))
36					.after(MessageOutgoingSet),
37			),
38		);
39		self
40	}
41}
42
43pub(crate) fn transport_incoming<T: Transport>(
44	mut events: ResMut<MessageIncoming>,
45	mut transport: NonSendMut<T>,
46) {
47	if let Some(messages) = transport.recv().ok_or(|e| log::error!("foo {e}")) {
48		for message in messages {
49			// log::info!("<<< MESSAGE: {:?}", message);
50			events.push(message);
51		}
52	}
53}
54
55pub(crate) fn transport_outgoing<T: Transport>(
56	mut outgoing: ResMut<MessageOutgoing>,
57	mut transport: NonSendMut<T>,
58) {
59	if outgoing.is_empty() {
60		return;
61	}
62
63	let messages = outgoing.drain(..).collect();
64	transport.send(&messages).ok_or(|e| log::error!("{e}"));
65	// {
66	// 	#[cfg(target_arch = "wasm32")]
67	// 	wasm_bindgen_futures::spawn_local(async move {
68	// 	});
69
70	// 	#[cfg(not(target_arch = "wasm32"))]
71	// 	//TODO transport defines async runtime
72	// 	std::thread::spawn(|| {
73	// 		bevy::tasks::block_on(async move {
74	// 			client.send(&messages).await.ok_or(|e| log::error!("{e}"));
75	// 		});
76	// 	});
77	// }
78}
79
80// #[derive(Debug, Default, Copy, Clone)]
81// pub struct TransportPlugin<T: Transport> {
82// 	phantom: PhantomData<T>,
83// 	interval: Duration,
84// }
85
86// impl<T: Transport> TransportPlugin<T> {
87// 	pub fn new() -> Self {
88// 		Self {
89// 			phantom: PhantomData,
90// 			interval: DEFAULT_TRANSPORT_INTERVAL,
91// 		}
92// 	}
93// 	pub fn new_with_interval(interval: Duration) -> Self {
94// 		Self {
95// 			phantom: PhantomData,
96// 			interval,
97// 		}
98// 	}
99
100// 	pub fn with_interval(mut self, interval: Duration) -> Self {
101// 		self.interval = interval;
102// 		self
103// 	}
104// }