@@ -6,7 +6,7 @@ use eframe::{
6
6
} ;
7
7
use egui_node_graph:: * ;
8
8
9
- use complogic:: { And , Compiler , Gate , Simulation } ;
9
+ use complogic:: { And , Compiler , Gate , Nand , Not , Simulation } ;
10
10
11
11
// ========= First, define your user data types =============
12
12
@@ -60,6 +60,8 @@ impl ValueType {
60
60
#[ derive( Clone , Copy , serde:: Serialize , serde:: Deserialize ) ]
61
61
pub enum NodeTempl {
62
62
And ,
63
+ Not ,
64
+ Nand ,
63
65
Immediate ,
64
66
}
65
67
@@ -120,6 +122,8 @@ impl NodeTemplateTrait for NodeTempl {
120
122
) -> Cow < ' _ , str > {
121
123
Cow :: Borrowed ( match self {
122
124
NodeTempl :: And => "And Gate" ,
125
+ NodeTempl :: Not => "Not Gate" ,
126
+ NodeTempl :: Nand => "Nand Gate" ,
123
127
NodeTempl :: Immediate => "Immediate" ,
124
128
} )
125
129
}
@@ -130,7 +134,7 @@ impl NodeTemplateTrait for NodeTempl {
130
134
_user_state : & mut Self :: UserState ,
131
135
) -> Vec < & ' static str > {
132
136
match self {
133
- NodeTempl :: And => vec ! [ "Gate " ] ,
137
+ NodeTempl :: And | NodeTempl :: Not | NodeTempl :: Nand => vec ! [ "Gates " ] ,
134
138
NodeTempl :: Immediate => vec ! [ "Tools" ] ,
135
139
}
136
140
}
@@ -172,6 +176,7 @@ impl NodeTemplateTrait for NodeTempl {
172
176
} ;
173
177
174
178
match self {
179
+ // Gates
175
180
NodeTempl :: And => {
176
181
// The first input param doesn't use the closure so we can comment
177
182
// it in more detail.
@@ -193,6 +198,17 @@ impl NodeTemplateTrait for NodeTempl {
193
198
input_scalar ( graph, "B" ) ;
194
199
output_scalar ( graph, "out" ) ;
195
200
}
201
+ NodeTempl :: Not => {
202
+ input_scalar ( graph, "A" ) ;
203
+ output_scalar ( graph, "out" ) ;
204
+ }
205
+ NodeTempl :: Nand => {
206
+ input_scalar ( graph, "A" ) ;
207
+ input_scalar ( graph, "B" ) ;
208
+ output_scalar ( graph, "out" ) ;
209
+ }
210
+
211
+ // Tools
196
212
NodeTempl :: Immediate => {
197
213
// The first input param doesn't use the closure so we can comment
198
214
// it in more detail.
@@ -225,7 +241,12 @@ impl NodeTemplateIter for AllNodeTempls {
225
241
// This function must return a list of node kinds, which the node finder
226
242
// will use to display it to the user. Crates like strum can reduce the
227
243
// boilerplate in enumerating all variants of an enum.
228
- vec ! [ NodeTempl :: And , NodeTempl :: Immediate ]
244
+ vec ! [
245
+ NodeTempl :: And ,
246
+ NodeTempl :: Not ,
247
+ NodeTempl :: Nand ,
248
+ NodeTempl :: Immediate ,
249
+ ]
229
250
}
230
251
}
231
252
@@ -484,6 +505,84 @@ impl eframe::App for NodeGraphExample {
484
505
let gate = And { a, b, out } ;
485
506
self . user_state . gates . insert ( id, Gate :: from ( gate) ) ;
486
507
}
508
+ NodeTempl :: Not => {
509
+ let mut in_ids = data. input_ids ( ) ;
510
+ let mut out_ids = data. output_ids ( ) ;
511
+
512
+ let a_out = self . state . graph . connection ( in_ids. next ( ) . unwrap ( ) ) ;
513
+
514
+ if a_out. is_none ( ) {
515
+ continue ;
516
+ }
517
+
518
+ let a_out = a_out. unwrap ( ) ;
519
+
520
+ let a = match self . user_state . outs_to_regs . get ( & a_out) {
521
+ Some ( reg) => * reg,
522
+ None => {
523
+ let reg = self . user_state . compiler . alloc ( ) ;
524
+ self . user_state . outs_to_regs . insert ( a_out, reg) ;
525
+ reg
526
+ }
527
+ } ;
528
+
529
+ let out_id = out_ids. next ( ) . unwrap ( ) ;
530
+ let out = match self . user_state . outs_to_regs . get ( & out_id) {
531
+ Some ( reg) => * reg,
532
+ None => {
533
+ let reg = self . user_state . compiler . alloc ( ) ;
534
+ self . user_state . outs_to_regs . insert ( out_id, reg) ;
535
+ reg
536
+ }
537
+ } ;
538
+
539
+ let gate = Not { a, out } ;
540
+ self . user_state . gates . insert ( id, Gate :: from ( gate) ) ;
541
+ }
542
+ NodeTempl :: Nand => {
543
+ let mut in_ids = data. input_ids ( ) ;
544
+ let mut out_ids = data. output_ids ( ) ;
545
+
546
+ let a_out = self . state . graph . connection ( in_ids. next ( ) . unwrap ( ) ) ;
547
+ let b_out = self . state . graph . connection ( in_ids. next ( ) . unwrap ( ) ) ;
548
+
549
+ if a_out. is_none ( ) || b_out. is_none ( ) {
550
+ continue ;
551
+ }
552
+
553
+ let a_out = a_out. unwrap ( ) ;
554
+ let b_out = b_out. unwrap ( ) ;
555
+
556
+ let a = match self . user_state . outs_to_regs . get ( & a_out) {
557
+ Some ( reg) => * reg,
558
+ None => {
559
+ let reg = self . user_state . compiler . alloc ( ) ;
560
+ self . user_state . outs_to_regs . insert ( a_out, reg) ;
561
+ reg
562
+ }
563
+ } ;
564
+ let b = match self . user_state . outs_to_regs . get ( & b_out) {
565
+ Some ( reg) => * reg,
566
+ None => {
567
+ let reg = self . user_state . compiler . alloc ( ) ;
568
+ self . user_state . outs_to_regs . insert ( b_out, reg) ;
569
+ reg
570
+ }
571
+ } ;
572
+
573
+ let out_id = out_ids. next ( ) . unwrap ( ) ;
574
+ let out = match self . user_state . outs_to_regs . get ( & out_id) {
575
+ Some ( reg) => * reg,
576
+ None => {
577
+ let reg = self . user_state . compiler . alloc ( ) ;
578
+ self . user_state . outs_to_regs . insert ( out_id, reg) ;
579
+ reg
580
+ }
581
+ } ;
582
+
583
+ let gate = Nand { a, b, out } ;
584
+ self . user_state . gates . insert ( id, Gate :: from ( gate) ) ;
585
+ }
487
586
488
587
// TODO: Implement
489
588
NodeTempl :: Immediate => { }
@@ -691,6 +790,30 @@ pub fn evaluate_node(
691
790
692
791
evaluator. output_scalar ( "out" , value)
693
792
}
793
+ NodeTempl :: Not => {
794
+ let mut outs = node. output_ids ( ) ;
795
+ let out_id = outs. next ( ) . unwrap ( ) ;
796
+
797
+ let value = if let Some ( reg) = user_state. outs_to_regs . get ( & out_id) {
798
+ user_state. simulation . register ( * reg)
799
+ } else {
800
+ false
801
+ } ;
802
+
803
+ evaluator. output_scalar ( "out" , !value)
804
+ }
805
+ NodeTempl :: Nand => {
806
+ let mut outs = node. output_ids ( ) ;
807
+ let out_id = outs. next ( ) . unwrap ( ) ;
808
+
809
+ let value = if let Some ( reg) = user_state. outs_to_regs . get ( & out_id) {
810
+ user_state. simulation . register ( * reg)
811
+ } else {
812
+ false
813
+ } ;
814
+
815
+ evaluator. output_scalar ( "out" , !value)
816
+ }
694
817
NodeTempl :: Immediate => {
695
818
let a = evaluator. input_scalar ( "A" , user_state) ?;
696
819
evaluator. output_scalar ( "out" , a)
0 commit comments