nimble-protocol 0.0.16

Nimble Protocol
Documentation
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/nimble-rust/nimble
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */

use crate::host_to_client::TickIdUtil;
use flood_rs::{Deserialize, ReadOctetStream, Serialize, WriteOctetStream};
use nimble_participant::ParticipantId;
use nimble_step_map::StepMap;
use seq_map::SeqMap;
use std::collections::HashSet;
use std::fmt::{Debug, Display, Formatter};
use std::io;
use tick_id::TickId;

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct CombinedSteps<StepT: Deserialize + Serialize + Debug + Clone + Display> {
    pub tick_id: TickId,
    pub steps: Vec<StepMap<StepT>>,
}

impl<StepT: Deserialize + Serialize + Debug + Clone + Display> Display for CombinedSteps<StepT> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "[{} step_count:{}]", self.tick_id, self.steps.len())
    }
}

impl<StepT: Deserialize + Serialize + Debug + Clone + Display> Serialize for CombinedSteps<StepT> {
    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
        TickIdUtil::to_stream(self.tick_id, stream)?;
        self.to_internal().serialize(stream)
    }
}

impl<StepT: Deserialize + Serialize + Debug + Clone + Display> Deserialize
    for CombinedSteps<StepT>
{
    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
        let start_tick_id = TickIdUtil::from_stream(stream)?;
        let internal = InternalAllParticipantVectors::deserialize(stream)?;
        Ok(Self::from_internal(&internal, start_tick_id))
    }
}

impl<StepT: Deserialize + Serialize + Debug + Clone + Display> CombinedSteps<StepT> {
    #[must_use]
    pub fn to_internal(&self) -> InternalAllParticipantVectors<StepT> {
        let mut hash_map = StepMap::<InternalStepVectorForOneParticipant<StepT>>::new();

        let mut unique_participant_ids: HashSet<ParticipantId> = HashSet::new();

        for auth_step in &self.steps {
            for key in auth_step.keys() {
                unique_participant_ids.insert(*key);
            }
        }

        let mut sorted_unique_ids: Vec<ParticipantId> =
            unique_participant_ids.into_iter().collect();
        sorted_unique_ids.sort();

        for participant_id in sorted_unique_ids {
            hash_map
                .insert(
                    participant_id,
                    InternalStepVectorForOneParticipant::<StepT> {
                        delta_tick_id: 0,
                        steps: vec![],
                    },
                )
                .expect("participant ids to be unique");
        }

        for (index_in_range, combined_auth_step) in self.steps.iter().enumerate() {
            for (participant_id, auth_step_for_one_player) in combined_auth_step {
                let vector_for_one_person = hash_map.get_mut(participant_id).unwrap();
                if vector_for_one_person.steps.is_empty() {
                    vector_for_one_person.delta_tick_id = index_in_range as u8;
                }
                vector_for_one_person
                    .steps
                    .push(auth_step_for_one_player.clone());
            }
        }

        InternalAllParticipantVectors::<StepT> {
            participant_step_vectors: hash_map,
        }
    }

    #[must_use]
    pub fn from_internal(
        separate_vectors: &InternalAllParticipantVectors<StepT>,
        start_tick_id: TickId,
    ) -> Self {
        let mut max_vector_length = 0;

        for serialized_step_vector in separate_vectors.participant_step_vectors.values() {
            if serialized_step_vector.steps.len() > max_vector_length {
                max_vector_length = serialized_step_vector.steps.len();
            }
        }

        let mut auth_step_range_vec = Vec::<StepMap<StepT>>::new();
        for _ in 0..max_vector_length {
            auth_step_range_vec.push(SeqMap::new());
        }

        for (participant_id, serialized_step_vector) in &separate_vectors.participant_step_vectors {
            for (index, serialized_step) in serialized_step_vector.steps.iter().enumerate() {
                let hash_map_for_auth_step = auth_step_range_vec.get_mut(index).unwrap();
                hash_map_for_auth_step
                    .insert(*participant_id, serialized_step.clone())
                    .expect("expect unique participant_id");
            }
        }

        Self {
            tick_id: start_tick_id,
            steps: auth_step_range_vec,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InternalStepVectorForOneParticipant<StepT: Serialize + Deserialize> {
    pub delta_tick_id: u8, // enables one vector to start at a later tick_id than the others
    pub steps: Vec<StepT>,
}

impl<StepT: Serialize + Deserialize + Display> Display
    for InternalStepVectorForOneParticipant<StepT>
{
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "delta_tick {} step_count:{}",
            self.delta_tick_id,
            self.steps.len()
        )
    }
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InternalAllParticipantVectors<StepT: Serialize + Deserialize + Display> {
    pub participant_step_vectors: SeqMap<ParticipantId, InternalStepVectorForOneParticipant<StepT>>,
}

impl<StepT: Serialize + Deserialize + Debug + Display> InternalAllParticipantVectors<StepT> {
    pub fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()>
    where
        Self: Sized,
    {
        // How many participants streams follows
        stream.write_u8(self.participant_step_vectors.len() as u8)?;

        for (participant_id, authoritative_steps_for_one_player_vector) in
            &self.participant_step_vectors
        {
            participant_id.serialize(stream)?;
            stream.write_u8(authoritative_steps_for_one_player_vector.delta_tick_id)?;
            stream.write_u8(authoritative_steps_for_one_player_vector.steps.len() as u8)?;

            for authoritative_step_for_one_player in
                &authoritative_steps_for_one_player_vector.steps
            {
                authoritative_step_for_one_player.serialize(stream)?;
            }
        }
        Ok(())
    }

    pub fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
        let required_participant_count_in_range = stream.read_u8()?;
        let mut authoritative_participants = SeqMap::new();
        for _ in 0..required_participant_count_in_range {
            let participant_id = ParticipantId::deserialize(stream)?;
            let delta_tick_id_from_range = stream.read_u8()?;
            let number_of_steps_that_follows = stream.read_u8()? as usize;

            let mut authoritative_steps_for_one_participant =
                Vec::with_capacity(number_of_steps_that_follows);

            for _ in 0..number_of_steps_that_follows {
                let authoritative_step = StepT::deserialize(stream)?;
                authoritative_steps_for_one_participant.push(authoritative_step);
            }

            authoritative_participants
                .insert(
                    participant_id,
                    InternalStepVectorForOneParticipant {
                        delta_tick_id: delta_tick_id_from_range,
                        steps: authoritative_steps_for_one_participant,
                    },
                )
                .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
        }

        Ok(Self {
            participant_step_vectors: authoritative_participants,
        })
    }
}

// ----

#[derive(Debug)]
pub struct InternalAuthoritativeStepRange<StepT: Deserialize + Serialize + Debug + Clone + Display>
{
    pub delta_tick_id_from_previous: u8,
    pub authoritative_steps: InternalAllParticipantVectors<StepT>,
}