Send different physics components individually

This commit is contained in:
timokoesters 2019-07-30 13:35:16 +02:00
parent 16b445c828
commit b695a63e98
5 changed files with 119 additions and 59 deletions

View File

@ -398,24 +398,27 @@ impl Client {
ServerMsg::EcsSync(sync_package) => { ServerMsg::EcsSync(sync_package) => {
self.state.ecs_mut().sync_with_package(sync_package) self.state.ecs_mut().sync_with_package(sync_package)
} }
ServerMsg::EntityPhysics { ServerMsg::EntityPos { entity, pos } => {
if let Some(entity) = self.state.ecs().entity_from_uid(entity) {
self.state.write_component(entity, pos);
}
}
ServerMsg::EntityVel { entity, vel } => {
if let Some(entity) = self.state.ecs().entity_from_uid(entity) {
self.state.write_component(entity, vel);
}
}
ServerMsg::EntityOri { entity, ori } => {
if let Some(entity) = self.state.ecs().entity_from_uid(entity) {
self.state.write_component(entity, ori);
}
}
ServerMsg::EntityActionState {
entity, entity,
pos,
vel,
ori,
action_state, action_state,
} => { } => {
if let Some(entity) = self.state.ecs().entity_from_uid(entity) { if let Some(entity) = self.state.ecs().entity_from_uid(entity) {
self.state.write_component(entity, pos); self.state.write_component(entity, action_state);
if let Some(v) = vel {
self.state.write_component(entity, v);
};
if let Some(o) = ori {
self.state.write_component(entity, o);
};
if let Some(a_s) = action_state {
self.state.write_component(entity, a_s);
}
} }
} }
ServerMsg::TerrainChunkUpdate { key, chunk } => { ServerMsg::TerrainChunkUpdate { key, chunk } => {

View File

@ -39,12 +39,21 @@ pub enum ServerMsg {
}, },
SetPlayerEntity(u64), SetPlayerEntity(u64),
EcsSync(sphynx::SyncPackage<EcsCompPacket, EcsResPacket>), EcsSync(sphynx::SyncPackage<EcsCompPacket, EcsResPacket>),
EntityPhysics { EntityPos {
entity: u64, entity: u64,
pos: comp::Pos, pos: comp::Pos,
vel: Option<comp::Vel>, },
ori: Option<comp::Ori>, EntityVel {
action_state: Option<comp::ActionState>, entity: u64,
vel: comp::Vel,
},
EntityOri {
entity: u64,
ori: comp::Ori,
},
EntityActionState {
entity: u64,
action_state: comp::ActionState,
}, },
TerrainChunkUpdate { TerrainChunkUpdate {
key: Vec2<i32>, key: Vec2<i32>,

View File

@ -190,7 +190,7 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
} }
// Try getting messages from the send channel. // Try getting messages from the send channel.
for _ in 0..100 { for _ in 0..1000 {
match send_rx.try_recv() { match send_rx.try_recv() {
Ok(send_msg) => { Ok(send_msg) => {
// Serialize message // Serialize message
@ -225,7 +225,7 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
} }
// Try sending bytes through the TCP stream. // Try sending bytes through the TCP stream.
for _ in 0..100 { for _ in 0..1000 {
match outgoing_chunks.pop_front() { match outgoing_chunks.pop_front() {
Some(mut chunk) => match stream.write(&chunk) { Some(mut chunk) => match stream.write(&chunk) {
Ok(n) if n == chunk.len() => {} Ok(n) if n == chunk.len() => {}
@ -249,7 +249,7 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
} }
// Try receiving bytes from the TCP stream. // Try receiving bytes from the TCP stream.
for _ in 0..100 { for _ in 0..1000 {
let mut buf = [0; 4096]; let mut buf = [0; 4096];
match stream.read(&mut buf) { match stream.read(&mut buf) {
@ -265,7 +265,7 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
} }
// Try turning bytes into messages. // Try turning bytes into messages.
for _ in 0..100 { for _ in 0..1000 {
match incoming_buf.get(0..9) { match incoming_buf.get(0..9) {
Some(len_bytes) => { Some(len_bytes) => {
let len = let len =

View File

@ -46,7 +46,7 @@ impl<'a> System<'a> for Sys {
Vec2::from(pos.0 - tgt_pos).normalized() Vec2::from(pos.0 - tgt_pos).normalized()
} else { } else {
Vec2::zero() Vec2::zero()
}; } * -10.0;
} }
_ => controller.move_dir = Vec2::zero(), _ => controller.move_dir = Vec2::zero(),
} }

View File

@ -677,23 +677,38 @@ impl Server {
// Save player metadata (for example the username). // Save player metadata (for example the username).
state.write_component(entity, player); state.write_component(entity, player);
// Sync physics // Sync physics of all entities
for (&uid, &pos, vel, ori, action_state) in ( for (&uid, &pos, vel, ori, action_state) in (
&state.ecs().read_storage::<Uid>(), &state.ecs().read_storage::<Uid>(),
&state.ecs().read_storage::<comp::Pos>(), &state.ecs().read_storage::<comp::Pos>(), // We assume all these entities have a position
state.ecs().read_storage::<comp::Vel>().maybe(), state.ecs().read_storage::<comp::Vel>().maybe(),
state.ecs().read_storage::<comp::Ori>().maybe(), state.ecs().read_storage::<comp::Ori>().maybe(),
state.ecs().read_storage::<comp::ActionState>().maybe(), state.ecs().read_storage::<comp::ActionState>().maybe(),
) )
.join() .join()
{ {
client.notify(ServerMsg::EntityPhysics { client.notify(ServerMsg::EntityPos {
entity: uid.into(), entity: uid.into(),
pos, pos,
vel: vel.copied(),
ori: ori.copied(),
action_state: action_state.copied(),
}); });
if let Some(vel) = vel.copied() {
client.notify(ServerMsg::EntityVel {
entity: uid.into(),
vel,
});
}
if let Some(ori) = ori.copied() {
client.notify(ServerMsg::EntityOri {
entity: uid.into(),
ori,
});
}
if let Some(action_state) = action_state.copied() {
client.notify(ServerMsg::EntityActionState {
entity: uid.into(),
action_state,
});
}
} }
// Tell the client its request was successful. // Tell the client its request was successful.
@ -794,28 +809,17 @@ impl Server {
} }
// Sync physics // Sync physics
for (entity, &uid, &pos, vel, ori, action_state, force_update) in ( for (entity, &uid, &pos, force_update) in (
&ecs.entities(), &ecs.entities(),
&ecs.read_storage::<Uid>(), &ecs.read_storage::<Uid>(),
&ecs.read_storage::<comp::Pos>(), &ecs.read_storage::<comp::Pos>(),
ecs.read_storage::<comp::Vel>().maybe(),
ecs.read_storage::<comp::Ori>().maybe(),
ecs.read_storage::<comp::ActionState>().maybe(),
ecs.read_storage::<comp::ForceUpdate>().maybe(), ecs.read_storage::<comp::ForceUpdate>().maybe(),
) )
.join() .join()
{ {
let msg = ServerMsg::EntityPhysics {
entity: uid.into(),
pos,
vel: vel.copied(),
ori: ori.copied(),
action_state: action_state.copied(),
};
let clients = &mut self.clients; let clients = &mut self.clients;
let in_vd_and_changed = |entity| { let in_vd = |entity| {
if let (Some(client_pos), Some(client_vd)) = ( if let (Some(client_pos), Some(client_vd)) = (
ecs.read_storage::<comp::Pos>().get(entity), ecs.read_storage::<comp::Pos>().get(entity),
ecs.read_storage::<comp::Player>() ecs.read_storage::<comp::Player>()
@ -858,27 +862,71 @@ impl Server {
.get(entity) .get(entity)
.map(|&l| l != *client_pos) .map(|&l| l != *client_pos)
.unwrap_or(true) .unwrap_or(true)
|| last_vel
.get(entity)
.map(|&l| l != *client_vel)
.unwrap_or(true)
|| last_ori
.get(entity)
.map(|&l| l != *client_ori)
.unwrap_or(true)
|| last_action_state
.get(entity)
.map(|&l| l != *client_action_state)
.unwrap_or(true)
{ {
let _ = last_pos.insert(entity, comp::Last(*client_pos)); let _ = last_pos.insert(entity, comp::Last(*client_pos));
let _ = last_vel.insert(entity, comp::Last(*client_vel));
let _ = last_ori.insert(entity, comp::Last(*client_ori)); let msg = ServerMsg::EntityPos {
let _ = last_action_state.insert(entity, comp::Last(*client_action_state)); entity: uid.into(),
pos: *client_pos,
};
match force_update { match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd_and_changed), Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd_and_changed), None => clients.notify_ingame_if_except(entity, msg, in_vd),
}
}
if last_vel
.get(entity)
.map(|&l| l != *client_vel)
.unwrap_or(true)
{
let _ = last_vel.insert(entity, comp::Last(*client_vel));
let msg = ServerMsg::EntityVel {
entity: uid.into(),
vel: *client_vel,
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd),
}
}
if last_ori
.get(entity)
.map(|&l| l != *client_ori)
.unwrap_or(true)
{
let _ = last_ori.insert(entity, comp::Last(*client_ori));
let msg = ServerMsg::EntityOri {
entity: uid.into(),
ori: *client_ori,
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd),
}
}
if last_action_state
.get(entity)
.map(|&l| l != *client_action_state)
.unwrap_or(true)
{
let _ = last_action_state.insert(entity, comp::Last(*client_action_state));
let msg = ServerMsg::EntityActionState {
entity: uid.into(),
action_state: *client_action_state,
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd),
} }
} }
} }