use std::{time::Duration, sync::Arc};
use log::{error};
use rapier2d_f64::prelude::{PhysicsPipeline, RigidBodyHandle};
use starkingdoms_protocol::{ProtocolPlanet, PlanetType};
use tokio::{time::sleep, sync::RwLock};
use crate::{manager::{ClientHandlerMessage, ClientManager, PhysicsData}, SCALE};
pub async fn timer_main(mgr: ClientManager, physics_data: Arc<RwLock<PhysicsData>>, world_data: Arc<RwLock<Vec<RigidBodyHandle>>>) {
let mut pipeline = PhysicsPipeline::new();
loop {
sleep(Duration::from_millis(5)).await;
physics_data.write().await.tick(&mut pipeline);
for (_addr, client_thread) in mgr.handlers.read().await.iter() {
match client_thread.tx.send(ClientHandlerMessage::Tick).await {
Ok(_) => {
let player_handles = mgr.players.read().await.values().map(|s| {s.handle}).collect::<Vec<_>>();
let data = physics_data.read().await;
let mut translations = Vec::new();
let mut rotations = Vec::new();
for handle in player_handles {
let player_body = data.rigid_body_set.get(handle).unwrap();
translations.push(player_body.translation());
rotations.push(player_body.rotation().angle());
}
let usernames_raw = mgr.usernames.read().await;
let usernames = usernames_raw.values().collect::<Vec<_>>();
match client_thread.tx.send(ClientHandlerMessage::PlayersUpdate {
rotation: rotations,
usernames: usernames.into_iter().map(|s| s.clone()).collect(),
x: translations.clone().into_iter().map(|s| { s.x * SCALE}).collect(),
y: translations.into_iter().map(|s| { s.y * SCALE}).collect() }).await {
Ok(_) => (),
Err(e) => {
error!("unable to send position packet: {}", e);
}
};
let world = world_data.read().await;
let earth_handle = world.get(0).unwrap();
let earth_body = data.rigid_body_set.get(*earth_handle).unwrap();
//let earth_collider = data.collider_set.get(earth_body.colliders()[0]).unwrap();
let protocol_earth = ProtocolPlanet {
planet_type: PlanetType::Earth,
x: earth_body.translation().x * SCALE,
y: earth_body.translation().y * SCALE,
radius: 1000.0,
};
match client_thread.tx.send(ClientHandlerMessage::PlanetData { planets: vec![protocol_earth] }).await {
Ok(_) => (),
Err(e) => {
error!("unable to send earth packet: {}", e);
}
};
}
Err(e) => {
error!("unable to update a client thread: {}", e);
}
}
}
}
}