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) => {
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,
pos,
vel,
ori,
action_state,
} => {
if let Some(entity) = self.state.ecs().entity_from_uid(entity) {
self.state.write_component(entity, pos);
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);
}
self.state.write_component(entity, action_state);
}
}
ServerMsg::TerrainChunkUpdate { key, chunk } => {

View File

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

View File

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

View File

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

View File

@ -677,23 +677,38 @@ impl Server {
// Save player metadata (for example the username).
state.write_component(entity, player);
// Sync physics
// Sync physics of all entities
for (&uid, &pos, vel, ori, action_state) in (
&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::Ori>().maybe(),
state.ecs().read_storage::<comp::ActionState>().maybe(),
)
.join()
{
client.notify(ServerMsg::EntityPhysics {
client.notify(ServerMsg::EntityPos {
entity: uid.into(),
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.
@ -794,28 +809,17 @@ impl Server {
}
// Sync physics
for (entity, &uid, &pos, vel, ori, action_state, force_update) in (
for (entity, &uid, &pos, force_update) in (
&ecs.entities(),
&ecs.read_storage::<Uid>(),
&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(),
)
.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 in_vd_and_changed = |entity| {
let in_vd = |entity| {
if let (Some(client_pos), Some(client_vd)) = (
ecs.read_storage::<comp::Pos>().get(entity),
ecs.read_storage::<comp::Player>()
@ -858,27 +862,71 @@ impl Server {
.get(entity)
.map(|&l| l != *client_pos)
.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_vel.insert(entity, comp::Last(*client_vel));
let _ = last_ori.insert(entity, comp::Last(*client_ori));
let _ = last_action_state.insert(entity, comp::Last(*client_action_state));
let msg = ServerMsg::EntityPos {
entity: uid.into(),
pos: *client_pos,
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd_and_changed),
None => clients.notify_ingame_if_except(entity, msg, in_vd_and_changed),
Some(_) => clients.notify_ingame_if(msg, in_vd),
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),
}
}
}