honestly fixed so much and forgot to commit

Signed-off-by: Sienna Meridian Satterwhite <sienna@r3t.io>
This commit is contained in:
2025-12-28 17:39:27 +00:00
parent 28909e8b76
commit e890b0213a
47 changed files with 2248 additions and 438 deletions

View File

@@ -47,7 +47,6 @@ use uuid::Uuid;
use crate::networking::{
GossipBridge,
NetworkedSelection,
NodeId,
VersionedMessage,
delta_generation::NodeVectorClock,
@@ -334,10 +333,63 @@ impl EntityLockRegistry {
}
}
/// System to acquire locks when entities are selected
///
/// This system detects when entities are added to the global `LocalSelection`
/// resource and attempts to acquire locks on those entities, broadcasting
/// the request to other peers.
pub fn acquire_locks_on_selection_system(
mut registry: ResMut<EntityLockRegistry>,
node_clock: Res<NodeVectorClock>,
bridge: Option<Res<GossipBridge>>,
selection: Res<crate::networking::LocalSelection>,
) {
// Only run when selection changes
if !selection.is_changed() {
return;
}
let node_id = node_clock.node_id;
// Try to acquire locks for all selected entities
for &entity_id in selection.iter() {
let already_locked = registry.is_locked_by(entity_id, node_id, node_id);
// Only try to acquire if we don't already hold the lock
if !already_locked {
match registry.try_acquire(entity_id, node_id) {
Ok(()) => {
info!("Acquired lock on newly selected entity {}", entity_id);
// Broadcast LockRequest
if let Some(ref bridge) = bridge {
let msg = VersionedMessage::new(SyncMessage::Lock(LockMessage::LockRequest {
entity_id,
node_id,
}));
if let Err(e) = bridge.send(msg) {
error!("Failed to broadcast LockRequest on selection: {}", e);
} else {
debug!("LockRequest broadcast successful for entity {}", entity_id);
}
} else {
warn!("No GossipBridge available to broadcast LockRequest");
}
}
Err(holder) => {
warn!("Failed to acquire lock on selected entity {} (held by {})", entity_id, holder);
}
}
}
}
}
/// System to release locks when entities are deselected
///
/// This system detects when entities are removed from selection and releases
/// any locks held on those entities, broadcasting the release to other peers.
/// This system detects when entities are removed from the global `LocalSelection`
/// resource and releases any locks held on those entities, broadcasting the release
/// to other peers.
///
/// Add to your app as an Update system:
/// ```no_run
@@ -350,42 +402,46 @@ pub fn release_locks_on_deselection_system(
mut registry: ResMut<EntityLockRegistry>,
node_clock: Res<NodeVectorClock>,
bridge: Option<Res<GossipBridge>>,
mut selection_query: Query<&mut NetworkedSelection, Changed<NetworkedSelection>>,
selection: Res<crate::networking::LocalSelection>,
) {
// Only run when selection changes
if !selection.is_changed() {
return;
}
let node_id = node_clock.node_id;
for selection in selection_query.iter_mut() {
// Find entities that were previously locked but are no longer selected
let currently_selected: std::collections::HashSet<Uuid> = selection.selected_ids.clone();
// Check all locks held by this node
let locks_to_release: Vec<Uuid> = registry
.locks
.iter()
.filter(|(entity_id, lock)| {
// Release if held by us and not currently selected
lock.holder == node_id && !selection.contains(**entity_id)
})
.map(|(entity_id, _)| *entity_id)
.collect();
// Check all locks held by this node
let locks_to_release: Vec<Uuid> = registry
.locks
.iter()
.filter(|(entity_id, lock)| {
// Release if held by us and not currently selected
lock.holder == node_id && !currently_selected.contains(entity_id)
})
.map(|(entity_id, _)| *entity_id)
.collect();
if !locks_to_release.is_empty() {
info!("Selection cleared, releasing {} locks", locks_to_release.len());
}
// Release each lock and broadcast
for entity_id in locks_to_release {
if registry.release(entity_id, node_id) {
debug!("Releasing lock on deselected entity {}", entity_id);
// Release each lock and broadcast
for entity_id in locks_to_release {
if registry.release(entity_id, node_id) {
info!("Released lock on deselected entity {}", entity_id);
// Broadcast LockRelease
if let Some(ref bridge) = bridge {
let msg = VersionedMessage::new(SyncMessage::Lock(LockMessage::LockRelease {
entity_id,
node_id,
}));
// Broadcast LockRelease
if let Some(ref bridge) = bridge {
let msg = VersionedMessage::new(SyncMessage::Lock(LockMessage::LockRelease {
entity_id,
node_id,
}));
if let Err(e) = bridge.send(msg) {
error!("Failed to broadcast LockRelease on deselection: {}", e);
} else {
info!("Lock released on deselection: entity {}", entity_id);
}
if let Err(e) = bridge.send(msg) {
error!("Failed to broadcast LockRelease on deselection: {}", e);
} else {
info!("Lock released on deselection: entity {}", entity_id);
}
}
}