Better packet handlers

This commit is contained in:
Tipragot 2023-04-30 16:36:14 +02:00
parent 9ea49fc109
commit 277afd16da
2 changed files with 91 additions and 76 deletions

View file

@ -112,20 +112,15 @@ impl Plugin for ClientPlugin {
#[cfg(feature = "sync")]
{
app.add_packet_handler::<Entity, _>(|data, world| {
match bincode::deserialize::<Entity>(&data) {
Ok(entity) => {
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
world.despawn(local_entity);
} else {
world.spawn(ServerEntity(entity));
}
}
Err(_) => println!("Failed to deserialize packet: {}", type_name::<Entity>()),
app.add_packet_handler(|entity: Entity, world| {
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
world.despawn(local_entity);
} else {
world.spawn(ServerEntity(entity));
}
});
app.add_system(Self::remove_synced.run_if(resource_removed::<ServerConnection>()));
@ -136,7 +131,10 @@ impl Plugin for ClientPlugin {
/// An extension to add packet handlers.
pub trait NetworkExt {
/// Add a new packet handler.
fn add_packet_handler<P: Packet, H: PacketHandlerFn>(&mut self, handler: H) -> &mut Self;
fn add_packet_handler<P: Packet, H: Fn(P, &mut World) + Send + Sync + 'static>(
&mut self,
handler: H,
) -> &mut Self;
#[cfg(all(feature = "sync"))]
/// Register syncronization for an [Event] that can be sent by the server.
@ -156,20 +154,28 @@ pub trait NetworkExt {
}
impl NetworkExt for App {
fn add_packet_handler<P: Packet, H: PacketHandlerFn>(&mut self, handler: H) -> &mut Self {
fn add_packet_handler<P: Packet, H: Fn(P, &mut World) + Send + Sync + 'static>(
&mut self,
handler: H,
) -> &mut Self {
Arc::get_mut(&mut self.world.resource_mut::<HandlerManager>().0)
.unwrap()
.insert(P::packet_id(), Box::new(handler));
.insert(
P::packet_id(),
Box::new(
move |data: Vec<u8>, world| match bincode::deserialize::<P>(&data) {
Ok(packet) => handler(packet, world),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<P>()),
},
),
);
self
}
#[cfg(feature = "sync")]
fn sync_server_event<E: Event + Packet>(&mut self) -> &mut Self {
self.add_event::<FromServer<E>>()
.add_packet_handler::<E, _>(|data, world| match bincode::deserialize::<E>(&data) {
Ok(event) => world.send_event(FromServer { event }),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<E>()),
})
.add_packet_handler(|event: E, world| world.send_event(FromServer { event }))
}
#[cfg(feature = "sync")]
@ -187,54 +193,43 @@ impl NetworkExt for App {
#[cfg(feature = "sync")]
fn sync_component<C: Component + DeserializeOwned + Serialize>(&mut self) -> &mut Self {
self.add_packet_handler::<(Entity, C), _>(|data, world| {
match bincode::deserialize::<(Entity, C)>(&data) {
Ok((entity, component)) => {
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
let mut local_entity = world.entity_mut(local_entity);
match local_entity.get_mut::<C>() {
Some(mut local_component) => {
*local_component = component;
}
None => {
local_entity.insert(component);
}
}
} else {
println!("Received component for unknown entity: {:?}", entity);
self.add_packet_handler(|data: (Entity, C), world| {
let (entity, component) = data;
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
let mut local_entity = world.entity_mut(local_entity);
match local_entity.get_mut::<C>() {
Some(mut local_component) => {
*local_component = component;
}
None => {
local_entity.insert(component);
}
}
Err(_) => println!("Failed to deserialize packet: {}", type_name::<C>()),
} else {
println!("Received component for unknown entity: {:?}", entity);
}
})
.add_packet_handler(|data: (Entity, PhantomData<C>), world| {
let (entity, _) = data;
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
world.entity_mut(local_entity).remove::<C>();
}
})
.add_packet_handler::<(Entity, PhantomData<C>), _>(
|data, world| match bincode::deserialize::<(Entity, PhantomData<C>)>(&data) {
Ok((entity, _)) => {
if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>()
.iter(world)
.find(|(_, server_entity)| server_entity.0 == entity)
{
world.entity_mut(local_entity).remove::<C>();
}
}
Err(_) => println!("Failed to deserialize packet: {}", type_name::<C>()),
},
)
}
#[cfg(feature = "sync")]
fn sync_resource<R: Resource + DeserializeOwned + Serialize>(&mut self) -> &mut Self {
self.add_packet_handler::<R, _>(|data, world| match bincode::deserialize::<R>(&data) {
Ok(resource) => world.insert_resource(resource),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<R>()),
})
.add_packet_handler::<PhantomData<R>, _>(|_, world| {
world.remove_resource::<R>();
})
self.add_packet_handler(|resource: R, world| world.insert_resource(resource))
.add_packet_handler(|_: PhantomData<R>, world| {
world.remove_resource::<R>();
})
}
}

View file

@ -193,7 +193,13 @@ impl Plugin for ServerPlugin {
/// An extension to add packet handlers.
pub trait NetworkExt {
/// Add a new packet handler.
fn add_packet_handler<P: Packet, H: PacketHandlerFn>(&mut self, handler: H) -> &mut Self;
fn add_packet_handler<
P: Packet,
H: Fn(Entity, ClientConnection, P, &mut World) + Send + Sync + 'static,
>(
&mut self,
handler: H,
) -> &mut Self;
#[cfg(all(feature = "sync"))]
/// Register syncronization for an [Event] that can be sent by the server.
@ -213,10 +219,26 @@ pub trait NetworkExt {
}
impl NetworkExt for App {
fn add_packet_handler<P: Packet, H: PacketHandlerFn>(&mut self, handler: H) -> &mut Self {
fn add_packet_handler<
P: Packet,
H: Fn(Entity, ClientConnection, P, &mut World) + Send + Sync + 'static,
>(
&mut self,
handler: H,
) -> &mut Self {
Arc::get_mut(&mut self.world.resource_mut::<HandlerManager>().0)
.unwrap()
.insert(P::packet_id(), Box::new(handler));
.insert(
P::packet_id(),
Box::new(
move |entity, connection, data: Vec<u8>, world| match bincode::deserialize::<P>(
&data,
) {
Ok(packet) => handler(entity, connection, packet, world),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<P>()),
},
),
);
self
}
@ -235,17 +257,15 @@ impl NetworkExt for App {
#[cfg(feature = "sync")]
fn sync_client_event<E: Event + Packet>(&mut self) -> &mut Self {
self.add_event::<FromClient<E>>()
.add_packet_handler::<E, _>(
|entity, connection, data, world| match bincode::deserialize::<E>(&data) {
Ok(event) => world.send_event(FromClient {
entity,
connection,
event,
}),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<E>()),
},
)
self.add_event::<FromClient<E>>().add_packet_handler(
|entity, connection, event: E, world| {
world.send_event(FromClient {
entity,
connection,
event,
})
},
)
}
#[cfg(feature = "sync")]