1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

az-physics tests pass 🎉

This commit is contained in:
Ubuntu 2023-01-30 17:58:47 +00:00
parent 284a5b645e
commit 8415aaccfe
5 changed files with 40 additions and 31 deletions

1
Cargo.lock generated
View file

@ -331,7 +331,6 @@ dependencies = [
"azalea-ecs-macros",
"bevy_app",
"bevy_ecs",
"futures",
"iyes_loopless",
"tokio",
]

View file

@ -445,7 +445,7 @@ impl Plugin for AzaleaPlugin {
app.add_event::<StartWalkEvent>()
.add_event::<StartSprintEvent>();
app.add_plugin(TickPlugin);
app.add_plugin(TickPlugin::default());
app.add_fixed_timestep_system_set(
"tick",
0,

View file

@ -9,6 +9,5 @@ version = "0.5.0"
azalea-ecs-macros = {path = "./azalea-ecs-macros", version = "^0.5.0"}
bevy_app = "0.9.1"
bevy_ecs = {version = "0.9.1", default-features = false}
futures = "0.3.25"
iyes_loopless = "0.9.1"
tokio = {version = "1.25.0", features = ["time"]}

View file

@ -8,13 +8,13 @@
//!
//! Changes:
//! - Add [`TickPlugin`], [`TickStage`] and [`AppTickExt`]
//! - Change the macros to use azalea_ecs instead of bevy_ecs
//! - Change the macros to use azalea/azalea_ecs instead of bevy/bevy_ecs
//! - Rename bevy_ecs::world::World to azalea_ecs::ecs::Ecs
//! - Re-export `bevy_app` in the `app` module.
use std::{
task::{Context, Poll},
time::Duration,
time::{Duration, Instant},
};
pub mod ecs {
@ -51,48 +51,57 @@ pub use bevy_ecs::{entity, event, ptr, query, schedule, storage};
use app::{App, CoreStage, Plugin};
use bevy_ecs::schedule::*;
use ecs::Ecs;
use futures::task::noop_waker_ref;
use tokio::time::Interval;
pub struct TickPlugin;
pub struct TickPlugin {
/// How often a tick should happen. 50 milliseconds by default. Set to 0 to
/// tick every update.
pub tick_interval: Duration,
}
impl Plugin for TickPlugin {
fn build(&self, app: &mut App) {
app.add_stage_before(
CoreStage::Update,
TickLabel,
TickStage::from_stage(SystemStage::parallel()),
TickStage {
interval: self.tick_interval,
next_tick: Instant::now(),
stage: Box::new(SystemStage::parallel()),
},
);
}
}
impl Default for TickPlugin {
fn default() -> Self {
Self {
tick_interval: Duration::from_millis(50),
}
}
}
#[derive(StageLabel)]
struct TickLabel;
/// A [`Stage`] that runs every 50 milliseconds.
pub struct TickStage {
pub interval: Interval,
pub interval: Duration,
pub next_tick: Instant,
stage: Box<dyn Stage>,
}
impl TickStage {
pub fn from_stage(stage: impl Stage) -> Self {
let mut game_tick_interval = tokio::time::interval(Duration::from_millis(50));
// TODO: Minecraft bursts up to 10 ticks and then skips, we should too
game_tick_interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Burst);
TickStage {
interval: game_tick_interval,
stage: Box::new(stage),
}
}
}
impl Stage for TickStage {
fn run(&mut self, ecs: &mut Ecs) {
// if the interval is 0, that means it runs every tick
println!("running tick stage maybe");
if self.interval.is_zero() {
println!("running tick stage");
self.stage.run(ecs);
return;
}
// keep calling run until it's caught up
while let Poll::Ready(_) = self
.interval
.poll_tick(&mut Context::from_waker(&noop_waker_ref()))
{
// TODO: Minecraft bursts up to 10 ticks and then skips, we should too (but
// check the source so we do it right)
while Instant::now() > self.next_tick {
self.next_tick += self.interval;
self.stage.run(ecs);
}
}

View file

@ -307,7 +307,7 @@ mod tests {
use super::*;
use azalea_core::{ChunkPos, ResourceLocation};
use azalea_ecs::app::App;
use azalea_ecs::{app::App, TickPlugin};
use azalea_world::{
entity::{EntityBundle, MinecraftEntityId},
Chunk, EntityPlugin, PartialWorld,
@ -319,10 +319,12 @@ mod tests {
/// You need an app to spawn entities in the world and do updates.
fn make_test_app() -> App {
let mut app = App::new();
app.add_fixed_timestep(Duration::from_secs(1), "tick")
.add_plugin(PhysicsPlugin)
.add_plugin(EntityPlugin)
.init_resource::<WorldContainer>();
app.add_plugin(TickPlugin {
tick_interval: Duration::ZERO,
})
.add_plugin(PhysicsPlugin)
.add_plugin(EntityPlugin)
.init_resource::<WorldContainer>();
app
}