Skip to content

Commit f56747d

Browse files
committed
cleaned up iterating over players in world/chunk
1 parent f93316d commit f56747d

File tree

8 files changed

+66
-20
lines changed

8 files changed

+66
-20
lines changed

server/src/player/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod player;
22
pub mod packet_handling;
33
pub mod attribute;
4-
pub mod sidebar;
4+
pub mod sidebar;
5+
pub mod player_iterator;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::{Player, PlayerExtension};
2+
use std::cell::UnsafeCell;
3+
use std::marker::PhantomData;
4+
use std::rc::Rc;
5+
6+
pub struct PlayerIterator<'a, I, P : PlayerExtension>
7+
where
8+
I: Iterator<Item = Rc<UnsafeCell<Player<P>>>>,
9+
{
10+
iter: I,
11+
_marker: PhantomData<&'a mut P>,
12+
}
13+
14+
impl<'a, I, P : PlayerExtension> PlayerIterator<'a, I, P>
15+
where
16+
I: Iterator<Item = Rc<UnsafeCell<Player<P>>>>,
17+
{
18+
pub fn new(iter: I) -> Self {
19+
Self {
20+
iter,
21+
_marker: PhantomData,
22+
}
23+
}
24+
}
25+
26+
impl<'a, I, P : PlayerExtension> Iterator for PlayerIterator<'a, I, P>
27+
where
28+
I: Iterator<Item = Rc<UnsafeCell<Player<P>>>>,
29+
{
30+
type Item = &'a mut Player<P>;
31+
32+
fn next(&mut self) -> Option<Self::Item> {
33+
self.iter.next().map(|rc| unsafe { &mut *rc.get() })
34+
}
35+
}

server/src/world/chunk/chunk.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ impl<W : WorldExtension> Chunk<W> {
161161
!self.entities.is_empty()
162162
}
163163

164+
pub fn players(&mut self) -> impl Iterator<Item = &mut Player<W::Player>> {
165+
self.players.values().map(|it| unsafe { &mut *it.get() })
166+
}
167+
164168
pub fn write_spawn_entities<P : PlayerExtension>(
165169
&self,
166170
player: &mut Player<P>

server/src/world/world.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,7 @@ impl<W: WorldExtension> World<W> {
247247
entity.tick()
248248
}
249249

250-
for player in self.players.iter_mut() {
251-
let player = unsafe { player.get().as_mut().unwrap() };
250+
for player in self.players_mut() {
252251
player.write_packet(&packet_destroy_entities);
253252
player.tick();
254253
}
@@ -291,6 +290,14 @@ impl<W: WorldExtension> World<W> {
291290
}
292291
}
293292
}
293+
294+
pub fn players(&self) -> impl Iterator<Item = &Player<W::Player>> {
295+
self.players.iter().map(|it| unsafe { &*it.get() })
296+
}
297+
298+
pub fn players_mut(&mut self) -> impl Iterator<Item = &mut Player<W::Player>> {
299+
self.players.iter().map(|it| unsafe { &mut *it.get() })
300+
}
294301
}
295302

296303
impl<W: WorldExtension> Deref for World<W> {

src/dungeon/dungeon.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ impl WorldExtension for Dungeon {
6666
let s = if seconds_remaining == 1 { "" } else { "s" };
6767
let str = format!("§aStarting in {} second{}.", seconds_remaining, s);
6868

69-
for player_rc in world.players.iter_mut() {
70-
let player = unsafe { &mut *player_rc.get() };
69+
// todo: global packet buffer for these global stuff
70+
for player in world.players_mut() {
7171
player.write_packet(&Chat {
7272
component: ChatComponent::new(str.clone()),
7373
chat_type: 0,
@@ -127,8 +127,7 @@ impl WorldExtension for Dungeon {
127127
}
128128

129129
if let Some(packet) = world.extension.map.get_packet() {
130-
for player_rc in world.players.iter_mut() {
131-
let player = unsafe { &mut *player_rc.get() };
130+
for player in world.players_mut() {
132131
player.write_packet(&packet)
133132
}
134133
}
@@ -195,7 +194,7 @@ impl WorldExtension for Dungeon {
195194
player.flush_packets()
196195
}
197196

198-
fn on_player_leave(world: &mut World<Self>, player: &mut Player<Self::Player>) {
197+
fn on_player_leave(_: &mut World<Self>, player: &mut Player<Self::Player>) {
199198
if let Some((room_rc, _)) = &player.current_room {
200199
let mut room = room_rc.borrow_mut();
201200
room.remove_player_ref(player.client_id)
@@ -210,8 +209,7 @@ impl Dungeon {
210209
}
211210

212211
pub fn start_dungeon(world: &mut World<Self>) {
213-
for player_rc in world.players.iter_mut() {
214-
let player = unsafe { &mut *player_rc.get() };
212+
for player in world.players_mut() {
215213
if let OpenContainer::Menu(_) = player.get_container() {
216214
player.open_container(OpenContainer::None)
217215
}
@@ -243,16 +241,14 @@ impl Dungeon {
243241
chat_type: 0,
244242
};
245243

246-
for player_rc in world.players.iter_mut() {
247-
let player = unsafe { &mut *player_rc.get() };
244+
for player in world.players_mut() {
248245
player.write_packet(&packet)
249246
}
250247

251248
if is_ready {
252249
let mut should_start = true;
253250

254-
for player_rc in world.players.iter() {
255-
let player = unsafe { &*player_rc.get() };
251+
for player in world.players_mut() {
256252
if !player.extension.is_ready {
257253
should_start = false
258254
}

src/dungeon/dungeon_player.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,7 @@ impl DungeonPlayer {
229229
// can't use one outside because of borrow checker
230230
let sidebar = &mut player.extension.sidebar;
231231

232-
for player_rc in world.players.iter() {
233-
let player = unsafe { &*player_rc.get() };
232+
for player in world.players() {
234233
let color = if player.extension.is_ready { 'a' } else { 'c' };
235234
sidebar.push(&format!("§{color}[M] §7{}", player.profile.username));
236235
}

src/dungeon/entities/npc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ impl EntityExtension<Dungeon> for InteractableNPC {
1818
return;
1919
}
2020

21-
let player: Option<&Player<DungeonPlayer>> = entity.world().players.iter()
22-
// todo custom iter for player to unwrap
23-
.map(|p| unsafe { &*p.get() })
21+
let player: Option<&Player<DungeonPlayer>> = entity
22+
.world()
23+
.players()
2424
.filter(|p| entity.position.distance(p.position) <= 5.0)
2525
.min_by(|a, b| {
2626
let dist_a = entity.position.distance(a.position);

src/dungeon/room/room.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ impl Room {
114114
self.segments.iter().flat_map(|seg| seg.neighbours.iter().flatten())
115115
}
116116

117+
pub fn players(&mut self) -> impl Iterator<Item = &mut Player<DungeonPlayer>> {
118+
self.players.values().map(|it| unsafe { &mut *it.get() })
119+
}
120+
117121
pub fn get_corner_pos(&self) -> IVec3 {
118122
Room::get_corner_pos_from(&self.segments, &self.rotation, &self.data)
119123
}
@@ -168,7 +172,7 @@ impl Room {
168172

169173
pub fn remove_player_ref(&mut self, client_id: ClientId) {
170174
debug_assert!(self.players.contains_key(&client_id), "player wasn't in the room");
171-
let segment = self.players.remove(&client_id).unwrap();
175+
self.players.remove(&client_id);
172176

173177
// if let Some(segment) = segment {
174178
// self.segments[segment].player_ref_count -= 1;

0 commit comments

Comments
 (0)