Skip to content

Commit

Permalink
feat: Hyperion is now a module (#736)
Browse files Browse the repository at this point in the history
- allows for easier testing of ECS
  • Loading branch information
andrewgazelka authored Dec 17, 2024
1 parent d2ac22e commit 92be6bc
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 54 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/hyperion/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Defined the [`Global`] struct which is used to store global data which defines a [`crate::Hyperion`]
//! Defined the [`Global`] struct which is used to store global data which defines a [`crate::HyperionCore`]
use std::{
sync::{Arc, atomic::AtomicUsize},
time::Duration,
Expand Down
99 changes: 52 additions & 47 deletions crates/hyperion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ use std::{
cell::RefCell,
fmt::Debug,
io::Write,
net::ToSocketAddrs,
net::{SocketAddr, ToSocketAddrs},
sync::{Arc, atomic::AtomicBool},
};

use anyhow::{Context, bail};
use derive_more::{Deref, DerefMut};
use anyhow::Context;
use derive_more::{Constructor, Deref, DerefMut};
use egress::EgressModule;
use flecs_ecs::prelude::*;
pub use glam;
use glam::IVec2;
use glam::{I16Vec2, IVec2};
use ingress::IngressModule;
#[cfg(unix)]
use libc::{RLIMIT_NOFILE, getrlimit, setrlimit};
Expand Down Expand Up @@ -69,7 +69,6 @@ use crate::{
mod common;
pub use common::*;
use hyperion_crafting::CraftingRegistry;
use system_order::SystemOrderModule;
pub use valence_ident;

use crate::{
Expand Down Expand Up @@ -142,27 +141,55 @@ pub fn adjust_file_descriptor_limits(recommended_min: u64) -> std::io::Result<()
Ok(())
}

/// The central [`Hyperion`] struct which owns and manages the entire server.
pub struct Hyperion;
#[derive(Component, Debug, Clone, PartialEq, Eq, Hash, Constructor)]
pub struct Address(SocketAddr);

#[derive(Component)]
pub struct AddressModule;

impl Module for AddressModule {
fn module(world: &World) {
world.component::<Address>();
}
}

/// The central [`HyperionCore`] struct which owns and manages the entire server.
#[derive(Component)]
pub struct HyperionCore;

#[derive(Component)]
struct Shutdown {
value: Arc<AtomicBool>,
}

impl Hyperion {
/// Initializes the server.
pub fn init(address: impl ToSocketAddrs + Send + Sync + 'static) -> anyhow::Result<()> {
Self::init_with(address, |_| {})
impl Module for HyperionCore {
fn module(world: &World) {
let address = world.get::<&Address>(|address| address.0);
Self::init_with(world, address).unwrap();
}
}

impl HyperionCore {
/// Initializes the server with a custom handler.
pub fn init_with(
fn init_with(
world: &World,
address: impl ToSocketAddrs + Send + Sync + 'static,
handlers: impl FnOnce(&World) + Send + Sync + 'static,
) -> anyhow::Result<()> {
// Denormals (numbers very close to 0) are flushed to zero because doing computations on them
// is slow.

no_denormals::no_denormals(|| Self::init_with_helper(world, address))
}

/// Initialize the server.
fn init_with_helper(
world: &World,
address: impl ToSocketAddrs + Send + Sync + 'static,
) -> anyhow::Result<()> {
// 10k players * 2 file handles / player = 20,000. We can probably get away with 16,384 file handles
#[cfg(unix)]
adjust_file_descriptor_limits(32_768).context("failed to set file limits")?;

rayon::ThreadPoolBuilder::new()
.num_threads(NUM_THREADS)
.spawn_handler(|thread| {
Expand All @@ -179,38 +206,12 @@ impl Hyperion {
.build_global()
.context("failed to build thread pool")?;

no_denormals::no_denormals(|| Self::init_with_helper(address, handlers))
}

/// Initialize the server.
fn init_with_helper(
address: impl ToSocketAddrs + Send + Sync + 'static,
handlers: impl FnOnce(&World) + Send + Sync + 'static,
) -> anyhow::Result<()> {
// 10k players * 2 file handles / player = 20,000. We can probably get away with 16,384 file handles
#[cfg(unix)]
adjust_file_descriptor_limits(32_768).context("failed to set file limits")?;

let shared = Arc::new(Shared {
compression_threshold: CompressionThreshold(256),
compression_level: CompressionLvl::new(2)
.map_err(|_| anyhow::anyhow!("failed to create compression level"))?,
});

let world = World::new();

let world = Box::new(world);
let world: &World = Box::leak(world);

let mut app = world.app();

app.enable_rest(0)
.enable_stats(true)
.set_threads(i32::try_from(rayon::current_num_threads())?)
.set_target_fps(20.0);

world.set_threads(i32::try_from(rayon::current_num_threads())?);

let address = address
.to_socket_addrs()?
.next()
Expand All @@ -234,6 +235,8 @@ impl Hyperion {
// .bit("glowing", *EntityFlags::GLOWING)
// .bit("flying_with_elytra", *EntityFlags::FLYING_WITH_ELYTRA);

component!(world, I16Vec2 { x: i16, y: i16 });

component!(world, IVec2 { x: i32, y: i32 });
world.component::<PendingRemove>();

Expand Down Expand Up @@ -350,6 +353,15 @@ impl Hyperion {
world.set(runtime);
world.set(StreamLookup::default());

world.set_threads(i32::try_from(rayon::current_num_threads())?);

let mut app = world.app();

app.enable_rest(0)
.enable_stats(true)
.set_threads(i32::try_from(rayon::current_num_threads())?)
.set_target_fps(20.0);

world.import::<SimModule>();
world.import::<EgressModule>();
world.import::<IngressModule>();
Expand Down Expand Up @@ -377,14 +389,7 @@ impl Hyperion {

world.set(IgnMap::default());

handlers(world);

// must be init last
world.import::<SystemOrderModule>();

app.run();

bail!("app exited");
Ok(())
}
}

Expand Down
1 change: 1 addition & 0 deletions events/tag/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rayon = { workspace = true }
roaring = { workspace = true }
rustc-hash = { workspace = true }
spatial = { workspace = true }
system-order = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
tracing-tracy = { workspace = true }
Expand Down
22 changes: 16 additions & 6 deletions events/tag/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#![feature(stmt_expr_attributes)]
#![feature(exact_size_is_empty)]

use std::{collections::HashSet, net::ToSocketAddrs};
use std::{collections::HashSet, net::SocketAddr};

use flecs_ecs::prelude::*;
use hyperion::{
Hyperion,
Address, AddressModule, HyperionCore,
runtime::AsyncRuntime,
simulation::{Player, blocks::Blocks},
};
Expand All @@ -24,6 +24,7 @@ use hyperion::{
use hyperion_rank_tree::Team;
use module::{attack::AttackModule, level::LevelModule, regeneration::RegenerationModule};
use spatial::SpatialIndex;
use system_order::SystemOrderModule;
use tracing::debug;

use crate::{
Expand Down Expand Up @@ -157,10 +158,19 @@ impl Module for TagModule {
}
}

pub fn init_game(address: impl ToSocketAddrs + Send + Sync + 'static) -> anyhow::Result<()> {
Hyperion::init_with(address, |world| {
world.import::<TagModule>();
})?;
pub fn init_game(address: SocketAddr) -> anyhow::Result<()> {
let world = World::new();

world.import::<AddressModule>();
world.set(Address::new(address));

world.import::<HyperionCore>();
world.import::<TagModule>();

// must be init last
world.import::<SystemOrderModule>();

world.app().run();

Ok(())
}
3 changes: 3 additions & 0 deletions events/tag/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::net::SocketAddr;

use clap::Parser;
use tag::init_game;
use tracing_subscriber::{EnvFilter, Registry, layer::SubscriberExt};
Expand Down Expand Up @@ -42,6 +44,7 @@ fn main() {
let Args { ip, port } = Args::parse();

let address = format!("{ip}:{port}");
let address = address.parse::<SocketAddr>().unwrap();

init_game(address).unwrap();
}

0 comments on commit 92be6bc

Please sign in to comment.