andrewgazelka / hyperion

Getting 10k players to PvP at once on a Minecraft server to break the Guinness World Record.
Other
109 stars 11 forks source link

do we really need three different lifetimes here? #311

Open github-actions[bot] opened 4 months ago

github-actions[bot] commented 4 months ago

https://github.com/andrewgazelka/hyperion/blob/35f8ce7e3689dc86cca046ae5f51cc9d45e3c5c4/crates/server/src/system/ingress.rs#L69


    ),
>;

#[derive(Event)]
pub struct AddPlayer {
    fd: Fd,
}

#[derive(Event)]
pub struct RemovePlayer {
    fd: Fd,
}

// todo: do we really need three different lifetimes here?
#[derive(Event)]
pub struct RecvData<'a, 'b, 'c> {
    fd: Fd,
    data: &'c [u8],
    scratch: &'b mut BumpScratch<'a>,
}

#[derive(Event)]
pub struct SendData {
    fd: Fd,
}

// todo: remove
#[expect(
    clippy::non_send_fields_in_send_ty,
    reason = "todo we will remove this"
)]
unsafe impl<'a, 'b, 'c> Send for RecvData<'a, 'b, 'c> {}
unsafe impl<'a, 'b, 'c> Sync for RecvData<'a, 'b, 'c> {}

pub fn generate_ingress_events(world: &mut World, server: &mut Server, scratch: &mut BumpScratch) {
    server
        .drain(|event| match event {
            ServerEvent::AddPlayer { fd } => {
                world.send(AddPlayer { fd });
            }
            ServerEvent::RemovePlayer { fd } => {
                world.send(RemovePlayer { fd });
            }
            ServerEvent::RecvData { fd, data } => {
                world.send(RecvData { fd, data, scratch });
            }
            ServerEvent::SentData { fd } => {
                world.send(SendData { fd });
            }
        })
        .unwrap();
}

// The `Receiver<Tick>` parameter tells our handler to listen for the `Tick` event.
#[instrument(skip_all, level = "trace")]
#[allow(clippy::too_many_arguments, reason = "todo")]
pub fn add_player(
    r: ReceiverMut<AddPlayer>,
    mut fd_lookup: Single<&mut FdLookup>,
    mut sender: IngressSender,
) {
    let event = r.event;

    let new_player = sender.spawn();
    sender.insert(new_player, LoginState::Handshake);
    sender.insert(new_player, DecodeBuffer::default());

    sender.insert(new_player, Packets::default());
    let fd = event.fd;
    sender.insert(new_player, fd);

    fd_lookup.insert(fd, new_player);
    info!("got a player with fd {:?}", fd);
}

// The `Receiver<Tick>` parameter tells our handler to listen for the `Tick` event.
#[instrument(skip_all, level = "trace")]
#[allow(clippy::too_many_arguments, reason = "todo")]
pub fn remove_player(
    r: ReceiverMut<RemovePlayer>,
    mut fd_lookup: Single<&mut FdLookup>,
    mut sender: IngressSender,
) {
    let event = r.event;

    let fd = event.fd;
    let Some(id) = fd_lookup.remove(&fd) else {
        warn!(
            "tried to remove player with fd {:?} but it seemed to already be removed",
            fd
        );
        return;
    };

    sender.despawn(id);

    info!("removed a player with fd {:?}", fd);
}

// The `Receiver<Tick>` parameter tells our handler to listen for the `Tick` event.
#[instrument(skip_all, level = "trace")]
#[allow(clippy::too_many_arguments, reason = "todo")]
pub fn send_data(
    r: Receiver<SendData>,
    mut players: Fetcher<&mut Packets>,
    fd_lookup: Single<&FdLookup>,
) {
    let event = r.event;

    let fd = event.fd;
    let Some(id) = fd_lookup.get(&fd) else {
        warn!(
            "tried to get id for fd {:?} but it seemed to already be removed",
            fd
        );
        return;
    };

    let Ok(pkts) = players.get_mut(*id) else {
        warn!(
            "tried to get pkts for id {:?} but it seemed to already be removed",
            id
        );
        return;
    };

    pkts.set_successfully_sent();
}

pub fn recv_data(
    r: ReceiverMut<RecvData>,
    mut fd_lookup: Single<&mut FdLookup>,
    mut sender: IngressSender,
    global: Single<&Global>,
    mut players: Fetcher<(
        &mut LoginState,
        &mut DecodeBuffer,
andrewgazelka commented 4 months ago

they are all actually needed I think all the lifetimes 'a is the lifetime of the bump allocator, b is the lifetime of the the reference to what is allocated by the bump alloc ... c is lifetime of byte slice received by io uring