naia-client 0.25.0

Provides a cross-platform client that can send/receive messages to/from a server, and has a pool of in-scope entities/components that is synced with the server.
Documentation
use std::collections::HashMap;

use log::warn;

use naia_shared::{
    ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer,
};

// GlobalRequestManager
pub struct GlobalRequestManager {
    map: HashMap<GlobalRequestId, Option<MessageContainer>>,
    next_id: u64,
}

impl GlobalRequestManager {
    pub fn new() -> Self {
        Self {
            map: HashMap::new(),
            next_id: 0,
        }
    }

    pub(crate) fn create_request_id(&mut self) -> GlobalRequestId {
        let id = GlobalRequestId::new(self.next_id);
        self.next_id = self.next_id.wrapping_add(1);

        self.map.insert(id, None);

        id
    }

    /// Check if a response is available for the given request ID (non-destructive)
    pub(crate) fn has_response(&self, request_id: &GlobalRequestId) -> bool {
        self.map
            .get(request_id)
            .map(|opt| opt.is_some())
            .unwrap_or(false)
    }

    pub(crate) fn destroy_request_id(
        &mut self,
        request_id: &GlobalRequestId,
    ) -> Option<MessageContainer> {
        let response_opt = self.map.get(request_id)?;
        if response_opt.is_some() {
            let response_opt = self.map.remove(request_id).unwrap();
            return Some(response_opt.unwrap());
        }
        None
    }

    pub(crate) fn receive_response(
        &mut self,
        request_id: &GlobalRequestId,
        response: MessageContainer,
    ) {
        if let Some(response_opt) = self.map.get_mut(request_id) {
            *response_opt = Some(response);
        } else {
            warn!("receive_response: dropping response for unknown request_id {:?}; request was likely cancelled or the connection was reset", request_id);
        }
    }
}

// GlobalResponseManager
pub struct GlobalResponseManager {
    map: HashMap<GlobalResponseId, (ChannelKind, LocalResponseId)>,
    next_id: u64,
}

impl GlobalResponseManager {
    pub fn new() -> Self {
        Self {
            map: HashMap::new(),
            next_id: 0,
        }
    }

    pub(crate) fn create_response_id(
        &mut self,
        channel_kind: &ChannelKind,
        local_response_id: &LocalResponseId,
    ) -> GlobalResponseId {
        let id = GlobalResponseId::new(self.next_id);
        self.next_id = self.next_id.wrapping_add(1);

        self.map
            .insert(id, (*channel_kind, *local_response_id));

        id
    }

    pub(crate) fn destroy_response_id(
        &mut self,
        global_response_id: &GlobalResponseId,
    ) -> Option<(ChannelKind, LocalResponseId)> {
        self.map.remove(global_response_id)
    }
}