honestly fixed so much and forgot to commit
Signed-off-by: Sienna Meridian Satterwhite <sienna@r3t.io>
This commit is contained in:
@@ -573,7 +573,7 @@ pub fn save_session_vector_clock(
|
||||
)?;
|
||||
|
||||
// Insert current clock state
|
||||
for (node_id, &counter) in &clock.clocks {
|
||||
for (node_id, &counter) in &clock.timestamps {
|
||||
tx.execute(
|
||||
"INSERT INTO vector_clock (session_id, node_id, counter, updated_at)
|
||||
VALUES (?1, ?2, ?3, ?4)",
|
||||
@@ -608,7 +608,7 @@ pub fn load_session_vector_clock(
|
||||
for row in rows {
|
||||
let (node_id_str, counter) = row?;
|
||||
if let Ok(node_id) = uuid::Uuid::parse_str(&node_id_str) {
|
||||
clock.clocks.insert(node_id, counter as u64);
|
||||
clock.timestamps.insert(node_id, counter as u64);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ mod metrics;
|
||||
mod migrations;
|
||||
mod plugin;
|
||||
pub mod reflection;
|
||||
mod registered_components;
|
||||
mod systems;
|
||||
mod type_registry;
|
||||
mod types;
|
||||
|
||||
@@ -38,6 +38,8 @@ pub struct Persisted {
|
||||
pub network_id: uuid::Uuid,
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Persisted {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
||||
64
crates/libmarathon/src/persistence/registered_components.rs
Normal file
64
crates/libmarathon/src/persistence/registered_components.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
//! Component registrations for CRDT synchronization
|
||||
//!
|
||||
//! This module registers all components that should be synchronized across
|
||||
//! the network using the inventory-based type registry.
|
||||
//!
|
||||
//! # When to use this file vs `#[synced]` attribute
|
||||
//!
|
||||
//! **Use `#[synced]` attribute for:**
|
||||
//! - Your own component types defined in this codebase
|
||||
//! - Any type you have source access to
|
||||
//! - Most game components (entities, markers, etc.)
|
||||
//! - Example: `#[synced] pub struct CubeMarker { ... }`
|
||||
//!
|
||||
//! **Use manual `inventory::submit!` here for:**
|
||||
//! - Third-party types (Bevy's Transform, external crates)
|
||||
//! - Types that need custom serialization logic
|
||||
//! - Types where the serialized format differs from in-memory format
|
||||
//!
|
||||
//! # Currently registered external types
|
||||
//!
|
||||
//! - `Transform` - Bevy's transform component (needs custom rkyv conversion)
|
||||
|
||||
use std::any::TypeId;
|
||||
|
||||
// Register Transform for synchronization
|
||||
// We serialize Bevy's Transform but convert to our rkyv-compatible type
|
||||
inventory::submit! {
|
||||
crate::persistence::ComponentMeta {
|
||||
type_name: "Transform",
|
||||
type_path: "bevy::transform::components::transform::Transform",
|
||||
type_id: TypeId::of::<bevy::prelude::Transform>(),
|
||||
|
||||
deserialize_fn: |bytes: &[u8]| -> anyhow::Result<Box<dyn std::any::Any>> {
|
||||
let transform: crate::transform::Transform = rkyv::from_bytes::<crate::transform::Transform, rkyv::rancor::Failure>(bytes)?;
|
||||
// Convert back to Bevy Transform
|
||||
let bevy_transform = bevy::prelude::Transform {
|
||||
translation: transform.translation.into(),
|
||||
rotation: transform.rotation.into(),
|
||||
scale: transform.scale.into(),
|
||||
};
|
||||
Ok(Box::new(bevy_transform))
|
||||
},
|
||||
|
||||
serialize_fn: |world: &bevy::ecs::world::World, entity: bevy::ecs::entity::Entity| -> Option<bytes::Bytes> {
|
||||
world.get::<bevy::prelude::Transform>(entity).map(|bevy_transform| {
|
||||
// Convert to our rkyv-compatible Transform
|
||||
let transform = crate::transform::Transform {
|
||||
translation: bevy_transform.translation.into(),
|
||||
rotation: bevy_transform.rotation.into(),
|
||||
scale: bevy_transform.scale.into(),
|
||||
};
|
||||
let serialized = rkyv::to_bytes::<rkyv::rancor::Failure>(&transform)
|
||||
.expect("Failed to serialize Transform");
|
||||
bytes::Bytes::from(serialized.to_vec())
|
||||
})
|
||||
},
|
||||
|
||||
insert_fn: |entity_mut: &mut bevy::ecs::world::EntityWorldMut, boxed: Box<dyn std::any::Any>| {
|
||||
if let Ok(transform) = boxed.downcast::<bevy::prelude::Transform>() {
|
||||
entity_mut.insert(*transform);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -261,6 +261,51 @@ impl Default for ComponentTypeRegistryResource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Macro to register a component type with the inventory system
|
||||
///
|
||||
/// This generates the necessary serialize/deserialize functions and submits
|
||||
/// the ComponentMeta to inventory for runtime registration.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// use bevy::prelude::*;
|
||||
/// register_component!(Transform, "bevy::transform::components::Transform");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! register_component {
|
||||
($component_type:ty, $type_path:expr) => {
|
||||
// Submit component metadata to inventory
|
||||
inventory::submit! {
|
||||
$crate::persistence::ComponentMeta {
|
||||
type_name: stringify!($component_type),
|
||||
type_path: $type_path,
|
||||
type_id: std::any::TypeId::of::<$component_type>(),
|
||||
|
||||
deserialize_fn: |bytes: &[u8]| -> anyhow::Result<Box<dyn std::any::Any>> {
|
||||
let component: $component_type = rkyv::from_bytes(bytes)?;
|
||||
Ok(Box::new(component))
|
||||
},
|
||||
|
||||
serialize_fn: |world: &bevy::ecs::world::World, entity: bevy::ecs::entity::Entity| -> Option<bytes::Bytes> {
|
||||
world.get::<$component_type>(entity).map(|component| {
|
||||
let serialized = rkyv::to_bytes::<rkyv::rancor::Failure>(component)
|
||||
.expect("Failed to serialize component");
|
||||
bytes::Bytes::from(serialized.to_vec())
|
||||
})
|
||||
},
|
||||
|
||||
insert_fn: |entity_mut: &mut bevy::ecs::world::EntityWorldMut, boxed: Box<dyn std::any::Any>| {
|
||||
if let Ok(component) = boxed.downcast::<$component_type>() {
|
||||
entity_mut.insert(*component);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user