use bevy::{
ecs::{lifecycle::HookContext, world::DeferredWorld},
platform::collections::HashMap,
prelude::*,
};
use log::error;
use serde::{Deserialize, Serialize};
use crate::prelude::*;
#[derive(Component, Reflect)]
#[component(immutable)]
#[require(Name::new("Connected client"), ConnectedClientStats)]
pub struct ConnectedClient {
pub max_size: usize,
}
#[derive(Resource, Default, Reflect, Deref)]
pub struct NetworkIdMap(HashMap<NetworkId, Entity>);
#[derive(
Component,
Debug,
Clone,
Copy,
Hash,
PartialEq,
Eq,
Ord,
PartialOrd,
Reflect,
Serialize,
Deserialize,
)]
#[component(on_add = on_id_add, on_remove = on_id_remove)]
pub struct NetworkId(u64);
impl NetworkId {
pub const fn new(value: u64) -> Self {
Self(value)
}
pub fn get(&self) -> u64 {
self.0
}
}
fn on_id_add(mut world: DeferredWorld, ctx: HookContext) {
let network_id = *world.get::<NetworkId>(ctx.entity).unwrap();
let mut network_map = world.resource_mut::<NetworkIdMap>();
if let Some(old_client) = network_map.0.insert(network_id, ctx.entity) {
error!("backend-provided `{network_id:?}` was already mapped to client `{old_client}`");
}
}
fn on_id_remove(mut world: DeferredWorld, ctx: HookContext) {
let network_id = *world.get::<NetworkId>(ctx.entity).unwrap();
let mut network_map = world.resource_mut::<NetworkIdMap>();
network_map.0.remove(&network_id);
}