Create generic distribution system

Still incredibly basic and only handles initial distribution and spawning with no relationships or anything.
This commit is contained in:
Michael Bradley 2025-07-06 18:29:58 -04:00
parent d76afe92f0
commit 4db82f328b
Signed by: MichaelBradley
SSH key fingerprint: SHA256:o/aaeYtRubILK7OYYjYP12DmU7BsPUhKji1AgaQ+ge4
5 changed files with 66 additions and 8 deletions

View file

@ -91,6 +91,8 @@ impl Plugin for GamePlugin {
), ),
); );
Seed::register(app);
match self.source { match self.source {
DataSource::Address(peer) => { DataSource::Address(peer) => {
info!("Will retrieve seed from peer => {peer}"); info!("Will retrieve seed from peer => {peer}");

49
src/net/distribution.rs Normal file
View file

@ -0,0 +1,49 @@
use bevy::prelude::*;
use super::{
packet::{InboundPacket, OutboundPacket, Packet},
peer::Peer,
state::NetworkState,
};
fn spawner<T: TryFrom<Vec<u8>> + Component>(
mut inbound: EventReader<InboundPacket>,
mut commands: Commands,
) {
for packet in inbound.read() {
if let Ok(entity) = T::try_from(packet.0.message.clone()) {
commands.spawn(entity);
}
}
}
fn sender<T: Into<Vec<u8>> + Component + Clone>(
peers: Query<&Peer, Added<Peer>>,
entities: Query<&T>,
mut outbound: EventWriter<OutboundPacket>,
) {
for peer in peers {
for entity in entities {
outbound.write(OutboundPacket(Packet::new(
(*entity).clone().into(),
peer.uuid,
)));
}
}
}
pub trait Networked: Into<Vec<u8>> + TryFrom<Vec<u8>> + Component + Clone {
fn register(app: &mut App);
}
impl<T> Networked for T
where
T: Into<Vec<u8>> + TryFrom<Vec<u8>> + Component + Clone,
{
fn register(app: &mut App) {
app.add_systems(
FixedUpdate,
(sender::<T>, spawner::<T>).run_if(in_state(NetworkState::MultiPlayer)),
);
}
}

View file

@ -1,14 +1,18 @@
mod distribution;
mod io; mod io;
mod packet; mod packet;
mod peer; mod peer;
mod plugin; mod plugin;
mod queues; mod queues;
mod socket; mod socket;
mod state;
mod thread; mod thread;
#[allow(unused_imports)] #[allow(unused_imports)]
pub mod prelude { pub mod prelude {
pub use super::distribution::Networked;
pub use super::packet::{InboundPacket, OutboundPacket, Packet}; pub use super::packet::{InboundPacket, OutboundPacket, Packet};
pub use super::peer::{Peer, PeerReceiveTiming, PeerSendTiming}; pub use super::peer::{Peer, PeerReceiveTiming, PeerSendTiming};
pub use super::plugin::{NetIOPlugin, NetworkState}; pub use super::plugin::NetIOPlugin;
pub use super::state::NetworkState;
} }

View file

@ -4,20 +4,15 @@ use bevy::prelude::*;
use uuid::Uuid; use uuid::Uuid;
use super::{ use super::{
distribution::Networked,
io::{Config, handle_network_input, handle_network_output, heartbeat, timeout}, io::{Config, handle_network_input, handle_network_output, heartbeat, timeout},
packet::{InboundPacket, OutboundPacket}, packet::{InboundPacket, OutboundPacket},
peer::{Peer, PeerChangeEvent, PeerMap, handle_new_peer, handle_peer_change}, peer::{Peer, PeerChangeEvent, PeerMap, handle_new_peer, handle_peer_change},
queues::{NetworkReceive, NetworkSend}, queues::{NetworkReceive, NetworkSend},
socket::bind_socket, socket::bind_socket,
state::NetworkState,
}; };
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
pub enum NetworkState {
#[default]
SinglePlayer,
MultiPlayer,
}
pub struct NetIOPlugin { pub struct NetIOPlugin {
listen: u16, listen: u16,
peer: Option<SocketAddr>, peer: Option<SocketAddr>,

8
src/net/state.rs Normal file
View file

@ -0,0 +1,8 @@
use bevy::prelude::*;
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
pub enum NetworkState {
#[default]
SinglePlayer,
MultiPlayer,
}