Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added broadcast_message_scoped to allow sending messages only to users with a specific entity in their scope #167

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions adapters/bevy/server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ impl<'w> Server<'w> {
self.server.broadcast_message::<C, M>(message);
}

pub fn broadcast_message_scoped<C: Channel, M: Message>(&mut self, entity: &Entity, message: &M) {
self.server.broadcast_message_scoped::<C, M>(entity, message);
}

pub fn receive_tick_buffer_messages(&mut self, tick: &Tick) -> TickBufferMessages {
self.server.receive_tick_buffer_messages(tick)
}
Expand Down
27 changes: 20 additions & 7 deletions server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,25 @@ impl<E: Copy + Eq + Hash + Send + Sync> Server<E> {
})
}

/// Sends a message to all connected users that contain the given entity in their scope using a given channel
pub fn broadcast_message_scoped<C: Channel, M: Message>(&mut self, entity: &E, message: &M) {
let cloned_message = M::clone_box(message);
self.broadcast_message_scoped_inner(entity, &ChannelKind::of::<C>(), cloned_message);
}

fn broadcast_message_scoped_inner(
&mut self,
entity: &E,
channel_kind: &ChannelKind,
message_box: Box<dyn Message>,
) {
self.user_keys().iter().for_each(|user_key| {
if self.entity_scope_map.get(user_key, entity) {
self.send_message_inner(user_key, channel_kind, message_box.clone())
}
})
}

pub fn receive_tick_buffer_messages(&mut self, tick: &Tick) -> TickBufferMessages {
let mut tick_buffer_messages = TickBufferMessages::new();
for (_user_address, connection) in self.user_connections.iter_mut() {
Expand Down Expand Up @@ -1281,13 +1300,7 @@ impl<E: Copy + Eq + Hash + Send + Sync> Server<E> {
let currently_in_scope =
connection.base.host_world_manager.host_has_entity(entity);

let should_be_in_scope = if let Some(in_scope) =
self.entity_scope_map.get(user_key, entity)
{
*in_scope
} else {
false
};
let should_be_in_scope = self.entity_scope_map.get(user_key, entity);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to take advantage of get returning just a bool instead of an option of a borrowed bool


if should_be_in_scope {
if !currently_in_scope {
Expand Down
9 changes: 7 additions & 2 deletions server/src/world/entity_scope_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ impl<E: Copy + Eq + Hash> EntityScopeMap<E> {
}
}

pub fn get(&self, user_key: &UserKey, entity: &E) -> Option<&bool> {
pub fn get(&self, user_key: &UserKey, entity: &E) -> bool {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this function to return a bool instead of an option of a borrowed bool.
Let me know if there is a use-case for this function returning None instead of just false.

let key = (*user_key, *entity);

self.main_map.get(&key)
self.main_map.get(&key).map(|k| *k).unwrap_or(false)
}

pub fn insert(&mut self, user_key: UserKey, entity: E, in_scope: bool) {
if self.main_map.contains_key(&(user_key, entity)) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in this check to see if the scope is just being updated rather than inserted.
If the user/entity key already existed in the main_map, then we should be able to assume that we just need to update main_map to the new boolean value

// Only need to update scope status
self.main_map.insert((user_key, entity), in_scope);
return;
}
self.entities_of_user
.entry(user_key)
.or_insert_with(|| HashSet::new());
Expand Down