@@ -334,6 +334,69 @@ impl DB {
334334 . expect ( "custom circuit not found (mut)" )
335335 }
336336
337+ // Pin helper methods with type checking
338+
339+ // Gates - generic versions
340+ pub fn gate_inp_n ( & self , id : InstanceId , n : u32 ) -> Pin {
341+ self . get_gate ( id) ; // Type check
342+ assert ! ( n < 2 , "Gates only have 2 inputs (0 and 1)" ) ;
343+ Pin {
344+ ins : id,
345+ index : if n == 0 { 0 } else { 2 } ,
346+ }
347+ }
348+
349+ pub fn gate_output_n ( & self , id : InstanceId , n : u32 ) -> Pin {
350+ self . get_gate ( id) ; // Type check
351+ assert ! ( n == 0 , "Gates only have 1 output" ) ;
352+ Pin { ins : id, index : 1 }
353+ }
354+
355+ // Gates - convenience methods
356+ pub fn gate_inp1 ( & self , id : InstanceId ) -> Pin {
357+ self . gate_inp_n ( id, 0 )
358+ }
359+
360+ pub fn gate_inp2 ( & self , id : InstanceId ) -> Pin {
361+ self . gate_inp_n ( id, 1 )
362+ }
363+
364+ pub fn gate_output ( & self , id : InstanceId ) -> Pin {
365+ self . gate_output_n ( id, 0 )
366+ }
367+
368+ // Wires
369+ pub fn wire_pin_n ( & self , id : InstanceId , n : u32 ) -> Pin {
370+ self . get_wire ( id) ; // Type check
371+ assert ! ( n < 2 , "Wires only have 2 pins (0 and 1)" ) ;
372+ Pin { ins : id, index : n }
373+ }
374+
375+ pub fn wire_start ( & self , id : InstanceId ) -> Pin {
376+ self . wire_pin_n ( id, 0 )
377+ }
378+
379+ pub fn wire_end ( & self , id : InstanceId ) -> Pin {
380+ self . wire_pin_n ( id, 1 )
381+ }
382+
383+ // Power
384+ pub fn power_output ( & self , id : InstanceId ) -> Pin {
385+ self . get_power ( id) ; // Type check
386+ Pin { ins : id, index : 0 }
387+ }
388+
389+ // Custom circuits (variable pins)
390+ pub fn custom_circuit_pin ( & self , id : InstanceId , n : u32 ) -> Pin {
391+ let cc = self . get_custom_circuit ( id) ;
392+ let def = & self . custom_circuit_definitions [ cc. definition_index ] ;
393+ assert ! (
394+ ( n as usize ) < def. external_pins. len( ) ,
395+ "Pin index out of bounds for custom circuit"
396+ ) ;
397+ Pin { ins : id, index : n }
398+ }
399+
337400 pub fn pins_of ( & self , id : InstanceId ) -> Vec < Pin > {
338401 match self . ty ( id) {
339402 InstanceKind :: Gate ( gk) => {
@@ -1001,7 +1064,7 @@ impl App {
10011064 self . draw_custom_circuit ( ui, id, custom_circuit) ;
10021065 }
10031066 for ( id, wire) in & self . db . wires {
1004- let has_current = self . current . contains ( & Pin { ins : id , index : 0 } ) ;
1067+ let has_current = self . current . contains ( & self . db . wire_start ( id ) ) ;
10051068 self . draw_wire (
10061069 ui,
10071070 wire,
@@ -1291,10 +1354,12 @@ impl App {
12911354 crate :: drag:: CanvasDrag :: Selected { .. } => { }
12921355 } ,
12931356 Drag :: Resize { id, start } => {
1294- return Some ( Hover :: Pin ( Pin {
1295- ins : id,
1296- index : u32:: from ( !start) ,
1297- } ) ) ;
1357+ let pin = if start {
1358+ self . db . wire_start ( id)
1359+ } else {
1360+ self . db . wire_end ( id)
1361+ } ;
1362+ return Some ( Hover :: Pin ( pin) ) ;
12981363 }
12991364 Drag :: PinToWire {
13001365 source_pin,
@@ -1331,30 +1396,24 @@ impl App {
13311396 }
13321397 }
13331398
1334- for ( k , power ) in & self . db . powers {
1335- let rect = Rect :: from_center_size ( power . pos , self . canvas_config . base_gate_size ) ;
1399+ // First pins
1400+ for ( k , _ ) in & self . db . powers {
13361401 for pin in self . db . pins_of ( k) {
13371402 if self . db . pin_position ( pin) . distance ( mouse_pos) < PIN_HOVER_THRESHOLD {
13381403 return Some ( Hover :: Pin ( pin) ) ;
13391404 }
13401405 }
1341- if rect. contains ( mouse_pos) {
1342- return Some ( Hover :: Instance ( k) ) ;
1343- }
13441406 }
13451407
1346- for ( k, gate) in & self . db . gates {
1347- let rect = Rect :: from_center_size ( gate. pos , self . canvas_config . base_gate_size ) ;
1408+ for ( k, _) in & self . db . gates {
13481409 for pin in self . db . pins_of ( k) {
13491410 if self . db . pin_position ( pin) . distance ( mouse_pos) < PIN_HOVER_THRESHOLD {
13501411 return Some ( Hover :: Pin ( pin) ) ;
13511412 }
13521413 }
1353- if rect. contains ( mouse_pos) {
1354- return Some ( Hover :: Instance ( k) ) ;
1355- }
13561414 }
1357- for ( k, wire) in & self . db . wires {
1415+
1416+ for ( k, _) in & self . db . wires {
13581417 for pin in self . db . pins_of ( k) {
13591418 if self . is_pin_connected ( pin) {
13601419 continue ;
@@ -1363,6 +1422,22 @@ impl App {
13631422 return Some ( Hover :: Pin ( pin) ) ;
13641423 }
13651424 }
1425+ }
1426+
1427+ // Then instances
1428+ for ( k, power) in & self . db . powers {
1429+ let rect = Rect :: from_center_size ( power. pos , self . canvas_config . base_gate_size ) ;
1430+ if rect. contains ( mouse_pos) {
1431+ return Some ( Hover :: Instance ( k) ) ;
1432+ }
1433+ }
1434+ for ( k, gate) in & self . db . gates {
1435+ let rect = Rect :: from_center_size ( gate. pos , self . canvas_config . base_gate_size ) ;
1436+ if rect. contains ( mouse_pos) {
1437+ return Some ( Hover :: Instance ( k) ) ;
1438+ }
1439+ }
1440+ for ( k, wire) in & self . db . wires {
13661441 let dist = wire. dist_to_closest_point_on_line ( mouse_pos) ;
13671442 if dist < WIRE_HIT_DISTANCE {
13681443 return Some ( Hover :: Instance ( k) ) ;
@@ -1507,12 +1582,12 @@ impl App {
15071582 InstanceKind :: Power => {
15081583 let p = self . db . get_power ( id) ;
15091584 if p. on {
1510- current. insert ( Pin { ins : id , index : 0 } ) ;
1585+ current. insert ( self . db . power_output ( id ) ) ;
15111586 }
15121587 }
15131588 InstanceKind :: Wire => {
1514- let a = Pin { ins : id , index : 0 } ;
1515- let b = Pin { ins : id , index : 1 } ;
1589+ let a = self . db . wire_start ( id ) ;
1590+ let b = self . db . wire_end ( id ) ;
15161591 let mut visiting = HashSet :: new ( ) ;
15171592 let a_on = self . eval_pin ( a, current, & mut visiting) ;
15181593 visiting. clear ( ) ;
@@ -1523,10 +1598,9 @@ impl App {
15231598 }
15241599 }
15251600 InstanceKind :: Gate ( kind) => {
1526- // pins: 0=input A, 2=input B, 1=output
1527- let a = Pin { ins : id, index : 0 } ;
1528- let b = Pin { ins : id, index : 2 } ;
1529- let out = Pin { ins : id, index : 1 } ;
1601+ let a = self . db . gate_inp1 ( id) ;
1602+ let b = self . db . gate_inp2 ( id) ;
1603+ let out = self . db . gate_output ( id) ;
15301604 let mut visiting = HashSet :: new ( ) ;
15311605 let a_on = self . eval_pin ( a, current, & mut visiting) ;
15321606 visiting. clear ( ) ;
@@ -1721,10 +1795,7 @@ impl App {
17211795 }
17221796 }
17231797 InstanceKind :: Gate ( _) => {
1724- let out_pin = Pin {
1725- ins : other. ins ,
1726- index : 1 ,
1727- } ;
1798+ let out_pin = self . db . gate_output ( other. ins ) ;
17281799 if other == out_pin {
17291800 self . eval_instance ( other. ins , current) ;
17301801 if current. contains ( & out_pin) {
0 commit comments