More complete Peer distribution
All checks were successful
CI / Formatting (push) Successful in 45s

Slightly better implementation of peers, still need to create a more generic system for deciding which components to distribute where and then use that for Peers.
This commit is contained in:
Michael Bradley 2025-10-13 01:06:31 -04:00
parent e013fb427a
commit 53fe3333f0
Signed by: MichaelBradley
SSH key fingerprint: SHA256:BKO2eI2LPsCbQS3n3i5SdwZTAIV3F1lHezR07qP+Ob0
14 changed files with 438 additions and 265 deletions

View file

@ -2,13 +2,16 @@ use bevy::prelude::*;
use crate::net::prelude::*;
pub fn handle_new_peer(new_peers: Query<&Peer, Added<Peer>>) {
pub fn handle_new_peer(new_peers: Query<&PeerID, Added<Peer>>) {
for peer in new_peers {
info!("Peer {} was added", peer.id);
}
}
pub fn handle_deleted_peer(mut old_peers: RemovedComponents<Peer>, peers: Query<&Peer>) -> Result {
pub fn handle_deleted_peer(
mut old_peers: RemovedComponents<Peer>,
peers: Query<&PeerID>,
) -> Result {
for entity in old_peers.read() {
if let Ok(peer) = peers.get(entity) {
info!("Peer {} was removed", peer.id);
@ -20,7 +23,7 @@ pub fn handle_deleted_peer(mut old_peers: RemovedComponents<Peer>, peers: Query<
}
pub fn handle_incoming_packets(mut packets: EventReader<InboundPacket>) {
for packet in packets.read() {
info!("Packet received: {:?}", packet.0.message);
for InboundPacket(packet) in packets.read() {
info!("Packet received: {:?}", packet.message);
}
}

View file

@ -13,7 +13,10 @@ use super::{
check_for_seed, setup_balls, setup_camera, setup_from_seed, setup_player, setup_walls,
},
state::AppState,
ui::{setup_peer_ui, setup_seed_ui, update_peer_ui, update_peer_ui_timings, update_seed_ui},
ui::{
setup_peer_ui, setup_potential_peer_ui, setup_seed_ui, update_peer_ui,
update_peer_ui_timings, update_potential_peer_ui, update_seed_ui,
},
};
#[derive(Debug, Clone, Copy)]
@ -55,11 +58,20 @@ impl GamePlugin {
impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_plugins((
NetIOPlugin::new(self.port, self.source.try_to_address()),
NetIOPlugin::maybe_peer(self.port, self.source.try_to_address()),
distribution_plugin::<Seed>,
PhysicsPlugins::default().with_length_unit(50.0),
))
.init_state::<AppState>()
.add_systems(Startup, (setup_camera, setup_seed_ui, setup_peer_ui))
.add_systems(
Startup,
(
setup_camera,
setup_seed_ui,
setup_peer_ui,
setup_potential_peer_ui,
),
)
.add_systems(
OnEnter(AppState::InGame),
(
@ -75,8 +87,7 @@ impl Plugin for GamePlugin {
handle_new_peer,
handle_deleted_peer,
handle_incoming_packets,
)
.run_if(in_state(NetworkState::MultiPlayer)),
),
),
)
.add_systems(
@ -85,14 +96,15 @@ impl Plugin for GamePlugin {
((move_player, move_camera).chain(), zoom_camera)
.run_if(in_state(AppState::InGame)),
update_seed_ui,
(update_peer_ui, update_peer_ui_timings)
.run_if(in_state(NetworkState::MultiPlayer)),
(
update_peer_ui,
update_peer_ui_timings,
update_potential_peer_ui,
),
quit.run_if(input_pressed(KeyCode::KeyQ)),
),
);
Seed::register(app);
match self.source {
DataSource::Address(peer) => {
info!("Will retrieve seed from peer => {peer}");

View file

@ -61,7 +61,7 @@ impl From<Seed> for Vec<u8> {
impl TryFrom<Vec<u8>> for Seed {
type Error = TryFromSliceError;
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
fn try_from(value: Vec<u8>) -> std::result::Result<Self, Self::Error> {
Ok(TryInto::<[u8; 8]>::try_into(value.as_slice())?.into())
}
}

View file

@ -1,6 +1,6 @@
use bevy::prelude::*;
use crate::net::prelude::{Peer, PeerReceiveTiming, PeerSendTiming};
use crate::net::prelude::{Peer, PeerID, PeerReceiveTiming, PeerSendTiming, PotentialPeers};
use super::seed::Seed;
@ -54,11 +54,11 @@ pub fn setup_peer_ui(mut commands: Commands) {
}
#[derive(Component)]
pub struct PeerID(Entity);
pub struct UIPeerID(Entity);
pub fn update_peer_ui(
ui: Query<(Entity, &Children), With<PeerUI>>,
rows: Query<&PeerID>,
rows: Query<&UIPeerID>,
added: Query<Entity, Added<Peer>>,
mut removed: RemovedComponents<Peer>,
mut commands: Commands,
@ -67,14 +67,14 @@ pub fn update_peer_ui(
for addition in added {
commands
.entity(table)
.with_child((Text::new("---- ---- ----"), PeerID(addition)));
.with_child((Text::new("---- ---- ----"), UIPeerID(addition)));
}
for removal in removed.read() {
for child in children {
if let Ok(id) = rows.get(*child) {
if id.0 == removal {
commands.entity(*child).despawn();
}
if let Ok(&UIPeerID(id)) = rows.get(*child)
&& id == removal
{
commands.entity(*child).despawn();
}
}
}
@ -82,12 +82,12 @@ pub fn update_peer_ui(
}
pub fn update_peer_ui_timings(
rows: Query<(&mut Text, &PeerID)>,
peers: Query<(&Peer, &PeerReceiveTiming, &PeerSendTiming)>,
rows: Query<(&mut Text, &UIPeerID)>,
peers: Query<(&PeerID, &PeerReceiveTiming, &PeerSendTiming)>,
time: Res<Time>,
) {
for (mut row, id) in rows {
if let Ok((peer, recv, send)) = peers.get(id.0) {
for (mut row, &UIPeerID(id)) in rows {
if let Ok((peer, recv, send)) = peers.get(id) {
**row = format!(
"{} {:.2} {:.2}",
peer.id,
@ -97,3 +97,34 @@ pub fn update_peer_ui_timings(
}
}
}
#[derive(Component, Debug)]
pub struct PotentialPeerUI;
pub fn setup_potential_peer_ui(mut commands: Commands) {
commands
.spawn((
Text::new("Potential peers:"),
Node {
position_type: PositionType::Absolute,
bottom: Val::Px(5.0),
right: Val::Px(5.0),
..default()
},
))
.with_child((TextSpan::new(""), PotentialPeerUI));
}
pub fn update_potential_peer_ui(
potential_peers: Res<PotentialPeers>,
text: Query<&mut TextSpan, With<PotentialPeerUI>>,
) {
for mut span in text {
**span = potential_peers
.addresses
.iter()
.map(|addr| addr.to_string())
.collect::<Vec<String>>()
.join("\n");
}
}