use core::ops::Range;
use bevy::{prelude::*, ptr::Ptr};
use crate::{
postcard_utils,
prelude::*,
shared::replication::registry::{FnsId, ctx::SerializeCtx, serde_fns::SerdeFns},
};
#[derive(Resource, Deref, DerefMut, Default)]
pub(crate) struct SerializedData(Vec<u8>);
impl SerializedData {
pub(crate) fn write_cached_mapping(
&mut self,
cached_range: &mut Option<Range<usize>>,
entity: Entity,
hash: u64,
) -> Result<Range<usize>> {
self.write_cached(cached_range, |serialized| {
serialized.write_mapping(entity, hash)
})
}
pub(crate) fn write_cached_component(
&mut self,
ctx: &mut SerializeCtx,
cached_range: &mut Option<Range<usize>>,
component: &mut ErasedComponent,
) -> Result<Range<usize>> {
self.write_cached(cached_range, |serialized| {
serialized.write_component(ctx, component)
})
}
pub(crate) fn write_cached_entity(
&mut self,
cached_range: &mut Option<Range<usize>>,
entity: Entity,
) -> Result<Range<usize>> {
self.write_cached(cached_range, |serialized| serialized.write_entity(entity))
}
pub(crate) fn write_cached_fns_id(
&mut self,
cached_range: &mut Option<Range<usize>>,
fns_id: FnsId,
) -> Result<Range<usize>> {
self.write_cached(cached_range, |serialized| serialized.write_fns_id(fns_id))
}
pub(crate) fn write_cached_tick(
&mut self,
cached_range: &mut Option<Range<usize>>,
tick: RepliconTick,
) -> Result<Range<usize>> {
self.write_cached(cached_range, |serialized| serialized.write_tick(tick))
}
fn write_cached(
&mut self,
cached_range: &mut Option<Range<usize>>,
write: impl FnOnce(&mut Self) -> Result<Range<usize>>,
) -> Result<Range<usize>> {
if let Some(range) = cached_range.clone() {
return Ok(range);
}
let range = write(self)?;
*cached_range = Some(range.clone());
Ok(range)
}
pub(crate) fn write_component(
&mut self,
ctx: &mut SerializeCtx,
component: &mut ErasedComponent,
) -> Result<Range<usize>> {
self.write_with(|bytes| {
postcard_utils::to_extend_mut(&component.fns_id, bytes)?;
unsafe {
component.fns.serialize(ctx, component.ptr, bytes)?;
}
Ok(())
})
}
fn write_mapping(&mut self, entity: Entity, hash: u64) -> Result<Range<usize>> {
self.write_with(|bytes| {
postcard_utils::entity_to_extend_mut(&entity, bytes)?;
bytes.extend(hash.to_le_bytes()); Ok(())
})
}
pub(crate) fn write_entity(&mut self, entity: Entity) -> Result<Range<usize>> {
self.write_with(|bytes| {
postcard_utils::entity_to_extend_mut(&entity, bytes)?;
Ok(())
})
}
pub(crate) fn write_fns_id(&mut self, fns_id: FnsId) -> Result<Range<usize>> {
self.write_with(|bytes| {
postcard_utils::to_extend_mut(&fns_id, bytes)?;
Ok(())
})
}
fn write_tick(&mut self, tick: RepliconTick) -> Result<Range<usize>> {
self.write_with(|bytes| {
postcard_utils::to_extend_mut(&tick, bytes)?;
Ok(())
})
}
fn write_with(
&mut self,
write: impl FnOnce(&mut Vec<u8>) -> Result<()>,
) -> Result<Range<usize>> {
let start = self.len();
write(&mut self.0)?;
let end = self.len();
Ok(start..end)
}
}
pub(crate) struct ErasedComponent<'a> {
fns: SerdeFns<'a>,
ptr: Ptr<'a>,
fns_id: FnsId,
}
impl<'a> ErasedComponent<'a> {
pub(crate) unsafe fn new(fns: SerdeFns<'a>, ptr: Ptr<'a>, fns_id: FnsId) -> Self {
Self { fns, ptr, fns_id }
}
}