use crate::Message;
use crate::multi::MultiMessageSender;
use crate::prelude::{MessageReceiver, MessageSender};
use crate::registry::MessageRegistration;
use crate::send::Priority;
use crate::send_trigger::EventSender;
use crate::trigger::TriggerRegistration;
use bevy_ecs::entity::EntitySet;
use bevy_ecs::query::QueryFilter;
use bevy_ecs::{
error::Result,
event::Event,
relationship::RelationshipTarget,
system::{Res, SystemParam},
};
use lightyear_connection::client::PeerMetadata;
use lightyear_connection::client_of::ClientOf;
use lightyear_connection::direction::NetworkDirection;
use lightyear_connection::network_target::NetworkTarget;
use lightyear_link::prelude::Server;
use lightyear_serde::entity_map::SendEntityMap;
use lightyear_transport::channel::Channel;
use tracing::error;
#[derive(SystemParam)]
pub struct ServerMultiMessageSender<'w, 's, F: QueryFilter + 'static = ()> {
sender: MultiMessageSender<'w, 's, F>,
metadata: Res<'w, PeerMetadata>,
}
impl<'w, 's, F: QueryFilter> ServerMultiMessageSender<'w, 's, F> {
pub fn send<M: Message, C: Channel>(
&mut self,
message: &M,
server: &Server,
target: &NetworkTarget,
) -> Result {
self.send_with_priority::<M, C>(message, server, target, 1.0)
}
pub fn send_with_priority<M: Message, C: Channel>(
&mut self,
message: &M,
server: &Server,
target: &NetworkTarget,
priority: Priority,
) -> Result {
if !self.sender.registry.is_map_entities::<M>()? {
self.sender.registry.serialize::<M>(
message,
&mut self.sender.writer,
&mut SendEntityMap::default(),
)?;
let bytes = self.sender.writer.split();
target.apply_targets(
server.collection().iter().copied(),
&self.metadata.mapping,
&mut |sender| {
if let Ok((_, transport)) = self.sender.query.get(sender) {
transport
.send_with_priority::<C>(bytes.clone(), priority)
.inspect_err(|e| error!("Failed to send message: {e}"))
.ok();
}
},
);
} else {
target.apply_targets(
server.collection().iter().copied(),
&self.metadata.mapping,
&mut |sender| {
if let Ok((_, transport)) = self.sender.query.get(sender) {
self.sender
.registry
.serialize::<M>(
message,
&mut self.sender.writer,
&mut SendEntityMap::default(),
)
.unwrap();
let bytes = self.sender.writer.split();
transport
.send_with_priority::<C>(bytes.clone(), priority)
.inspect_err(|e| error!("Failed to send message: {e}"))
.ok();
}
},
);
}
Ok(())
}
pub fn send_to_entities<M: Message, C: Channel>(
&mut self,
message: &M,
target: impl EntitySet,
) -> Result {
self.send_to_entities_with_priority::<M, C>(message, target, 1.0)
}
pub fn send_to_entities_with_priority<M: Message, C: Channel>(
&mut self,
message: &M,
target: impl EntitySet,
priority: Priority,
) -> Result {
self.sender
.send_with_priority::<M, C>(message, target, priority)
}
}
impl<M: Message> MessageRegistration<'_, M> {
pub(crate) fn add_server_direction(&mut self, direction: NetworkDirection) {
match direction {
NetworkDirection::ClientToServer => {
self.app
.register_required_components::<ClientOf, MessageReceiver<M>>();
}
NetworkDirection::ServerToClient => {
self.app
.register_required_components::<ClientOf, MessageSender<M>>();
}
NetworkDirection::Bidirectional => {
self.add_server_direction(NetworkDirection::ClientToServer);
self.add_server_direction(NetworkDirection::ServerToClient);
}
}
}
}
impl<M: Event> TriggerRegistration<'_, M> {
pub(crate) fn add_server_direction(&mut self, direction: NetworkDirection) {
match direction {
NetworkDirection::ClientToServer => {
}
NetworkDirection::ServerToClient => {
self.app
.register_required_components::<ClientOf, EventSender<M>>();
}
NetworkDirection::Bidirectional => {
self.add_server_direction(NetworkDirection::ClientToServer);
self.add_server_direction(NetworkDirection::ServerToClient);
}
}
}
}