Rename things to make them much clear
This commit is contained in:
parent
1a8136b078
commit
59dc588c39
|
@ -23,9 +23,9 @@ struct HandlerManager(Arc<HashMap<u64, PacketHandler>>);
|
||||||
|
|
||||||
/// A [Connection] to a remote server.
|
/// A [Connection] to a remote server.
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct Connection(tcp::Connection);
|
pub struct ServerConnection(tcp::Connection);
|
||||||
|
|
||||||
impl Connection {
|
impl ServerConnection {
|
||||||
/// Connects to a remote server.
|
/// Connects to a remote server.
|
||||||
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<Self> {
|
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<Self> {
|
||||||
Ok(Self(tcp::Connection::connect(addr)?))
|
Ok(Self(tcp::Connection::connect(addr)?))
|
||||||
|
@ -42,7 +42,7 @@ impl Connection {
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
/// An event that comes from the server.
|
/// An event that comes from the server.
|
||||||
#[derive(Deref)]
|
#[derive(Deref)]
|
||||||
pub struct PacketEvent<E: Event + Packet> {
|
pub struct FromServer<E: Event + Packet> {
|
||||||
/// The event.
|
/// The event.
|
||||||
pub event: E,
|
pub event: E,
|
||||||
}
|
}
|
||||||
|
@ -50,18 +50,18 @@ pub struct PacketEvent<E: Event + Packet> {
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
/// Mark an [Entity] as synced by the server.
|
/// Mark an [Entity] as synced by the server.
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Synced(Entity);
|
pub struct ServerEntity(Entity);
|
||||||
|
|
||||||
/// A plugin that manage the network [Connection]s.
|
/// A plugin that manage the network [Connection]s.
|
||||||
pub struct NetworkPlugin;
|
pub struct ClientPlugin;
|
||||||
|
|
||||||
impl NetworkPlugin {
|
impl ClientPlugin {
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
/// Handles a received [Packet] on the server.
|
/// Handles a received [Packet] on the server.
|
||||||
pub fn handle_packets(world: &mut World) {
|
pub fn handle_packets(world: &mut World) {
|
||||||
// Get all received packets
|
// Get all received packets
|
||||||
let mut packets = Vec::new();
|
let mut packets = Vec::new();
|
||||||
if let Some(connection) = world.get_resource::<Connection>() {
|
if let Some(connection) = world.get_resource::<ServerConnection>() {
|
||||||
while let Some(mut packet) = connection.0.recv() {
|
while let Some(mut packet) = connection.0.recv() {
|
||||||
if packet.len() < 8 {
|
if packet.len() < 8 {
|
||||||
println!("Invalid packet received: {:?}", packet);
|
println!("Invalid packet received: {:?}", packet);
|
||||||
|
@ -88,24 +88,24 @@ impl NetworkPlugin {
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
/// Remove [Connection] if it's disconnected.
|
/// Remove [Connection] if it's disconnected.
|
||||||
pub fn remove_disconnected(mut commands: Commands, connection: Option<Res<Connection>>) {
|
pub fn remove_disconnected(mut commands: Commands, connection: Option<Res<ServerConnection>>) {
|
||||||
if let Some(connection) = connection {
|
if let Some(connection) = connection {
|
||||||
if connection.0.closed() {
|
if connection.0.closed() {
|
||||||
commands.remove_resource::<Connection>();
|
commands.remove_resource::<ServerConnection>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
/// Removes [ServerEntity] when disconnected.
|
/// Removes [ServerEntity] when disconnected.
|
||||||
fn remove_synced(mut commands: Commands, entities: Query<Entity, With<Synced>>) {
|
fn remove_synced(mut commands: Commands, entities: Query<Entity, With<ServerEntity>>) {
|
||||||
for entity in entities.iter() {
|
for entity in entities.iter() {
|
||||||
commands.entity(entity).despawn();
|
commands.entity(entity).despawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for NetworkPlugin {
|
impl Plugin for ClientPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.insert_resource(HandlerManager(Arc::new(HashMap::new())));
|
app.insert_resource(HandlerManager(Arc::new(HashMap::new())));
|
||||||
app.add_system(Self::handle_packets);
|
app.add_system(Self::handle_packets);
|
||||||
|
@ -117,19 +117,19 @@ impl Plugin for NetworkPlugin {
|
||||||
match bincode::deserialize::<Entity>(&data) {
|
match bincode::deserialize::<Entity>(&data) {
|
||||||
Ok(entity) => {
|
Ok(entity) => {
|
||||||
if let Some((local_entity, _)) = world
|
if let Some((local_entity, _)) = world
|
||||||
.query::<(Entity, &Synced)>()
|
.query::<(Entity, &ServerEntity)>()
|
||||||
.iter(world)
|
.iter(world)
|
||||||
.find(|(_, server_entity)| server_entity.0 == entity)
|
.find(|(_, server_entity)| server_entity.0 == entity)
|
||||||
{
|
{
|
||||||
world.despawn(local_entity);
|
world.despawn(local_entity);
|
||||||
} else {
|
} else {
|
||||||
world.spawn(Synced(entity));
|
world.spawn(ServerEntity(entity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => println!("Failed to deserialize packet: {}", type_name::<Entity>()),
|
Err(_) => println!("Failed to deserialize packet: {}", type_name::<Entity>()),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.add_system(Self::remove_synced.run_if(resource_removed::<Connection>()));
|
app.add_system(Self::remove_synced.run_if(resource_removed::<ServerConnection>()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,9 +162,9 @@ impl NetworkExt for App {
|
||||||
|
|
||||||
#[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::<PacketEvent<E>>()
|
self.add_event::<FromServer<E>>()
|
||||||
.add_packet_handler::<E, _>(|data, world| match bincode::deserialize::<E>(&data) {
|
.add_packet_handler::<E, _>(|data, world| match bincode::deserialize::<E>(&data) {
|
||||||
Ok(event) => world.send_event(PacketEvent { event }),
|
Ok(event) => world.send_event(FromServer { event }),
|
||||||
Err(_) => println!("Failed to deserialize packet: {}", type_name::<E>()),
|
Err(_) => println!("Failed to deserialize packet: {}", type_name::<E>()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ 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::<E>().add_system(
|
self.add_event::<E>().add_system(
|
||||||
|mut events: EventReader<E>, connection: Option<Res<Connection>>| {
|
|mut events: EventReader<E>, connection: Option<Res<ServerConnection>>| {
|
||||||
if let Some(connection) = connection {
|
if let Some(connection) = connection {
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
connection.send(event);
|
connection.send(event);
|
||||||
|
@ -188,7 +188,7 @@ impl NetworkExt for App {
|
||||||
match bincode::deserialize::<(Entity, C)>(&data) {
|
match bincode::deserialize::<(Entity, C)>(&data) {
|
||||||
Ok((entity, component)) => {
|
Ok((entity, component)) => {
|
||||||
if let Some((local_entity, _)) = world
|
if let Some((local_entity, _)) = world
|
||||||
.query::<(Entity, &Synced)>()
|
.query::<(Entity, &ServerEntity)>()
|
||||||
.iter(world)
|
.iter(world)
|
||||||
.find(|(_, server_entity)| server_entity.0 == entity)
|
.find(|(_, server_entity)| server_entity.0 == entity)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +213,7 @@ impl NetworkExt for App {
|
||||||
|data, world| match bincode::deserialize::<(Entity, PhantomData<C>)>(&data) {
|
|data, world| match bincode::deserialize::<(Entity, PhantomData<C>)>(&data) {
|
||||||
Ok((entity, _)) => {
|
Ok((entity, _)) => {
|
||||||
if let Some((local_entity, _)) = world
|
if let Some((local_entity, _)) = world
|
||||||
.query::<(Entity, &Synced)>()
|
.query::<(Entity, &ServerEntity)>()
|
||||||
.iter(world)
|
.iter(world)
|
||||||
.find(|(_, server_entity)| server_entity.0 == entity)
|
.find(|(_, server_entity)| server_entity.0 == entity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,11 +10,14 @@ use ::{
|
||||||
|
|
||||||
/// A trait for a handler function.
|
/// A trait for a handler function.
|
||||||
pub trait PacketHandlerFn:
|
pub trait PacketHandlerFn:
|
||||||
Fn(Entity, Connection, Vec<u8>, &mut World) + Send + Sync + 'static
|
Fn(Entity, ClientConnection, Vec<u8>, &mut World) + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Fn(Entity, Connection, Vec<u8>, &mut World) + Send + Sync + 'static> PacketHandlerFn for T {}
|
impl<T: Fn(Entity, ClientConnection, Vec<u8>, &mut World) + Send + Sync + 'static> PacketHandlerFn
|
||||||
|
for T
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// A function that handle a received [Packet]s.
|
/// A function that handle a received [Packet]s.
|
||||||
type PacketHandler = Box<dyn PacketHandlerFn>;
|
type PacketHandler = Box<dyn PacketHandlerFn>;
|
||||||
|
@ -36,9 +39,9 @@ impl Listener {
|
||||||
|
|
||||||
/// A [Connection] to a remote client.
|
/// A [Connection] to a remote client.
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Connection(Arc<tcp::Connection>);
|
pub struct ClientConnection(Arc<tcp::Connection>);
|
||||||
|
|
||||||
impl Connection {
|
impl ClientConnection {
|
||||||
/// Sends a packet through this connection.
|
/// Sends a packet through this connection.
|
||||||
pub fn send<P: Packet>(&self, packet: &P) {
|
pub fn send<P: Packet>(&self, packet: &P) {
|
||||||
let mut data = bincode::serialize(packet).expect("Failed to serialize packet");
|
let mut data = bincode::serialize(packet).expect("Failed to serialize packet");
|
||||||
|
@ -49,19 +52,19 @@ impl Connection {
|
||||||
|
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
/// An event that comes from a client.
|
/// An event that comes from a client.
|
||||||
pub struct PacketEvent<E: Event + Packet> {
|
pub struct FromClient<E: Event + Packet> {
|
||||||
/// The entity of the [Connection] that sent the event.
|
/// The entity of the [Connection] that sent the event.
|
||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
|
|
||||||
/// The [Connection] that sent the event.
|
/// The [Connection] that sent the event.
|
||||||
pub connection: Connection,
|
pub connection: ClientConnection,
|
||||||
|
|
||||||
/// The event.
|
/// The event.
|
||||||
pub event: E,
|
pub event: E,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
impl<E: Event + Packet> Deref for PacketEvent<E> {
|
impl<E: Event + Packet> Deref for FromClient<E> {
|
||||||
type Target = E;
|
type Target = E;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -75,14 +78,14 @@ impl<E: Event + Packet> Deref for PacketEvent<E> {
|
||||||
pub struct Synced;
|
pub struct Synced;
|
||||||
|
|
||||||
/// A plugin that manage the network [Connection]s.
|
/// A plugin that manage the network [Connection]s.
|
||||||
pub struct NetworkPlugin;
|
pub struct ServerPlugin;
|
||||||
|
|
||||||
impl NetworkPlugin {
|
impl ServerPlugin {
|
||||||
/// Accept new [Connection]s.
|
/// Accept new [Connection]s.
|
||||||
fn accept_connections(mut commands: Commands, listener: Option<Res<Listener>>) {
|
fn accept_connections(mut commands: Commands, listener: Option<Res<Listener>>) {
|
||||||
if let Some(listener) = listener {
|
if let Some(listener) = listener {
|
||||||
if let Some(connection) = listener.0.accept() {
|
if let Some(connection) = listener.0.accept() {
|
||||||
commands.spawn(Connection(Arc::new(connection)));
|
commands.spawn(ClientConnection(Arc::new(connection)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +94,7 @@ impl NetworkPlugin {
|
||||||
fn handle_packets(world: &mut World) {
|
fn handle_packets(world: &mut World) {
|
||||||
// Get all received packets
|
// Get all received packets
|
||||||
let mut packets = Vec::new();
|
let mut packets = Vec::new();
|
||||||
for (entity, connection) in world.query::<(Entity, &Connection)>().iter(world) {
|
for (entity, connection) in world.query::<(Entity, &ClientConnection)>().iter(world) {
|
||||||
while let Some(mut packet) = connection.0.recv() {
|
while let Some(mut packet) = connection.0.recv() {
|
||||||
if packet.len() < 8 {
|
if packet.len() < 8 {
|
||||||
println!("Invalid packet received: {:?}", packet);
|
println!("Invalid packet received: {:?}", packet);
|
||||||
|
@ -100,7 +103,7 @@ impl NetworkPlugin {
|
||||||
let packet_id = u64::from_be_bytes(id_buffer.try_into().unwrap());
|
let packet_id = u64::from_be_bytes(id_buffer.try_into().unwrap());
|
||||||
packets.push((
|
packets.push((
|
||||||
entity,
|
entity,
|
||||||
Connection(Arc::clone(&connection.0)),
|
ClientConnection(Arc::clone(&connection.0)),
|
||||||
packet_id,
|
packet_id,
|
||||||
packet,
|
packet,
|
||||||
));
|
));
|
||||||
|
@ -120,17 +123,23 @@ impl NetworkPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove disconnected [Connection]s.
|
/// Remove disconnected [Connection]s.
|
||||||
fn remove_disconnected(mut commands: Commands, connections: Query<(Entity, &Connection)>) {
|
fn remove_disconnected(
|
||||||
|
mut commands: Commands,
|
||||||
|
connections: Query<(Entity, &ClientConnection)>,
|
||||||
|
) {
|
||||||
for (entity, connection) in connections.iter() {
|
for (entity, connection) in connections.iter() {
|
||||||
if connection.0.closed() {
|
if connection.0.closed() {
|
||||||
commands.entity(entity).remove::<Connection>();
|
commands.entity(entity).remove::<ClientConnection>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
/// Send to clients the [Synced] entity that has been added to the server.
|
/// Send to clients the [Synced] entity that has been added to the server.
|
||||||
fn send_added(added_entities: Query<Entity, Added<Synced>>, connections: Query<&Connection>) {
|
fn send_added(
|
||||||
|
added_entities: Query<Entity, Added<Synced>>,
|
||||||
|
connections: Query<&ClientConnection>,
|
||||||
|
) {
|
||||||
for entity in added_entities.iter() {
|
for entity in added_entities.iter() {
|
||||||
for connection in connections.iter() {
|
for connection in connections.iter() {
|
||||||
connection.send(&entity);
|
connection.send(&entity);
|
||||||
|
@ -142,7 +151,7 @@ impl NetworkPlugin {
|
||||||
/// Send [Synced] entities to new clients.
|
/// Send [Synced] entities to new clients.
|
||||||
fn send_synced(
|
fn send_synced(
|
||||||
synced_entities: Query<Entity, With<Synced>>,
|
synced_entities: Query<Entity, With<Synced>>,
|
||||||
new_connections: Query<&Connection, Added<Connection>>,
|
new_connections: Query<&ClientConnection, Added<ClientConnection>>,
|
||||||
) {
|
) {
|
||||||
for entity in synced_entities.iter() {
|
for entity in synced_entities.iter() {
|
||||||
for connection in new_connections.iter() {
|
for connection in new_connections.iter() {
|
||||||
|
@ -155,7 +164,7 @@ impl NetworkPlugin {
|
||||||
/// Send to clients the [Synced] entity that has been removed.
|
/// Send to clients the [Synced] entity that has been removed.
|
||||||
fn send_removed(
|
fn send_removed(
|
||||||
mut removed_entities: RemovedComponents<Synced>,
|
mut removed_entities: RemovedComponents<Synced>,
|
||||||
connections: Query<&Connection>,
|
connections: Query<&ClientConnection>,
|
||||||
) {
|
) {
|
||||||
for entity in removed_entities.iter() {
|
for entity in removed_entities.iter() {
|
||||||
for connection in connections.iter() {
|
for connection in connections.iter() {
|
||||||
|
@ -165,7 +174,7 @@ impl NetworkPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for NetworkPlugin {
|
impl Plugin for ServerPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.insert_resource(HandlerManager(Arc::new(HashMap::new())));
|
app.insert_resource(HandlerManager(Arc::new(HashMap::new())));
|
||||||
app.add_system(Self::handle_packets);
|
app.add_system(Self::handle_packets);
|
||||||
|
@ -210,7 +219,7 @@ impl NetworkExt for App {
|
||||||
#[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::<E>().add_system(
|
self.add_event::<E>().add_system(
|
||||||
|mut events: EventReader<E>, connections: Query<&Connection>| {
|
|mut events: EventReader<E>, connections: Query<&ClientConnection>| {
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
for connection in connections.iter() {
|
for connection in connections.iter() {
|
||||||
connection.send(event);
|
connection.send(event);
|
||||||
|
@ -222,10 +231,10 @@ 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::<PacketEvent<E>>()
|
self.add_event::<FromClient<E>>()
|
||||||
.add_packet_handler::<E, _>(
|
.add_packet_handler::<E, _>(
|
||||||
|entity, connection, data, world| match bincode::deserialize::<E>(&data) {
|
|entity, connection, data, world| match bincode::deserialize::<E>(&data) {
|
||||||
Ok(event) => world.send_event(PacketEvent {
|
Ok(event) => world.send_event(FromClient {
|
||||||
entity,
|
entity,
|
||||||
connection,
|
connection,
|
||||||
event,
|
event,
|
||||||
|
@ -239,7 +248,7 @@ impl NetworkExt for App {
|
||||||
fn sync_component<C: Component + DeserializeOwned + Serialize + Clone>(&mut self) -> &mut Self {
|
fn sync_component<C: Component + DeserializeOwned + Serialize + Clone>(&mut self) -> &mut Self {
|
||||||
let update_components =
|
let update_components =
|
||||||
|changed_components: Query<(Entity, &C), (Changed<C>, With<Synced>)>,
|
|changed_components: Query<(Entity, &C), (Changed<C>, With<Synced>)>,
|
||||||
connections: Query<&Connection>| {
|
connections: Query<&ClientConnection>| {
|
||||||
for (entity, component) in changed_components.iter() {
|
for (entity, component) in changed_components.iter() {
|
||||||
for connection in connections.iter() {
|
for connection in connections.iter() {
|
||||||
connection.send(&(entity, component.clone()));
|
connection.send(&(entity, component.clone()));
|
||||||
|
@ -248,26 +257,27 @@ impl NetworkExt for App {
|
||||||
};
|
};
|
||||||
let send_components =
|
let send_components =
|
||||||
|components: Query<(Entity, &C), With<Synced>>,
|
|components: Query<(Entity, &C), With<Synced>>,
|
||||||
new_connections: Query<&Connection, Added<Connection>>| {
|
new_connections: Query<&ClientConnection, Added<ClientConnection>>| {
|
||||||
for (entity, component) in components.iter() {
|
for (entity, component) in components.iter() {
|
||||||
for connection in new_connections.iter() {
|
for connection in new_connections.iter() {
|
||||||
connection.send(&(entity, component.clone()));
|
connection.send(&(entity, component.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let remove_components = |mut removed_components: RemovedComponents<C>,
|
let remove_components =
|
||||||
synced_entities: Query<Entity, With<Synced>>,
|
|mut removed_components: RemovedComponents<C>,
|
||||||
connections: Query<&Connection>| {
|
synced_entities: Query<Entity, With<Synced>>,
|
||||||
for entity in removed_components.iter() {
|
connections: Query<&ClientConnection>| {
|
||||||
if synced_entities.contains(entity) {
|
for entity in removed_components.iter() {
|
||||||
for connection in connections.iter() {
|
if synced_entities.contains(entity) {
|
||||||
connection.send(&(entity, PhantomData::<C>));
|
for connection in connections.iter() {
|
||||||
|
connection.send(&(entity, PhantomData::<C>));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
self.add_system(update_components.after(ServerPlugin::send_added))
|
||||||
self.add_system(update_components.after(NetworkPlugin::send_added))
|
.add_system(send_components.after(ServerPlugin::send_synced))
|
||||||
.add_system(send_components.after(NetworkPlugin::send_synced))
|
|
||||||
.add_system(remove_components.after(update_components))
|
.add_system(remove_components.after(update_components))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue