Skip to content

Commit 2ea42cc

Browse files
rsthorntonclaude
andcommitted
fix: WebView icon cache + Interface↔Interface block + G network save panic
## Fixes - Renamed palette icons to bust WebView cache (interface-icon.png, subsystem-icon.png) - Block Interface↔Interface connections with user warning (deferred feature) - Fix save panic for G network flows: FlowStartConnection/FlowEndConnection targets now correctly point to parent system when source/dest is interface ## Root Causes - WebView was caching bad responses for original icon filenames - Save system expects flow targets to be systems, not interfaces directly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 001c3a6 commit 2ea42cc

5 files changed

Lines changed: 49 additions & 9 deletions

File tree

src/bevy_app/systems/connection_mode.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ pub fn finalize_connection(
242242
let dest_is_interface = interface_query.get(destination_entity).is_ok();
243243
let dest_is_external = external_entity_query.get(destination_entity).is_ok();
244244

245+
// Block Interface ↔ Interface connections (deferred - direction logic not stable)
246+
if source_is_interface && dest_is_interface {
247+
warn!("❌ Interface ↔ Interface connections coming in future version");
248+
continue;
249+
}
250+
245251
// Phase 3A: Check if entities have InterfaceBehavior (subsystem-capable interfaces)
246252
let source_has_interface_behavior = interface_behavior_query.get(source_entity).is_ok();
247253
let dest_has_interface_behavior = interface_behavior_query.get(destination_entity).is_ok();
@@ -311,7 +317,11 @@ pub fn finalize_connection(
311317
subsystem_query.get(source_entity).unwrap().0.parent_system
312318
} else if dest_is_subsystem {
313319
// Dest is a subsystem - parent flow to its parent_system
314-
subsystem_query.get(destination_entity).unwrap().0.parent_system
320+
subsystem_query
321+
.get(destination_entity)
322+
.unwrap()
323+
.0
324+
.parent_system
315325
} else if source_is_interface {
316326
// Interface's parent might be a subsystem - check and get grandparent
317327
let interface_parent = parent_query
@@ -483,16 +493,38 @@ pub fn finalize_connection(
483493
EndTargetType::System
484494
};
485495

496+
// Determine the actual targets for FlowStartConnection/FlowEndConnection
497+
// For interfaces: target should be the interface's parent SYSTEM, not the interface itself
498+
// This matches how the save system expects flows to be structured
499+
let start_target = if source_is_interface {
500+
// Get the interface's parent (the system it's attached to)
501+
parent_query
502+
.get(source_entity)
503+
.map(|p| p.get())
504+
.expect("Interface should have parent")
505+
} else {
506+
source_entity
507+
};
508+
509+
let end_target = if dest_is_interface {
510+
parent_query
511+
.get(destination_entity)
512+
.map(|p| p.get())
513+
.expect("Interface should have parent")
514+
} else {
515+
destination_entity
516+
};
517+
486518
// Add connection components to link flow to source and destination
487519
let mut flow_commands = commands.entity(flow_entity);
488520

489521
flow_commands.insert((
490522
FlowStartConnection {
491-
target: source_entity,
523+
target: start_target,
492524
target_type: start_target_type,
493525
},
494526
FlowEndConnection {
495-
target: destination_entity,
527+
target: end_target,
496528
target_type: end_target_type,
497529
},
498530
));
@@ -570,7 +602,12 @@ fn compute_endpoint_for_entity_world(
570602

571603
if let (Some(other_pos), Some(other_dir)) = (other_end, other_end_dir) {
572604
// Use zoomed radius (system.radius * scale)
573-
compute_end_and_direction_from_subsystem(pos, system.radius * scale, other_pos, other_dir)
605+
compute_end_and_direction_from_subsystem(
606+
pos,
607+
system.radius * scale,
608+
other_pos,
609+
other_dir,
610+
)
574611
} else {
575612
// First pass - use a placeholder direction (will be recomputed)
576613
(pos, Vec2::X)

src/bevy_app/systems/palette.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ const PALETTE_ICON_SIZE: f32 = 40.0;
5151
/// Maps PaletteElementType to its icon asset path.
5252
fn icon_path_for(element_type: PaletteElementType) -> &'static str {
5353
match element_type {
54-
PaletteElementType::Subsystem => "palette-icons/subsystem.png",
55-
PaletteElementType::Interface => "palette-icons/interface.png",
54+
PaletteElementType::Subsystem => "palette-icons/subsystem-icon.png",
55+
PaletteElementType::Interface => "palette-icons/interface-icon.png",
5656
PaletteElementType::EnvironmentalObject => "palette-icons/source.png", // Reuse source icon for now
5757
}
5858
}
@@ -193,7 +193,10 @@ pub fn handle_leptos_palette_click(
193193
.id();
194194

195195
placement_mode.ghost_entity = Some(ghost);
196-
info!("✨ Entered placement mode for {:?} (from Leptos)", element_type);
196+
info!(
197+
"✨ Entered placement mode for {:?} (from Leptos)",
198+
element_type
199+
);
197200
}
198201
}
199202

src/leptos_app/components/palette.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ pub fn Palette(
1818
<div class="fixed left-0 top-20 bottom-0 w-16 bg-stone-50 shadow-md z-10 flex flex-col items-center py-3 space-y-2">
1919
<PaletteButton
2020
element_type=PaletteElementTypeEvent::Subsystem
21-
icon_path="assets/palette-icons/subsystem.png"
21+
icon_path="assets/palette-icons/subsystem-icon.png"
2222
on_click=on_element_click
2323
/>
2424
<PaletteButton
2525
element_type=PaletteElementTypeEvent::Interface
26-
icon_path="assets/palette-icons/interface.png"
26+
icon_path="assets/palette-icons/interface-icon.png"
2727
on_click=on_element_click
2828
/>
2929
<PaletteButton

0 commit comments

Comments
 (0)