Skip to content

Commit

Permalink
Merge pull request #91 from AnonymousBit0111/feature/ticking_system
Browse files Browse the repository at this point in the history
added ticking system
  • Loading branch information
Sweattypalms authored Oct 26, 2024
2 parents 353370b + 0067cc9 commit 9e32128
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/bin/src/packet_handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod handshake;
mod login_process;
mod transform;
mod transform;
mod tick_handler;
39 changes: 39 additions & 0 deletions src/bin/src/packet_handlers/tick_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::sync::Arc;

use ferrumc_macros::event_handler;
use ferrumc_net::connection::ConnectionState;
use ferrumc_net::connection::StreamWriter;
use ferrumc_net::errors::NetError;
use ferrumc_net::packets::outgoing::update_time::TickEvent;
use ferrumc_net::packets::outgoing::update_time::UpdateTimePacket;
use ferrumc_net::GlobalState;
use ferrumc_net_codec::encode::NetEncodeOpts;
use tracing::error;

#[event_handler]
async fn handle_tick(event: TickEvent, state: GlobalState) -> Result<TickEvent, NetError> {
// info!("Tick {} ", event.tick);
// TODO: Handle tick in terms of game logic here
// this should call a function in world which handles the world state and calls the appropriate events which send their respective packets

///////

let packet = Arc::new(UpdateTimePacket::new(event.tick, event.tick % 24000));

let query = state
.universe
.query::<(&mut StreamWriter, &ConnectionState)>();

for (mut writer, connection_state) in query {
if let ConnectionState::Play = *connection_state {
if let Err(e) = writer
.send_packet(packet.as_ref(), &NetEncodeOpts::WithLength)
.await
{
error!("Error sending update_time packet: {}", e);
}
}
}

Ok(event)
}
5 changes: 4 additions & 1 deletion src/bin/src/systems/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use async_trait::async_trait;
use crate::systems::keep_alive_system::KeepAliveSystem;
use crate::systems::tcp_listener_system::TcpListenerSystem;

use super::ticking_system::TickingSystem;

#[async_trait]
pub trait System: Send + Sync {
async fn start(&self, state: GlobalState);
Expand All @@ -15,7 +17,8 @@ pub trait System: Send + Sync {

pub static ALL_SYSTEMS: &[&dyn System] = &[
&TcpListenerSystem,
&KeepAliveSystem
&KeepAliveSystem,
&TickingSystem
];

pub async fn start_all_systems(state: GlobalState) -> NetResult<()> {
Expand Down
3 changes: 2 additions & 1 deletion src/bin/src/systems/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub(crate) mod definition;

mod tcp_listener_system;
mod keep_alive_system;
mod keep_alive_system;
mod ticking_system;
48 changes: 48 additions & 0 deletions src/bin/src/systems/ticking_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use crate::systems::definition::System;
use async_trait::async_trait;
use ferrumc_events::infrastructure::Event;
use ferrumc_net::packets::outgoing::update_time::TickEvent;
use ferrumc_net::GlobalState;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use tokio::time::Instant;
use tracing::{debug, info};

pub struct TickingSystem;

static KILLED: AtomicBool = AtomicBool::new(false);

#[async_trait]
impl System for TickingSystem {
async fn start(&self, state: GlobalState) {
// TODO game time must be loaded from a file
let mut tick = 0;
while !KILLED.load(Ordering::Relaxed) {
let required_end = Instant::now() + Duration::from_millis(50);
// TODO handle error
let res = TickEvent::trigger(TickEvent::new(tick), state.clone()).await;

if res.is_err() {
debug!("error : {:?}", res);
}
let now = Instant::now();
if required_end > now {
tokio::time::sleep(required_end - now).await;
} else {
let time_debt = now - required_end;
info!("running behind! by : {}ms", time_debt.as_millis());
}

tick += 1;
}
}

async fn stop(&self, _state: GlobalState) {
tracing::debug!("Stopping ticking system...");
KILLED.store(true, Ordering::Relaxed);
}

fn name(&self) -> &'static str {
"keep_alive"
}
}
3 changes: 2 additions & 1 deletion src/lib/net/src/packets/outgoing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ pub mod login_play;
pub mod set_default_spawn_position;
pub mod synchronize_player_position;
pub mod keep_alive;
pub mod game_event;
pub mod game_event;
pub mod update_time;
31 changes: 31 additions & 0 deletions src/lib/net/src/packets/outgoing/update_time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use ferrumc_macros::Event;
use ferrumc_macros::{packet, NetEncode};
use std::io::Write;
use tokio::io::AsyncWriteExt;

#[derive(NetEncode)]
#[packet(packet_id = 0x64)]
pub struct UpdateTimePacket {
pub world_age: i64,
pub time_of_day: i64,
}

impl UpdateTimePacket {
pub fn new(world_age: i64, time_of_day: i64) -> UpdateTimePacket {
Self {
world_age,
time_of_day,
}
}
}

#[derive(Event, Clone, Copy)]
pub struct TickEvent {
pub tick: i64,
}

impl TickEvent {
pub fn new(tick: i64) -> Self {
Self { tick }
}
}

0 comments on commit 9e32128

Please sign in to comment.