Merge branch 'better-packet-handler' into 'main'

Better packet handlers

See merge request tipragot/bevnet!8
This commit is contained in:
Tipragot 2023-04-30 16:36:59 +02:00
commit 40cc38fe60
2 changed files with 91 additions and 76 deletions

View file

@ -112,9 +112,7 @@ impl Plugin for ClientPlugin {
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
{ {
app.add_packet_handler::<Entity, _>(|data, world| { app.add_packet_handler(|entity: Entity, world| {
match bincode::deserialize::<Entity>(&data) {
Ok(entity) => {
if let Some((local_entity, _)) = world if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>() .query::<(Entity, &ServerEntity)>()
.iter(world) .iter(world)
@ -124,9 +122,6 @@ impl Plugin for ClientPlugin {
} else { } else {
world.spawn(ServerEntity(entity)); world.spawn(ServerEntity(entity));
} }
}
Err(_) => println!("Failed to deserialize packet: {}", type_name::<Entity>()),
}
}); });
app.add_system(Self::remove_synced.run_if(resource_removed::<ServerConnection>())); 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. /// An extension to add packet handlers.
pub trait NetworkExt { pub trait NetworkExt {
/// Add a new packet handler. /// 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"))] #[cfg(all(feature = "sync"))]
/// Register syncronization for an [Event] that can be sent by the server. /// Register syncronization for an [Event] that can be sent by the server.
@ -156,20 +154,28 @@ pub trait NetworkExt {
} }
impl NetworkExt for App { 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) Arc::get_mut(&mut self.world.resource_mut::<HandlerManager>().0)
.unwrap() .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 self
} }
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
fn sync_server_event<E: Event + Packet>(&mut self) -> &mut Self { fn sync_server_event<E: Event + Packet>(&mut self) -> &mut Self {
self.add_event::<FromServer<E>>() self.add_event::<FromServer<E>>()
.add_packet_handler::<E, _>(|data, world| match bincode::deserialize::<E>(&data) { .add_packet_handler(|event: E, world| world.send_event(FromServer { event }))
Ok(event) => world.send_event(FromServer { event }),
Err(_) => println!("Failed to deserialize packet: {}", type_name::<E>()),
})
} }
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
@ -187,9 +193,8 @@ impl NetworkExt for App {
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
fn sync_component<C: Component + DeserializeOwned + Serialize>(&mut self) -> &mut Self { fn sync_component<C: Component + DeserializeOwned + Serialize>(&mut self) -> &mut Self {
self.add_packet_handler::<(Entity, C), _>(|data, world| { self.add_packet_handler(|data: (Entity, C), world| {
match bincode::deserialize::<(Entity, C)>(&data) { let (entity, component) = data;
Ok((entity, component)) => {
if let Some((local_entity, _)) = world if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>() .query::<(Entity, &ServerEntity)>()
.iter(world) .iter(world)
@ -207,13 +212,9 @@ impl NetworkExt for App {
} else { } else {
println!("Received component for unknown entity: {:?}", entity); println!("Received component for unknown entity: {:?}", entity);
} }
}
Err(_) => println!("Failed to deserialize packet: {}", type_name::<C>()),
}
}) })
.add_packet_handler::<(Entity, PhantomData<C>), _>( .add_packet_handler(|data: (Entity, PhantomData<C>), world| {
|data, world| match bincode::deserialize::<(Entity, PhantomData<C>)>(&data) { let (entity, _) = data;
Ok((entity, _)) => {
if let Some((local_entity, _)) = world if let Some((local_entity, _)) = world
.query::<(Entity, &ServerEntity)>() .query::<(Entity, &ServerEntity)>()
.iter(world) .iter(world)
@ -221,19 +222,13 @@ impl NetworkExt for App {
{ {
world.entity_mut(local_entity).remove::<C>(); world.entity_mut(local_entity).remove::<C>();
} }
} })
Err(_) => println!("Failed to deserialize packet: {}", type_name::<C>()),
},
)
} }
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
fn sync_resource<R: Resource + DeserializeOwned + Serialize>(&mut self) -> &mut Self { fn sync_resource<R: Resource + DeserializeOwned + Serialize>(&mut self) -> &mut Self {
self.add_packet_handler::<R, _>(|data, world| match bincode::deserialize::<R>(&data) { self.add_packet_handler(|resource: R, world| world.insert_resource(resource))
Ok(resource) => world.insert_resource(resource), .add_packet_handler(|_: PhantomData<R>, world| {
Err(_) => println!("Failed to deserialize packet: {}", type_name::<R>()),
})
.add_packet_handler::<PhantomData<R>, _>(|_, world| {
world.remove_resource::<R>(); world.remove_resource::<R>();
}) })
} }

View file

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